files.com 1.0.418 → 1.0.420

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 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.418
1
+ 1.0.420
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.418";
14
+ var version = "1.0.420";
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,262 @@
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 = (typeof path === 'string' ? 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 typeof path1 === 'string' && typeof path2 === 'string' && normalizeForComparison(path1) === normalizeForComparison(path2);
243
+ };
244
+ var startsWith = function startsWith(path1, path2) {
245
+ return typeof path1 === 'string' && typeof path2 === 'string' && 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
+ normalizeForComparison: normalizeForComparison,
257
+ same: same,
258
+ startsWith: startsWith
259
+ };
260
+ var _default = exports.default = pathNormalizer;
261
+ module.exports = pathNormalizer;
262
+ module.exports.default = pathNormalizer;
@@ -0,0 +1,88 @@
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('handles non-string params', function () {
19
+ expect(_pathNormalizer.default.normalize([])).toBe('');
20
+ expect(_pathNormalizer.default.normalize({})).toBe('');
21
+ expect(_pathNormalizer.default.normalize(null)).toBe('');
22
+ expect(_pathNormalizer.default.normalize(undefined)).toBe('');
23
+ expect(_pathNormalizer.default.same([], '')).toBe(false);
24
+ expect(_pathNormalizer.default.same(null, '')).toBe(false);
25
+ expect(_pathNormalizer.default.same([], null)).toBe(false);
26
+ expect(_pathNormalizer.default.same(undefined, undefined)).toBe(false);
27
+ expect(_pathNormalizer.default.startsWith(null, '')).toBe(false);
28
+ expect(_pathNormalizer.default.startsWith(null, [])).toBe(false);
29
+ expect(_pathNormalizer.default.startsWith([], null)).toBe(false);
30
+ expect(_pathNormalizer.default.startsWith(undefined, undefined)).toBe(false);
31
+ expect(_pathNormalizer.default.keyLookup(null, '')).toBe(undefined);
32
+ expect(_pathNormalizer.default.keyLookup(null, [])).toBe(undefined);
33
+ expect(_pathNormalizer.default.keyLookup([], null)).toBe(undefined);
34
+ expect(_pathNormalizer.default.keyLookup(undefined, undefined)).toBe(undefined);
35
+ });
36
+ it('looks up keys in a map', function () {
37
+ var map = {
38
+ '': {
39
+ list: true
40
+ },
41
+ foo: {
42
+ readonly: true
43
+ },
44
+ 'foo/bar': {
45
+ read: false,
46
+ write: true
47
+ }
48
+ };
49
+ expect(_pathNormalizer.default.keyLookup(map, 'foo/bar')).toEqual({
50
+ read: false,
51
+ write: true
52
+ });
53
+ expect(_pathNormalizer.default.keyLookup(map, '/foo/bar')).toEqual({
54
+ read: false,
55
+ write: true
56
+ });
57
+ expect(_pathNormalizer.default.keyLookup(map, '.')).toEqual({
58
+ list: true
59
+ });
60
+ expect(_pathNormalizer.default.keyLookup(map, './..')).toEqual({
61
+ list: true
62
+ });
63
+ expect(_pathNormalizer.default.keyLookup(map, '')).toEqual({
64
+ list: true
65
+ });
66
+ expect(_pathNormalizer.default.keyLookup(map, '/')).toEqual({
67
+ list: true
68
+ });
69
+ expect(_pathNormalizer.default.keyLookup(map, '/ ')).toEqual({
70
+ list: true
71
+ });
72
+ expect(_pathNormalizer.default.keyLookup(map, '// ')).toEqual({
73
+ list: true
74
+ });
75
+ expect(_pathNormalizer.default.keyLookup(map, '////')).toEqual({
76
+ list: true
77
+ });
78
+ expect(_pathNormalizer.default.keyLookup(map, '/foo')).toEqual({
79
+ readonly: true
80
+ });
81
+ expect(_pathNormalizer.default.keyLookup(map, '/////foo')).toEqual({
82
+ readonly: true
83
+ });
84
+ expect(_pathNormalizer.default.keyLookup(map, '/////foo/')).toEqual({
85
+ readonly: true
86
+ });
87
+ });
88
+ });
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.418",
3
+ "version": "1.0.420",
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
@@ -5,7 +5,7 @@ const endpointPrefix = '/api/rest/v1'
5
5
  let apiKey
