files.com 1.0.418 → 1.0.419
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 +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