files.com 1.0.418 → 1.0.419
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +10 -0
- package/_VERSION +1 -1
- package/lib/Files.js +1 -1
- package/lib/utils/pathNormalizer.js +261 -0
- package/lib/utils/pathNormalizer.test.js +70 -0
- package/lib/utils.js +2 -0
- package/package.json +6 -3
- package/src/Files.js +1 -1
- package/src/utils/pathNormalizer.js +261 -0
- package/src/utils/pathNormalizer.test.js +35 -0
- package/src/utils.js +3 -0
package/README.md
CHANGED
@@ -157,6 +157,16 @@ You can set the following global properties using static methods on the `Files`
|
|
157
157
|
const textContent = await downloadableFile.downloadToString()
|
158
158
|
}
|
159
159
|
|
160
|
+
#### Comparing Case insensitive files and paths
|
161
|
+
|
162
|
+
For related documentation see [Case Sensitivity Documentation](https://www.files.com/docs/topics/file-system-semantics#case-sensitivity).
|
163
|
+
|
164
|
+
import { pathNormalizer } from 'files.com/lib/utils.js'
|
165
|
+
|
166
|
+
if (pathNormalizer.same('Fïłèńämê.Txt', 'filename.txt')) {
|
167
|
+
// the paths are the same
|
168
|
+
}
|
169
|
+
|
160
170
|
### Additional Object Documentation
|
161
171
|
|
162
172
|
Additional docs are available at https://developers.files.com
|
package/_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.419
|
package/lib/Files.js
CHANGED
@@ -11,7 +11,7 @@ var endpointPrefix = '/api/rest/v1';
|
|
11
11
|
var apiKey;
|
12
12
|
var baseUrl = 'https://app.files.com';
|
13
13
|
var sessionId = null;
|
14
|
-
var version = "1.0.
|
14
|
+
var version = "1.0.419";
|
15
15
|
var userAgent = "Files.com JavaScript SDK v".concat(version);
|
16
16
|
var logLevel = _Logger.LogLevel.INFO;
|
17
17
|
var debugRequest = false;
|
@@ -0,0 +1,261 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
exports.__esModule = true;
|
4
|
+
exports.default = void 0;
|
5
|
+
// This implements the algorithm for path normalization described here:
|
6
|
+
// https://www.files.com/docs/topics/file-system-semantics#exact-algorithm-for-path-normalization
|
7
|
+
|
8
|
+
/* eslint-disable sort-keys */
|
9
|
+
var transliterationMap = {
|
10
|
+
À: 'A',
|
11
|
+
Á: 'A',
|
12
|
+
Â: 'A',
|
13
|
+
Ã: 'A',
|
14
|
+
Ä: 'A',
|
15
|
+
Å: 'A',
|
16
|
+
Æ: 'AE',
|
17
|
+
Ç: 'C',
|
18
|
+
È: 'E',
|
19
|
+
É: 'E',
|
20
|
+
Ê: 'E',
|
21
|
+
Ë: 'E',
|
22
|
+
Ì: 'I',
|
23
|
+
Í: 'I',
|
24
|
+
Î: 'I',
|
25
|
+
Ï: 'I',
|
26
|
+
Ð: 'D',
|
27
|
+
Ñ: 'N',
|
28
|
+
Ò: 'O',
|
29
|
+
Ó: 'O',
|
30
|
+
Ô: 'O',
|
31
|
+
Õ: 'O',
|
32
|
+
Ö: 'O',
|
33
|
+
Ø: 'O',
|
34
|
+
Ù: 'U',
|
35
|
+
Ú: 'U',
|
36
|
+
Û: 'U',
|
37
|
+
Ü: 'U',
|
38
|
+
Ý: 'Y',
|
39
|
+
ß: 'ss',
|
40
|
+
à: 'a',
|
41
|
+
á: 'a',
|
42
|
+
â: 'a',
|
43
|
+
ã: 'a',
|
44
|
+
ä: 'a',
|
45
|
+
å: 'a',
|
46
|
+
æ: 'ae',
|
47
|
+
ç: 'c',
|
48
|
+
è: 'e',
|
49
|
+
é: 'e',
|
50
|
+
ê: 'e',
|
51
|
+
ë: 'e',
|
52
|
+
ì: 'i',
|
53
|
+
í: 'i',
|
54
|
+
î: 'i',
|
55
|
+
ï: 'i',
|
56
|
+
ð: 'd',
|
57
|
+
ñ: 'n',
|
58
|
+
ò: 'o',
|
59
|
+
ó: 'o',
|
60
|
+
ô: 'o',
|
61
|
+
õ: 'o',
|
62
|
+
ö: 'o',
|
63
|
+
ø: 'o',
|
64
|
+
ù: 'u',
|
65
|
+
ú: 'u',
|
66
|
+
û: 'u',
|
67
|
+
ü: 'u',
|
68
|
+
ý: 'y',
|
69
|
+
ÿ: 'y',
|
70
|
+
Ā: 'A',
|
71
|
+
ā: 'a',
|
72
|
+
Ă: 'A',
|
73
|
+
ă: 'a',
|
74
|
+
Ą: 'A',
|
75
|
+
ą: 'a',
|
76
|
+
Ć: 'C',
|
77
|
+
ć: 'c',
|
78
|
+
Ĉ: 'C',
|
79
|
+
ĉ: 'c',
|
80
|
+
Ċ: 'C',
|
81
|
+
ċ: 'c',
|
82
|
+
Č: 'C',
|
83
|
+
č: 'c',
|
84
|
+
Ď: 'D',
|
85
|
+
ď: 'd',
|
86
|
+
Đ: 'D',
|
87
|
+
đ: 'd',
|
88
|
+
Ē: 'E',
|
89
|
+
ē: 'e',
|
90
|
+
Ĕ: 'E',
|
91
|
+
ĕ: 'e',
|
92
|
+
Ė: 'E',
|
93
|
+
ė: 'e',
|
94
|
+
Ę: 'E',
|
95
|
+
ę: 'e',
|
96
|
+
Ě: 'E',
|
97
|
+
ě: 'e',
|
98
|
+
Ĝ: 'G',
|
99
|
+
ĝ: 'g',
|
100
|
+
Ğ: 'G',
|
101
|
+
ğ: 'g',
|
102
|
+
Ġ: 'G',
|
103
|
+
ġ: 'g',
|
104
|
+
Ģ: 'G',
|
105
|
+
ģ: 'g',
|
106
|
+
Ĥ: 'H',
|
107
|
+
ĥ: 'h',
|
108
|
+
Ħ: 'H',
|
109
|
+
ħ: 'h',
|
110
|
+
Ĩ: 'I',
|
111
|
+
ĩ: 'i',
|
112
|
+
Ī: 'I',
|
113
|
+
ī: 'i',
|
114
|
+
Ĭ: 'I',
|
115
|
+
ĭ: 'i',
|
116
|
+
Į: 'I',
|
117
|
+
į: 'i',
|
118
|
+
İ: 'I',
|
119
|
+
IJ: 'IJ',
|
120
|
+
ij: 'ij',
|
121
|
+
Ĵ: 'J',
|
122
|
+
ĵ: 'j',
|
123
|
+
Ķ: 'K',
|
124
|
+
ķ: 'k',
|
125
|
+
Ĺ: 'L',
|
126
|
+
ĺ: 'l',
|
127
|
+
Ļ: 'L',
|
128
|
+
ļ: 'l',
|
129
|
+
Ľ: 'L',
|
130
|
+
ľ: 'l',
|
131
|
+
Ł: 'L',
|
132
|
+
ł: 'l',
|
133
|
+
Ń: 'N',
|
134
|
+
ń: 'n',
|
135
|
+
Ņ: 'N',
|
136
|
+
ņ: 'n',
|
137
|
+
Ň: 'N',
|
138
|
+
ň: 'n',
|
139
|
+
ʼn: '\'n',
|
140
|
+
Ō: 'O',
|
141
|
+
ō: 'o',
|
142
|
+
Ŏ: 'O',
|
143
|
+
ŏ: 'o',
|
144
|
+
Ő: 'O',
|
145
|
+
ő: 'o',
|
146
|
+
Œ: 'OE',
|
147
|
+
œ: 'oe',
|
148
|
+
Ŕ: 'R',
|
149
|
+
ŕ: 'r',
|
150
|
+
Ŗ: 'R',
|
151
|
+
ŗ: 'r',
|
152
|
+
Ř: 'R',
|
153
|
+
ř: 'r',
|
154
|
+
Ś: 'S',
|
155
|
+
ś: 's',
|
156
|
+
Ŝ: 'S',
|
157
|
+
ŝ: 's',
|
158
|
+
Ş: 'S',
|
159
|
+
ş: 's',
|
160
|
+
Š: 'S',
|
161
|
+
š: 's',
|
162
|
+
Ţ: 'T',
|
163
|
+
ţ: 't',
|
164
|
+
Ť: 'T',
|
165
|
+
ť: 't',
|
166
|
+
Ũ: 'U',
|
167
|
+
ũ: 'u',
|
168
|
+
Ū: 'U',
|
169
|
+
ū: 'u',
|
170
|
+
Ŭ: 'U',
|
171
|
+
ŭ: 'u',
|
172
|
+
Ů: 'U',
|
173
|
+
ů: 'u',
|
174
|
+
Ű: 'U',
|
175
|
+
ű: 'u',
|
176
|
+
Ų: 'U',
|
177
|
+
ų: 'u',
|
178
|
+
Ŵ: 'W',
|
179
|
+
ŵ: 'w',
|
180
|
+
Ŷ: 'Y',
|
181
|
+
ŷ: 'y',
|
182
|
+
Ÿ: 'Y',
|
183
|
+
Ź: 'Z',
|
184
|
+
ź: 'z',
|
185
|
+
Ż: 'Z',
|
186
|
+
ż: 'z',
|
187
|
+
Ž: 'Z',
|
188
|
+
ž: 'z'
|
189
|
+
};
|
190
|
+
/* eslint-enable sort-keys */
|
191
|
+
|
192
|
+
var transliterate = function transliterate(str) {
|
193
|
+
return Array.from(str).map(function (char) {
|
194
|
+
return transliterationMap[char] || char;
|
195
|
+
}).join('');
|
196
|
+
};
|
197
|
+
|
198
|
+
// converting the path to UTF-8 is not necessary in JS as it's the default
|
199
|
+
var normalize = function normalize(path) {
|
200
|
+
// Remove any characters with byte value of 0
|
201
|
+
var cleaned = (path || '').replace(/\0/g, '');
|
202
|
+
|
203
|
+
// Convert any backslash (\) characters to a forward slash (/)
|
204
|
+
cleaned = cleaned.replace(/\\/g, '/');
|
205
|
+
|
206
|
+
// Remove any trailing or leading slashes
|
207
|
+
cleaned = cleaned.replace(/^\/+|\/+$/g, '');
|
208
|
+
|
209
|
+
// Remove any path parts that are . or ..
|
210
|
+
cleaned = cleaned.split('/').filter(function (part) {
|
211
|
+
return part !== '.' && part !== '..';
|
212
|
+
}).join('/');
|
213
|
+
|
214
|
+
// Replace any duplicate forward slashes (such as ///) with a single forward slash (/)
|
215
|
+
cleaned = cleaned.replace(/\/+/g, '/');
|
216
|
+
return cleaned;
|
217
|
+
};
|
218
|
+
var normalizeForComparisonCache = new Map();
|
219
|
+
var normalizeForComparison = function normalizeForComparison(path) {
|
220
|
+
if (normalizeForComparisonCache.has(path)) {
|
221
|
+
return normalizeForComparisonCache.get(path);
|
222
|
+
}
|
223
|
+
|
224
|
+
// Run the path through the Normalize Algorithm
|
225
|
+
var normalized = normalize(path);
|
226
|
+
|
227
|
+
// Unicode Normalize the Path using Unicode NFKC algorithm
|
228
|
+
normalized = normalized.normalize('NFKC');
|
229
|
+
|
230
|
+
// Transliterate and remove accent marks
|
231
|
+
normalized = transliterate(normalized);
|
232
|
+
|
233
|
+
// Convert the Path to lowercase
|
234
|
+
normalized = normalized.toLowerCase();
|
235
|
+
|
236
|
+
// Remove any trailing whitespace (\r, \n, \t or the space character)
|
237
|
+
normalized = normalized.replace(/[\r\n\t ]+$/g, '');
|
238
|
+
normalizeForComparisonCache.set(path, normalized);
|
239
|
+
return normalized;
|
240
|
+
};
|
241
|
+
var same = function same(path1, path2) {
|
242
|
+
return normalizeForComparison(path1) === normalizeForComparison(path2);
|
243
|
+
};
|
244
|
+
var startsWith = function startsWith(path1, path2) {
|
245
|
+
return normalizeForComparison(path1).startsWith(normalizeForComparison(path2));
|
246
|
+
};
|
247
|
+
var keyLookup = function keyLookup(object, path) {
|
248
|
+
var key = Object.keys(object).find(function (key) {
|
249
|
+
return same(key, path);
|
250
|
+
});
|
251
|
+
return typeof key === 'string' ? object[key] : undefined;
|
252
|
+
};
|
253
|
+
var pathNormalizer = {
|
254
|
+
keyLookup: keyLookup,
|
255
|
+
normalize: normalize,
|
256
|
+
same: same,
|
257
|
+
startsWith: startsWith
|
258
|
+
};
|
259
|
+
var _default = exports.default = pathNormalizer;
|
260
|
+
module.exports = pathNormalizer;
|
261
|
+
module.exports.default = pathNormalizer;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
5
|
+
var _pathNormalizer = _interopRequireDefault(require("./pathNormalizer"));
|
6
|
+
var _normalization_for_comparison_test_data = _interopRequireDefault(require("../../../common/shared/normalization_for_comparison_test_data.json"));
|
7
|
+
describe('pathNormalizer', function () {
|
8
|
+
it('normalizes paths for comparison', function () {
|
9
|
+
_normalization_for_comparison_test_data.default.forEach(function (_ref) {
|
10
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
11
|
+
input = _ref2[0],
|
12
|
+
expected = _ref2[1];
|
13
|
+
expect(_pathNormalizer.default.same(input, expected)).toBe(true);
|
14
|
+
var startOfExpected = expected.substring(0, 3);
|
15
|
+
expect(_pathNormalizer.default.startsWith(input, startOfExpected)).toBe(true);
|
16
|
+
});
|
17
|
+
});
|
18
|
+
it('looks up keys in a map', function () {
|
19
|
+
var map = {
|
20
|
+
'': {
|
21
|
+
list: true
|
22
|
+
},
|
23
|
+
foo: {
|
24
|
+
readonly: true
|
25
|
+
},
|
26
|
+
'foo/bar': {
|
27
|
+
read: false,
|
28
|
+
write: true
|
29
|
+
}
|
30
|
+
};
|
31
|
+
expect(_pathNormalizer.default.keyLookup(map, 'foo/bar')).toEqual({
|
32
|
+
read: false,
|
33
|
+
write: true
|
34
|
+
});
|
35
|
+
expect(_pathNormalizer.default.keyLookup(map, '/foo/bar')).toEqual({
|
36
|
+
read: false,
|
37
|
+
write: true
|
38
|
+
});
|
39
|
+
expect(_pathNormalizer.default.keyLookup(map, '.')).toEqual({
|
40
|
+
list: true
|
41
|
+
});
|
42
|
+
expect(_pathNormalizer.default.keyLookup(map, './..')).toEqual({
|
43
|
+
list: true
|
44
|
+
});
|
45
|
+
expect(_pathNormalizer.default.keyLookup(map, '')).toEqual({
|
46
|
+
list: true
|
47
|
+
});
|
48
|
+
expect(_pathNormalizer.default.keyLookup(map, '/')).toEqual({
|
49
|
+
list: true
|
50
|
+
});
|
51
|
+
expect(_pathNormalizer.default.keyLookup(map, '/ ')).toEqual({
|
52
|
+
list: true
|
53
|
+
});
|
54
|
+
expect(_pathNormalizer.default.keyLookup(map, '// ')).toEqual({
|
55
|
+
list: true
|
56
|
+
});
|
57
|
+
expect(_pathNormalizer.default.keyLookup(map, '////')).toEqual({
|
58
|
+
list: true
|
59
|
+
});
|
60
|
+
expect(_pathNormalizer.default.keyLookup(map, '/foo')).toEqual({
|
61
|
+
readonly: true
|
62
|
+
});
|
63
|
+
expect(_pathNormalizer.default.keyLookup(map, '/////foo')).toEqual({
|
64
|
+
readonly: true
|
65
|
+
});
|
66
|
+
expect(_pathNormalizer.default.keyLookup(map, '/////foo/')).toEqual({
|
67
|
+
readonly: true
|
68
|
+
});
|
69
|
+
});
|
70
|
+
});
|
package/lib/utils.js
CHANGED
@@ -4,6 +4,8 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
4
4
|
exports.__esModule = true;
|
5
5
|
exports.isString = exports.isObject = exports.isInt = exports.isEmpty = exports.isBrowser = exports.isArray = exports.getType = void 0;
|
6
6
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
7
|
+
var _pathNormalizer = _interopRequireDefault(require("./utils/pathNormalizer"));
|
8
|
+
exports.pathNormalizer = _pathNormalizer.default;
|
7
9
|
var isArray = exports.isArray = function isArray(value) {
|
8
10
|
return Array.isArray(value);
|
9
11
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "files.com",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.419",
|
4
4
|
"description": "Files.com SDK for JavaScript",
|
5
5
|
"keywords": [
|
6
6
|
"files.com",
|
@@ -32,9 +32,12 @@
|
|
32
32
|
"@babel/plugin-proposal-class-properties": "^7.10.1",
|
33
33
|
"@babel/plugin-transform-modules-commonjs": "^7.10.1",
|
34
34
|
"@babel/plugin-transform-runtime": "^7.10.3",
|
35
|
-
"@babel/preset-env": "^7.10.3"
|
35
|
+
"@babel/preset-env": "^7.10.3",
|
36
|
+
"jest": "^29.7.0"
|
36
37
|
},
|
37
38
|
"scripts": {
|
38
|
-
"build": "./node_modules/.bin/babel src -d lib"
|
39
|
+
"build": "./node_modules/.bin/babel src -d lib",
|
40
|
+
"test": "jest",
|
41
|
+
"watch": "jest --watch"
|
39
42
|
}
|
40
43
|
}
|
package/src/Files.js
CHANGED
@@ -0,0 +1,261 @@
|
|
1
|
+
// This implements the algorithm for path normalization described here:
|
2
|
+
// https://www.files.com/docs/topics/file-system-semantics#exact-algorithm-for-path-normalization
|
3
|
+
|
4
|
+
/* eslint-disable sort-keys */
|
5
|
+
const transliterationMap = {
|
6
|
+
À: 'A',
|
7
|
+
Á: 'A',
|
8
|
+
Â: 'A',
|
9
|
+
Ã: 'A',
|
10
|
+
Ä: 'A',
|
11
|
+
Å: 'A',
|
12
|
+
Æ: 'AE',
|
13
|
+
Ç: 'C',
|
14
|
+
È: 'E',
|
15
|
+
É: 'E',
|
16
|
+
Ê: 'E',
|
17
|
+
Ë: 'E',
|
18
|
+
Ì: 'I',
|
19
|
+
Í: 'I',
|
20
|
+
Î: 'I',
|
21
|
+
Ï: 'I',
|
22
|
+
Ð: 'D',
|
23
|
+
Ñ: 'N',
|
24
|
+
Ò: 'O',
|
25
|
+
Ó: 'O',
|
26
|
+
Ô: 'O',
|
27
|
+
Õ: 'O',
|
28
|
+
Ö: 'O',
|
29
|
+
Ø: 'O',
|
30
|
+
Ù: 'U',
|
31
|
+
Ú: 'U',
|
32
|
+
Û: 'U',
|
33
|
+
Ü: 'U',
|
34
|
+
Ý: 'Y',
|
35
|
+
ß: 'ss',
|
36
|
+
à: 'a',
|
37
|
+
á: 'a',
|
38
|
+
â: 'a',
|
39
|
+
ã: 'a',
|
40
|
+
ä: 'a',
|
41
|
+
å: 'a',
|
42
|
+
æ: 'ae',
|
43
|
+
ç: 'c',
|
44
|
+
è: 'e',
|
45
|
+
é: 'e',
|
46
|
+
ê: 'e',
|
47
|
+
ë: 'e',
|
48
|
+
ì: 'i',
|
49
|
+
í: 'i',
|
50
|
+
î: 'i',
|
51
|
+
ï: 'i',
|
52
|
+
ð: 'd',
|
53
|
+
ñ: 'n',
|
54
|
+
ò: 'o',
|
55
|
+
ó: 'o',
|
56
|
+
ô: 'o',
|
57
|
+
õ: 'o',
|
58
|
+
ö: 'o',
|
59
|
+
ø: 'o',
|
60
|
+
ù: 'u',
|
61
|
+
ú: 'u',
|
62
|
+
û: 'u',
|
63
|
+
ü: 'u',
|
64
|
+
ý: 'y',
|
65
|
+
ÿ: 'y',
|
66
|
+
Ā: 'A',
|
67
|
+
ā: 'a',
|
68
|
+
Ă: 'A',
|
69
|
+
ă: 'a',
|
70
|
+
Ą: 'A',
|
71
|
+
ą: 'a',
|
72
|
+
Ć: 'C',
|
73
|
+
ć: 'c',
|
74
|
+
Ĉ: 'C',
|
75
|
+
ĉ: 'c',
|
76
|
+
Ċ: 'C',
|
77
|
+
ċ: 'c',
|
78
|
+
Č: 'C',
|
79
|
+
č: 'c',
|
80
|
+
Ď: 'D',
|
81
|
+
ď: 'd',
|
82
|
+
Đ: 'D',
|
83
|
+
đ: 'd',
|
84
|
+
Ē: 'E',
|
85
|
+
ē: 'e',
|
86
|
+
Ĕ: 'E',
|
87
|
+
ĕ: 'e',
|
88
|
+
Ė: 'E',
|
89
|
+
ė: 'e',
|
90
|
+
Ę: 'E',
|
91
|
+
ę: 'e',
|
92
|
+
Ě: 'E',
|
93
|
+
ě: 'e',
|
94
|
+
Ĝ: 'G',
|
95
|
+
ĝ: 'g',
|
96
|
+
Ğ: 'G',
|
97
|
+
ğ: 'g',
|
98
|
+
Ġ: 'G',
|
99
|
+
ġ: 'g',
|
100
|
+
Ģ: 'G',
|
101
|
+
ģ: 'g',
|
102
|
+
Ĥ: 'H',
|
103
|
+
ĥ: 'h',
|
104
|
+
Ħ: 'H',
|
105
|
+
ħ: 'h',
|
106
|
+
Ĩ: 'I',
|
107
|
+
ĩ: 'i',
|
108
|
+
Ī: 'I',
|
109
|
+
ī: 'i',
|
110
|
+
Ĭ: 'I',
|
111
|
+
ĭ: 'i',
|
112
|
+
Į: 'I',
|
113
|
+
į: 'i',
|
114
|
+
İ: 'I',
|
115
|
+
IJ: 'IJ',
|
116
|
+
ij: 'ij',
|
117
|
+
Ĵ: 'J',
|
118
|
+
ĵ: 'j',
|
119
|
+
Ķ: 'K',
|
120
|
+
ķ: 'k',
|
121
|
+
Ĺ: 'L',
|
122
|
+
ĺ: 'l',
|
123
|
+
Ļ: 'L',
|
124
|
+
ļ: 'l',
|
125
|
+
Ľ: 'L',
|
126
|
+
ľ: 'l',
|
127
|
+
Ł: 'L',
|
128
|
+
ł: 'l',
|
129
|
+
Ń: 'N',
|
130
|
+
ń: 'n',
|
131
|
+
Ņ: 'N',
|
132
|
+
ņ: 'n',
|
133
|
+
Ň: 'N',
|
134
|
+
ň: 'n',
|
135
|
+
ʼn: '\'n',
|
136
|
+
Ō: 'O',
|
137
|
+
ō: 'o',
|
138
|
+
Ŏ: 'O',
|
139
|
+
ŏ: 'o',
|
140
|
+
Ő: 'O',
|
141
|
+
ő: 'o',
|
142
|
+
Œ: 'OE',
|
143
|
+
œ: 'oe',
|
144
|
+
Ŕ: 'R',
|
145
|
+
ŕ: 'r',
|
146
|
+
Ŗ: 'R',
|
147
|
+
ŗ: 'r',
|
148
|
+
Ř: 'R',
|
149
|
+
ř: 'r',
|
150
|
+
Ś: 'S',
|
151
|
+
ś: 's',
|
152
|
+
Ŝ: 'S',
|
153
|
+
ŝ: 's',
|
154
|
+
Ş: 'S',
|
155
|
+
ş: 's',
|
156
|
+
Š: 'S',
|
157
|
+
š: 's',
|
158
|
+
Ţ: 'T',
|
159
|
+
ţ: 't',
|
160
|
+
Ť: 'T',
|
161
|
+
ť: 't',
|
162
|
+
Ũ: 'U',
|
163
|
+
ũ: 'u',
|
164
|
+
Ū: 'U',
|
165
|
+
ū: 'u',
|
166
|
+
Ŭ: 'U',
|
167
|
+
ŭ: 'u',
|
168
|
+
Ů: 'U',
|
169
|
+
ů: 'u',
|
170
|
+
Ű: 'U',
|
171
|
+
ű: 'u',
|
172
|
+
Ų: 'U',
|
173
|
+
ų: 'u',
|
174
|
+
Ŵ: 'W',
|
175
|
+
ŵ: 'w',
|
176
|
+
Ŷ: 'Y',
|
177
|
+
ŷ: 'y',
|
178
|
+
Ÿ: 'Y',
|
179
|
+
Ź: 'Z',
|
180
|
+
ź: 'z',
|
181
|
+
Ż: 'Z',
|
182
|
+
ż: 'z',
|
183
|
+
Ž: 'Z',
|
184
|
+
ž: 'z',
|
185
|
+
}
|
186
|
+
/* eslint-enable sort-keys */
|
187
|
+
|
188
|
+
const transliterate = str =>
|
189
|
+
Array.from(str)
|
190
|
+
.map(char => transliterationMap[char] || char)
|
191
|
+
.join('')
|
192
|
+
|
193
|
+
// converting the path to UTF-8 is not necessary in JS as it's the default
|
194
|
+
const normalize = path => {
|
195
|
+
// Remove any characters with byte value of 0
|
196
|
+
let cleaned = (path || '').replace(/\0/g, '')
|
197
|
+
|
198
|
+
// Convert any backslash (\) characters to a forward slash (/)
|
199
|
+
cleaned = cleaned.replace(/\\/g, '/')
|
200
|
+
|
201
|
+
// Remove any trailing or leading slashes
|
202
|
+
cleaned = cleaned.replace(/^\/+|\/+$/g, '')
|
203
|
+
|
204
|
+
// Remove any path parts that are . or ..
|
205
|
+
cleaned = cleaned.split('/').filter(part => part !== '.' && part !== '..').join('/')
|
206
|
+
|
207
|
+
// Replace any duplicate forward slashes (such as ///) with a single forward slash (/)
|
208
|
+
cleaned = cleaned.replace(/\/+/g, '/')
|
209
|
+
|
210
|
+
return cleaned
|
211
|
+
}
|
212
|
+
|
213
|
+
const normalizeForComparisonCache = new Map()
|
214
|
+
|
215
|
+
const normalizeForComparison = path => {
|
216
|
+
if (normalizeForComparisonCache.has(path)) {
|
217
|
+
return normalizeForComparisonCache.get(path)
|
218
|
+
}
|
219
|
+
|
220
|
+
// Run the path through the Normalize Algorithm
|
221
|
+
let normalized = normalize(path)
|
222
|
+
|
223
|
+
// Unicode Normalize the Path using Unicode NFKC algorithm
|
224
|
+
normalized = normalized.normalize('NFKC')
|
225
|
+
|
226
|
+
// Transliterate and remove accent marks
|
227
|
+
normalized = transliterate(normalized)
|
228
|
+
|
229
|
+
// Convert the Path to lowercase
|
230
|
+
normalized = normalized.toLowerCase()
|
231
|
+
|
232
|
+
// Remove any trailing whitespace (\r, \n, \t or the space character)
|
233
|
+
normalized = normalized.replace(/[\r\n\t ]+$/g, '')
|
234
|
+
|
235
|
+
normalizeForComparisonCache.set(path, normalized)
|
236
|
+
|
237
|
+
return normalized
|
238
|
+
}
|
239
|
+
|
240
|
+
const same = (path1, path2) =>
|
241
|
+
normalizeForComparison(path1) === normalizeForComparison(path2)
|
242
|
+
|
243
|
+
const startsWith = (path1, path2) =>
|
244
|
+
normalizeForComparison(path1).startsWith(normalizeForComparison(path2))
|
245
|
+
|
246
|
+
const keyLookup = (object, path) => {
|
247
|
+
const key = Object.keys(object).find(key => same(key, path))
|
248
|
+
return typeof key === 'string' ? object[key] : undefined
|
249
|
+
}
|
250
|
+
|
251
|
+
const pathNormalizer = {
|
252
|
+
keyLookup,
|
253
|
+
normalize,
|
254
|
+
same,
|
255
|
+
startsWith,
|
256
|
+
}
|
257
|
+
|
258
|
+
export default pathNormalizer
|
259
|
+
|
260
|
+
module.exports = pathNormalizer
|
261
|
+
module.exports.default = pathNormalizer
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import pathNormalizer from './pathNormalizer'
|
2
|
+
|
3
|
+
import normalizationForComparisonTestData from '../../../common/shared/normalization_for_comparison_test_data.json'
|
4
|
+
|
5
|
+
describe('pathNormalizer', () => {
|
6
|
+
it('normalizes paths for comparison', () => {
|
7
|
+
normalizationForComparisonTestData.forEach(([input, expected]) => {
|
8
|
+
expect(pathNormalizer.same(input, expected)).toBe(true)
|
9
|
+
|
10
|
+
const startOfExpected = expected.substring(0, 3)
|
11
|
+
expect(pathNormalizer.startsWith(input, startOfExpected)).toBe(true)
|
12
|
+
})
|
13
|
+
})
|
14
|
+
|
15
|
+
it('looks up keys in a map', () => {
|
16
|
+
const map = {
|
17
|
+
'': { list: true },
|
18
|
+
foo: { readonly: true },
|
19
|
+
'foo/bar': { read: false, write: true },
|
20
|
+
}
|
21
|
+
|
22
|
+
expect(pathNormalizer.keyLookup(map, 'foo/bar')).toEqual({ read: false, write: true })
|
23
|
+
expect(pathNormalizer.keyLookup(map, '/foo/bar')).toEqual({ read: false, write: true })
|
24
|
+
expect(pathNormalizer.keyLookup(map, '.')).toEqual({ list: true })
|
25
|
+
expect(pathNormalizer.keyLookup(map, './..')).toEqual({ list: true })
|
26
|
+
expect(pathNormalizer.keyLookup(map, '')).toEqual({ list: true })
|
27
|
+
expect(pathNormalizer.keyLookup(map, '/')).toEqual({ list: true })
|
28
|
+
expect(pathNormalizer.keyLookup(map, '/ ')).toEqual({ list: true })
|
29
|
+
expect(pathNormalizer.keyLookup(map, '// ')).toEqual({ list: true })
|
30
|
+
expect(pathNormalizer.keyLookup(map, '////')).toEqual({ list: true })
|
31
|
+
expect(pathNormalizer.keyLookup(map, '/foo')).toEqual({ readonly: true })
|
32
|
+
expect(pathNormalizer.keyLookup(map, '/////foo')).toEqual({ readonly: true })
|
33
|
+
expect(pathNormalizer.keyLookup(map, '/////foo/')).toEqual({ readonly: true })
|
34
|
+
})
|
35
|
+
})
|
package/src/utils.js
CHANGED