6
6
  let baseUrl = 'https://app.files.com'
7
7
  let sessionId = null
8
- let version = "1.0.418"
8
+ let version = "1.0.420"
9
9
  let userAgent = `Files.com JavaScript SDK v${version}`
10
10
 
11
11
  let logLevel = LogLevel.INFO
@@ -0,0 +1,262 @@
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 = (typeof path === 'string' ? 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) => typeof path1 === 'string' && typeof path2 === 'string'
241
+ && normalizeForComparison(path1) === normalizeForComparison(path2)
242
+
243
+ const startsWith = (path1, path2) => typeof path1 === 'string' && typeof path2 === 'string'
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
+ normalizeForComparison,
255
+ same,
256
+ startsWith,
257
+ }
258
+
259
+ export default pathNormalizer
260
+
261
+ module.exports = pathNormalizer
262
+ module.exports.default = pathNormalizer
@@ -0,0 +1,57 @@
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('handles non-string params', () => {
16
+ expect(pathNormalizer.normalize([])).toBe('')
17
+ expect(pathNormalizer.normalize({})).toBe('')
18
+ expect(pathNormalizer.normalize(null)).toBe('')
19
+ expect(pathNormalizer.normalize(undefined)).toBe('')
20
+
21
+ expect(pathNormalizer.same([], '')).toBe(false)
22
+ expect(pathNormalizer.same(null, '')).toBe(false)
23
+ expect(pathNormalizer.same([], null)).toBe(false)
24
+ expect(pathNormalizer.same(undefined, undefined)).toBe(false)
25
+
26
+ expect(pathNormalizer.startsWith(null, '')).toBe(false)
27
+ expect(pathNormalizer.startsWith(null, [])).toBe(false)
28
+ expect(pathNormalizer.startsWith([], null)).toBe(false)
29
+ expect(pathNormalizer.startsWith(undefined, undefined)).toBe(false)
30
+
31
+ expect(pathNormalizer.keyLookup(null, '')).toBe(undefined)
32
+ expect(pathNormalizer.keyLookup(null, [])).toBe(undefined)
33
+ expect(pathNormalizer.keyLookup([], null)).toBe(undefined)
34
+ expect(pathNormalizer.keyLookup(undefined, undefined)).toBe(undefined)
35
+ })
36
+
37
+ it('looks up keys in a map', () => {
38
+ const map = {
39
+ '': { list: true },
40
+ foo: { readonly: true },
41
+ 'foo/bar': { read: false, write: true },
42
+ }
43
+
44
+ expect(pathNormalizer.keyLookup(map, 'foo/bar')).toEqual({ read: false, write: true })
45
+ expect(pathNormalizer.keyLookup(map, '/foo/bar')).toEqual({ read: false, write: true })
46
+ expect(pathNormalizer.keyLookup(map, '.')).toEqual({ list: true })
47
+ expect(pathNormalizer.keyLookup(map, './..')).toEqual({ list: true })
48
+ expect(pathNormalizer.keyLookup(map, '')).toEqual({ list: true })
49
+ expect(pathNormalizer.keyLookup(map, '/')).toEqual({ list: true })
50
+ expect(pathNormalizer.keyLookup(map, '/ ')).toEqual({ list: true })
51
+ expect(pathNormalizer.keyLookup(map, '// ')).toEqual({ list: true })
52
+ expect(pathNormalizer.keyLookup(map, '////')).toEqual({ list: true })
53
+ expect(pathNormalizer.keyLookup(map, '/foo')).toEqual({ readonly: true })
54
+ expect(pathNormalizer.keyLookup(map, '/////foo')).toEqual({ readonly: true })
55
+ expect(pathNormalizer.keyLookup(map, '/////foo/')).toEqual({ readonly: true })
56
+ })
57
+ })
package/src/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ import pathNormalizer from './utils/pathNormalizer'
2
+
1
3
  const isArray = value => Array.isArray(value)
2
4
 
3
5
  const isInt = value => typeof value === 'number'
@@ -25,4 +27,5 @@ export {
25
27
  isInt,
26
28
  isObject,
27
29
  isString,
30
+ pathNormalizer,
28
31
  }