@deephaven/file-explorer 0.5.1 → 0.5.2-allpackages.16
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/dist/FileExistsError.js +7 -35
- package/dist/FileExistsError.js.map +1 -1
- package/dist/FileExplorer.js +62 -139
- package/dist/FileExplorer.js.map +1 -1
- package/dist/FileExplorerShortcuts.js +1 -1
- package/dist/FileExplorerShortcuts.js.map +1 -1
- package/dist/FileExplorerToolbar.js +7 -6
- package/dist/FileExplorerToolbar.js.map +1 -1
- package/dist/FileList.js +103 -172
- package/dist/FileList.js.map +1 -1
- package/dist/FileListContainer.js +38 -68
- package/dist/FileListContainer.js.map +1 -1
- package/dist/FileListItemEditor.js +28 -58
- package/dist/FileListItemEditor.js.map +1 -1
- package/dist/FileNotFoundError.js +5 -40
- package/dist/FileNotFoundError.js.map +1 -1
- package/dist/FileUtils.js +208 -258
- package/dist/FileUtils.js.map +1 -1
- package/dist/NewItemModal.js +397 -464
- package/dist/NewItemModal.js.map +1 -1
- package/dist/WebdavFileStorage.js +97 -250
- package/dist/WebdavFileStorage.js.map +1 -1
- package/dist/WebdavFileStorageTable.js +196 -346
- package/dist/WebdavFileStorageTable.js.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileNotFoundError.ts"],"names":["FileNotFoundError","Error"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/FileNotFoundError.ts"],"names":["FileNotFoundError","Error","constructor"],"mappings":";;AAAA,MAAMA,iBAAN,SAAgCC,KAAhC,CAAsC;AACpCC,EAAAA,WAAW,GAAG;AACZ,UAAM,sCAAN;;AADY,4CAIG,IAJH;AAEb;;AAHmC;;AAQtC,eAAeF,iBAAf","sourcesContent":["class FileNotFoundError extends Error {\n constructor() {\n super('No file exists at the path specified');\n }\n\n isFileNotFound = true;\n}\n\nexport default FileNotFoundError;\n"],"file":"FileNotFoundError.js"}
|
package/dist/FileUtils.js
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
|
-
|
|
3
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
-
|
|
5
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
6
|
-
|
|
7
|
-
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
|
8
|
-
|
|
9
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
10
|
-
|
|
11
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
12
|
-
|
|
13
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
14
|
-
|
|
15
|
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
16
|
-
|
|
17
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
18
|
-
|
|
19
1
|
import { ValidationError } from '@deephaven/utils';
|
|
20
2
|
/**
|
|
21
3
|
* A basic list of some common MIME types.
|
|
@@ -35,274 +17,242 @@ export var MIME_TYPE;
|
|
|
35
17
|
MIME_TYPE["UNKNOWN"] = "";
|
|
36
18
|
})(MIME_TYPE || (MIME_TYPE = {}));
|
|
37
19
|
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
|
|
20
|
+
export class FileUtils {
|
|
21
|
+
/**
|
|
22
|
+
* Format file extension
|
|
23
|
+
* @param extension File extension to format, defaults to empty string
|
|
24
|
+
* @returns Formatted string - '' for no extension, '.' for empty extension, '.ext' for non-empty extension
|
|
25
|
+
*/
|
|
26
|
+
static fileExtensionToString() {
|
|
27
|
+
var extension = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
28
|
+
return extension.length === 0 ? '' : ".".concat(extension);
|
|
41
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the depth (how many directories deep it is) of the provided filename with path.
|
|
32
|
+
* @param name The full file name to get the depth of
|
|
33
|
+
*/
|
|
42
34
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* @returns Formatted string - '' for no extension, '.' for empty extension, '.ext' for non-empty extension
|
|
50
|
-
*/
|
|
51
|
-
function fileExtensionToString() {
|
|
52
|
-
var extension = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
53
|
-
return extension.length === 0 ? '' : ".".concat(extension);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Get the depth (how many directories deep it is) of the provided filename with path.
|
|
57
|
-
* @param name The full file name to get the depth of
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
}, {
|
|
61
|
-
key: "getDepth",
|
|
62
|
-
value: function getDepth(name) {
|
|
63
|
-
var _name$match;
|
|
64
|
-
|
|
65
|
-
if (!FileUtils.hasPath(name)) {
|
|
66
|
-
throw new Error("Invalid path provided: ".concat(name));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
var matches = (_name$match = name.match(/\//g)) !== null && _name$match !== void 0 ? _name$match : [];
|
|
70
|
-
return matches.length - 1;
|
|
35
|
+
|
|
36
|
+
static getDepth(name) {
|
|
37
|
+
var _name$match;
|
|
38
|
+
|
|
39
|
+
if (!FileUtils.hasPath(name)) {
|
|
40
|
+
throw new Error("Invalid path provided: ".concat(name));
|
|
71
41
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Get just the extension of file name.
|
|
74
|
-
* Note that it just returns the last extension, so 'example.tar.gz' would just return 'gz'.
|
|
75
|
-
* @param name The file name with or without path to get the extension of
|
|
76
|
-
* @returns The file extension
|
|
77
|
-
*/
|
|
78
42
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
43
|
+
var matches = (_name$match = name.match(/\//g)) !== null && _name$match !== void 0 ? _name$match : [];
|
|
44
|
+
return matches.length - 1;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get just the extension of file name.
|
|
48
|
+
* Note that it just returns the last extension, so 'example.tar.gz' would just return 'gz'.
|
|
49
|
+
* @param name The file name with or without path to get the extension of
|
|
50
|
+
* @returns The file extension
|
|
51
|
+
*/
|
|
83
52
|
|
|
84
|
-
if (components.length > 1) {
|
|
85
|
-
var _components$pop;
|
|
86
53
|
|
|
87
|
-
|
|
88
|
-
|
|
54
|
+
static getExtension(name) {
|
|
55
|
+
var components = this.getBaseName(name).split('.');
|
|
89
56
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
* @param name The full name including path of the file
|
|
95
|
-
* @returns Just the file name part of the file
|
|
96
|
-
*/
|
|
97
|
-
|
|
98
|
-
}, {
|
|
99
|
-
key: "getBaseName",
|
|
100
|
-
value: function getBaseName(name) {
|
|
101
|
-
var _name$split$pop;
|
|
102
|
-
|
|
103
|
-
return (_name$split$pop = name.split('/').pop()) !== null && _name$split$pop !== void 0 ? _name$split$pop : '';
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Create copy file name, used for copying unsaved files so doesn't have to be unique
|
|
107
|
-
* @param originalName File name
|
|
108
|
-
* @returns The file name of the copy
|
|
109
|
-
*/
|
|
110
|
-
|
|
111
|
-
}, {
|
|
112
|
-
key: "getCopyFileName",
|
|
113
|
-
value: function getCopyFileName(originalName) {
|
|
114
|
-
var extensionPosition = originalName.lastIndexOf('.');
|
|
115
|
-
var extension = null;
|
|
116
|
-
var name = null;
|
|
117
|
-
|
|
118
|
-
if (extensionPosition < 0) {
|
|
119
|
-
// No extension
|
|
120
|
-
name = originalName;
|
|
121
|
-
} else {
|
|
122
|
-
name = originalName.substring(0, extensionPosition);
|
|
123
|
-
extension = originalName.substring(extensionPosition + 1);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
var copyName = name ? "".concat(name, "-copy") : 'Copy';
|
|
127
|
-
return extension !== null ? "".concat(copyName, ".").concat(extension) : copyName;
|
|
57
|
+
if (components.length > 1) {
|
|
58
|
+
var _components$pop;
|
|
59
|
+
|
|
60
|
+
return (_components$pop = components.pop()) !== null && _components$pop !== void 0 ? _components$pop : '';
|
|
128
61
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Return a MIME type for the provided file
|
|
131
|
-
* @param name The file name to get the type for
|
|
132
|
-
* @returns A known MIME type if recognized
|
|
133
|
-
*/
|
|
134
62
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the base name portion of the file, eg '/foo/bar.txt' => 'bar.txt'
|
|
67
|
+
* @param name The full name including path of the file
|
|
68
|
+
* @returns Just the file name part of the file
|
|
69
|
+
*/
|
|
139
70
|
|
|
140
|
-
switch (basename) {
|
|
141
|
-
case 'groovy':
|
|
142
|
-
return MIME_TYPE.GROOVY;
|
|
143
71
|
|
|
144
|
-
|
|
145
|
-
|
|
72
|
+
static getBaseName(name) {
|
|
73
|
+
var _name$split$pop;
|
|
146
74
|
|
|
147
|
-
|
|
148
|
-
|
|
75
|
+
return (_name$split$pop = name.split('/').pop()) !== null && _name$split$pop !== void 0 ? _name$split$pop : '';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Create copy file name, used for copying unsaved files so doesn't have to be unique
|
|
79
|
+
* @param originalName File name
|
|
80
|
+
* @returns The file name of the copy
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
static getCopyFileName(originalName) {
|
|
85
|
+
var extensionPosition = originalName.lastIndexOf('.');
|
|
86
|
+
var extension = null;
|
|
87
|
+
var name = null;
|
|
88
|
+
|
|
89
|
+
if (extensionPosition < 0) {
|
|
90
|
+
// No extension
|
|
91
|
+
name = originalName;
|
|
92
|
+
} else {
|
|
93
|
+
name = originalName.substring(0, extensionPosition);
|
|
94
|
+
extension = originalName.substring(extensionPosition + 1);
|
|
95
|
+
}
|
|
149
96
|
|
|
150
|
-
|
|
151
|
-
|
|
97
|
+
var copyName = name ? "".concat(name, "-copy") : 'Copy';
|
|
98
|
+
return extension !== null ? "".concat(copyName, ".").concat(extension) : copyName;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Return a MIME type for the provided file
|
|
102
|
+
* @param name The file name to get the type for
|
|
103
|
+
* @returns A known MIME type if recognized
|
|
104
|
+
*/
|
|
152
105
|
|
|
153
|
-
case 'txt':
|
|
154
|
-
return MIME_TYPE.PLAIN_TEXT;
|
|
155
106
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* @param name The file name to get the parent path of
|
|
163
|
-
*/
|
|
107
|
+
static getMimeType(name) {
|
|
108
|
+
var extension = this.getExtension(name).toLowerCase();
|
|
109
|
+
|
|
110
|
+
switch (extension) {
|
|
111
|
+
case 'groovy':
|
|
112
|
+
return MIME_TYPE.GROOVY;
|
|
164
113
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
value: function getParent(name) {
|
|
168
|
-
if (!FileUtils.hasPath(name)) {
|
|
169
|
-
throw new Error("Invalid name provided: ".concat(name));
|
|
170
|
-
}
|
|
114
|
+
case 'py':
|
|
115
|
+
return MIME_TYPE.PYTHON;
|
|
171
116
|
|
|
172
|
-
|
|
117
|
+
case 'pyc':
|
|
118
|
+
return MIME_TYPE.PYTHON_COMPILED;
|
|
173
119
|
|
|
174
|
-
|
|
175
|
-
;
|
|
176
|
-
}
|
|
120
|
+
case 'scala':
|
|
121
|
+
return MIME_TYPE.SCALA;
|
|
177
122
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
123
|
+
case 'txt':
|
|
124
|
+
return MIME_TYPE.PLAIN_TEXT;
|
|
181
125
|
|
|
182
|
-
|
|
126
|
+
default:
|
|
127
|
+
return MIME_TYPE.UNKNOWN;
|
|
183
128
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
throw new Error("Invalid filename provided: ".concat(name));
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
var parts = name.split('/');
|
|
198
|
-
parts.pop();
|
|
199
|
-
return "".concat(parts.join('/'), "/");
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Pop the last part of the filename component to return the parent path
|
|
132
|
+
* @param name The file name to get the parent path of
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
static getParent(name) {
|
|
137
|
+
if (!FileUtils.hasPath(name)) {
|
|
138
|
+
throw new Error("Invalid name provided: ".concat(name));
|
|
200
139
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}, {
|
|
208
|
-
key: "hasPath",
|
|
209
|
-
value: function hasPath(name) {
|
|
210
|
-
return name.startsWith('/');
|
|
140
|
+
|
|
141
|
+
var parts = name.split('/');
|
|
142
|
+
|
|
143
|
+
while (parts.pop() === '') {
|
|
144
|
+
;
|
|
211
145
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
* @returns True if it's a full path, false otherwise
|
|
216
|
-
*/
|
|
217
|
-
|
|
218
|
-
}, {
|
|
219
|
-
key: "isPath",
|
|
220
|
-
value: function isPath(name) {
|
|
221
|
-
return name.startsWith('/') && name.endsWith('/');
|
|
146
|
+
|
|
147
|
+
if (parts.length === 0) {
|
|
148
|
+
throw new Error("No parent for path provided: ".concat(name));
|
|
222
149
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
150
|
+
|
|
151
|
+
return "".concat(parts.join('/'), "/");
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get the path name portion of the file
|
|
155
|
+
* @param name The full path with or without filename to get the path of
|
|
156
|
+
* @returns Just the path with out the file name part, including trailing slash
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
static getPath(name) {
|
|
161
|
+
if (!FileUtils.hasPath(name)) {
|
|
162
|
+
throw new Error("Invalid filename provided: ".concat(name));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
var parts = name.split('/');
|
|
166
|
+
parts.pop();
|
|
167
|
+
return "".concat(parts.join('/'), "/");
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if a given file name includes the full path
|
|
171
|
+
* @param name The file name to check
|
|
172
|
+
* @returns True if it's a full path, false otherwise
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
static hasPath(name) {
|
|
177
|
+
return name.startsWith('/');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check a given file name is a path
|
|
181
|
+
* @param name The file name to check
|
|
182
|
+
* @returns True if it's a full path, false otherwise
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
static isPath(name) {
|
|
187
|
+
return name.startsWith('/') && name.endsWith('/');
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Turns a directory file name into a path. Basically ensures there's a trailing slash
|
|
191
|
+
* @param name The directory name to make a path
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
static makePath(name) {
|
|
196
|
+
if (!name.endsWith('/')) {
|
|
197
|
+
return "".concat(name, "/");
|
|
236
198
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
199
|
+
|
|
200
|
+
return name;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Replace extension in the item name
|
|
204
|
+
* @param name Name to replace the extension in
|
|
205
|
+
* @param newExtension New extension, defaults to no extension
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
static replaceExtension(name) {
|
|
210
|
+
var newExtension = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
211
|
+
var index = name.lastIndexOf('.');
|
|
212
|
+
var nameWithoutExtension = index > -1 ? name.substring(0, index) : name;
|
|
213
|
+
var extensionString = FileUtils.fileExtensionToString(newExtension);
|
|
214
|
+
return "".concat(nameWithoutExtension).concat(extensionString);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate the provided name. Throws an error if validation fails
|
|
218
|
+
* @param name The item name to validate
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
static validateName(name) {
|
|
223
|
+
// Static checks
|
|
224
|
+
var reservedNames = ['.', '..']; // Global flag to show all invalid chars, not just the first match
|
|
225
|
+
|
|
226
|
+
var invalidCharsRegex = /[\\/\0]/g;
|
|
227
|
+
var invalidCharLabels = new Map([['\0', 'null']]);
|
|
228
|
+
|
|
229
|
+
if (!name) {
|
|
230
|
+
throw new ValidationError("Name cannot be empty");
|
|
251
231
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
*/
|
|
256
|
-
|
|
257
|
-
}, {
|
|
258
|
-
key: "validateName",
|
|
259
|
-
value: function validateName(name) {
|
|
260
|
-
// Static checks
|
|
261
|
-
var reservedNames = ['.', '..']; // Global flag to show all invalid chars, not just the first match
|
|
262
|
-
|
|
263
|
-
var invalidCharsRegex = /[\\/\0]/g;
|
|
264
|
-
var invalidCharLabels = new Map([['\0', 'null']]);
|
|
265
|
-
|
|
266
|
-
if (!name) {
|
|
267
|
-
throw new ValidationError("Name cannot be empty");
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (reservedNames.includes(name)) {
|
|
271
|
-
throw new ValidationError("\"".concat(name, "\" is a reserved name"));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (invalidCharsRegex.test(name)) {
|
|
275
|
-
var _name$match2;
|
|
276
|
-
|
|
277
|
-
throw new ValidationError("Invalid characters in name: \"".concat(((_name$match2 = name.match(invalidCharsRegex)) !== null && _name$match2 !== void 0 ? _name$match2 : []). // Filter out duplicates
|
|
278
|
-
reduce(function (acc, next) {
|
|
279
|
-
return acc.includes(next) ? acc : [].concat(_toConsumableArray(acc), [next]);
|
|
280
|
-
}, []).map(function (_char) {
|
|
281
|
-
return invalidCharLabels.has(_char) ? invalidCharLabels.get(_char) : _char;
|
|
282
|
-
}).join('", "'), "\""));
|
|
283
|
-
}
|
|
232
|
+
|
|
233
|
+
if (reservedNames.includes(name)) {
|
|
234
|
+
throw new ValidationError("\"".concat(name, "\" is a reserved name"));
|
|
284
235
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}, {
|
|
292
|
-
key: "reducePaths",
|
|
293
|
-
value: function reducePaths(paths) {
|
|
294
|
-
var folders = paths.filter(function (path) {
|
|
295
|
-
return FileUtils.isPath(path);
|
|
296
|
-
});
|
|
297
|
-
return paths.filter(function (path) {
|
|
298
|
-
return !folders.some(function (folder) {
|
|
299
|
-
return path !== folder && path.startsWith(folder);
|
|
300
|
-
});
|
|
301
|
-
});
|
|
236
|
+
|
|
237
|
+
if (invalidCharsRegex.test(name)) {
|
|
238
|
+
var _name$match2;
|
|
239
|
+
|
|
240
|
+
throw new ValidationError("Invalid characters in name: \"".concat(((_name$match2 = name.match(invalidCharsRegex)) !== null && _name$match2 !== void 0 ? _name$match2 : []). // Filter out duplicates
|
|
241
|
+
reduce((acc, next) => acc.includes(next) ? acc : [...acc, next], []).map(char => invalidCharLabels.has(char) ? invalidCharLabels.get(char) : char).join('", "'), "\""));
|
|
302
242
|
}
|
|
303
|
-
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Reduce the provided paths to the minimum selection.
|
|
246
|
+
* Removes any nested files or directories if a parent is already selected.
|
|
247
|
+
* @param paths The paths to reduce
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
static reducePaths(paths) {
|
|
252
|
+
var folders = paths.filter(path => FileUtils.isPath(path));
|
|
253
|
+
return paths.filter(path => !folders.some(folder => path !== folder && path.startsWith(folder)));
|
|
254
|
+
}
|
|
304
255
|
|
|
305
|
-
|
|
306
|
-
}();
|
|
256
|
+
}
|
|
307
257
|
export default FileUtils;
|
|
308
258
|
//# sourceMappingURL=FileUtils.js.map
|
package/dist/FileUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileUtils.ts"],"names":["ValidationError","MIME_TYPE","FileUtils","extension","length","name","hasPath","Error","matches","match","components","getBaseName","split","pop","originalName","extensionPosition","lastIndexOf","substring","copyName","basename","toLowerCase","GROOVY","PYTHON","PYTHON_COMPILED","SCALA","PLAIN_TEXT","UNKNOWN","parts","join","startsWith","endsWith","newExtension","index","nameWithoutExtension","extensionString","fileExtensionToString","reservedNames","invalidCharsRegex","invalidCharLabels","Map","includes","test","reduce","acc","next","map","char","has","get","paths","folders","filter","path","isPath","some","folder"],"mappings":"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","sourcesContent":["import { ValidationError } from '@deephaven/utils';\n\n/**\n * A basic list of some common MIME types.\n */\nexport enum MIME_TYPE {\n GROOVY = 'text/x-groovy',\n PLAIN_TEXT = 'text/plain',\n PYTHON = 'text/x-python',\n PYTHON_COMPILED = 'application/x-python-code',\n SCALA = 'text/x-scala',\n UNKNOWN = '',\n}\n\n/**\n * Collection of utils for operating on file names\n */\nexport class FileUtils {\n /**\n * Format file extension\n * @param extension File extension to format, defaults to empty string\n * @returns Formatted string - '' for no extension, '.' for empty extension, '.ext' for non-empty extension\n */\n static fileExtensionToString(extension = ''): string {\n return extension.length === 0 ? '' : `.${extension}`;\n }\n\n /**\n * Get the depth (how many directories deep it is) of the provided filename with path.\n * @param name The full file name to get the depth of\n */\n static getDepth(name: string): number {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid path provided: ${name}`);\n }\n const matches = name.match(/\\//g) ?? [];\n return matches.length - 1;\n }\n\n /**\n * Get just the extension of file name.\n * Note that it just returns the last extension, so 'example.tar.gz' would just return 'gz'.\n * @param name The file name with or without path to get the extension of\n * @returns The file extension\n */\n static getExtension(name: string): string {\n const components = this.getBaseName(name).split('.');\n if (components.length > 1) {\n return components.pop() ?? '';\n }\n return '';\n }\n\n /**\n * Get the base name portion of the file, eg '/foo/bar.txt' => 'bar.txt'\n * @param name The full name including path of the file\n * @returns Just the file name part of the file\n */\n static getBaseName(name: string): string {\n return name.split('/').pop() ?? '';\n }\n\n /**\n * Create copy file name, used for copying unsaved files so doesn't have to be unique\n * @param originalName File name\n * @returns The file name of the copy\n */\n static getCopyFileName(originalName: string): string {\n const extensionPosition = originalName.lastIndexOf('.');\n let extension = null;\n let name = null;\n if (extensionPosition < 0) {\n // No extension\n name = originalName;\n } else {\n name = originalName.substring(0, extensionPosition);\n extension = originalName.substring(extensionPosition + 1);\n }\n const copyName = name ? `${name}-copy` : 'Copy';\n return extension !== null ? `${copyName}.${extension}` : copyName;\n }\n\n /**\n * Return a MIME type for the provided file\n * @param name The file name to get the type for\n * @returns A known MIME type if recognized\n */\n static getMimeType(name: string): MIME_TYPE {\n const basename = this.getBaseName(name).toLowerCase();\n switch (basename) {\n case 'groovy':\n return MIME_TYPE.GROOVY;\n case 'py':\n return MIME_TYPE.PYTHON;\n case 'pyc':\n return MIME_TYPE.PYTHON_COMPILED;\n case 'scala':\n return MIME_TYPE.SCALA;\n case 'txt':\n return MIME_TYPE.PLAIN_TEXT;\n default:\n return MIME_TYPE.UNKNOWN;\n }\n }\n\n /**\n * Pop the last part of the filename component to return the parent path\n * @param name The file name to get the parent path of\n */\n static getParent(name: string): string {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid name provided: ${name}`);\n }\n\n const parts = name.split('/');\n while (parts.pop() === '');\n if (parts.length === 0) {\n throw new Error(`No parent for path provided: ${name}`);\n }\n return `${parts.join('/')}/`;\n }\n\n /**\n * Get the path name portion of the file\n * @param name The full path with or without filename to get the path of\n * @returns Just the path with out the file name part, including trailing slash\n */\n static getPath(name: string): string {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid filename provided: ${name}`);\n }\n const parts = name.split('/');\n parts.pop();\n return `${parts.join('/')}/`;\n }\n\n /**\n * Check if a given file name includes the full path\n * @param name The file name to check\n * @returns True if it's a full path, false otherwise\n */\n static hasPath(name: string): boolean {\n return name.startsWith('/');\n }\n\n /**\n * Check a given file name is a path\n * @param name The file name to check\n * @returns True if it's a full path, false otherwise\n */\n static isPath(name: string): boolean {\n return name.startsWith('/') && name.endsWith('/');\n }\n\n /**\n * Turns a directory file name into a path. Basically ensures there's a trailing slash\n * @param name The directory name to make a path\n */\n static makePath(name: string): string {\n if (!name.endsWith('/')) {\n return `${name}/`;\n }\n return name;\n }\n\n /**\n * Replace extension in the item name\n * @param name Name to replace the extension in\n * @param newExtension New extension, defaults to no extension\n */\n static replaceExtension(name: string, newExtension = ''): string {\n const index = name.lastIndexOf('.');\n const nameWithoutExtension = index > -1 ? name.substring(0, index) : name;\n const extensionString = FileUtils.fileExtensionToString(newExtension);\n return `${nameWithoutExtension}${extensionString}`;\n }\n\n /**\n * Validate the provided name. Throws an error if validation fails\n * @param name The item name to validate\n */\n static validateName(name: string): void {\n // Static checks\n const reservedNames = ['.', '..'];\n // Global flag to show all invalid chars, not just the first match\n const invalidCharsRegex = /[\\\\/\\0]/g;\n const invalidCharLabels = new Map([['\\0', 'null']]);\n\n if (!name) {\n throw new ValidationError(`Name cannot be empty`);\n }\n if (reservedNames.includes(name)) {\n throw new ValidationError(`\"${name}\" is a reserved name`);\n }\n if (invalidCharsRegex.test(name)) {\n throw new ValidationError(\n `Invalid characters in name: \"${(name.match(invalidCharsRegex) ?? [])\n // Filter out duplicates\n .reduce(\n (acc, next) => (acc.includes(next) ? acc : [...acc, next]),\n [] as string[]\n )\n .map(char =>\n invalidCharLabels.has(char) ? invalidCharLabels.get(char) : char\n )\n .join('\", \"')}\"`\n );\n }\n }\n\n /**\n * Reduce the provided paths to the minimum selection.\n * Removes any nested files or directories if a parent is already selected.\n * @param paths The paths to reduce\n */\n static reducePaths(paths: string[]): string[] {\n const folders = paths.filter(path => FileUtils.isPath(path));\n return paths.filter(\n path =>\n !folders.some(folder => path !== folder && path.startsWith(folder))\n );\n }\n}\n\nexport default FileUtils;\n"],"file":"FileUtils.js"}
|
|
1
|
+
{"version":3,"sources":["../src/FileUtils.ts"],"names":["ValidationError","MIME_TYPE","FileUtils","fileExtensionToString","extension","length","getDepth","name","hasPath","Error","matches","match","getExtension","components","getBaseName","split","pop","getCopyFileName","originalName","extensionPosition","lastIndexOf","substring","copyName","getMimeType","toLowerCase","GROOVY","PYTHON","PYTHON_COMPILED","SCALA","PLAIN_TEXT","UNKNOWN","getParent","parts","join","getPath","startsWith","isPath","endsWith","makePath","replaceExtension","newExtension","index","nameWithoutExtension","extensionString","validateName","reservedNames","invalidCharsRegex","invalidCharLabels","Map","includes","test","reduce","acc","next","map","char","has","get","reducePaths","paths","folders","filter","path","some","folder"],"mappings":"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","sourcesContent":["import { ValidationError } from '@deephaven/utils';\n\n/**\n * A basic list of some common MIME types.\n */\nexport enum MIME_TYPE {\n GROOVY = 'text/x-groovy',\n PLAIN_TEXT = 'text/plain',\n PYTHON = 'text/x-python',\n PYTHON_COMPILED = 'application/x-python-code',\n SCALA = 'text/x-scala',\n UNKNOWN = '',\n}\n\n/**\n * Collection of utils for operating on file names\n */\nexport class FileUtils {\n /**\n * Format file extension\n * @param extension File extension to format, defaults to empty string\n * @returns Formatted string - '' for no extension, '.' for empty extension, '.ext' for non-empty extension\n */\n static fileExtensionToString(extension = ''): string {\n return extension.length === 0 ? '' : `.${extension}`;\n }\n\n /**\n * Get the depth (how many directories deep it is) of the provided filename with path.\n * @param name The full file name to get the depth of\n */\n static getDepth(name: string): number {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid path provided: ${name}`);\n }\n const matches = name.match(/\\//g) ?? [];\n return matches.length - 1;\n }\n\n /**\n * Get just the extension of file name.\n * Note that it just returns the last extension, so 'example.tar.gz' would just return 'gz'.\n * @param name The file name with or without path to get the extension of\n * @returns The file extension\n */\n static getExtension(name: string): string {\n const components = this.getBaseName(name).split('.');\n if (components.length > 1) {\n return components.pop() ?? '';\n }\n return '';\n }\n\n /**\n * Get the base name portion of the file, eg '/foo/bar.txt' => 'bar.txt'\n * @param name The full name including path of the file\n * @returns Just the file name part of the file\n */\n static getBaseName(name: string): string {\n return name.split('/').pop() ?? '';\n }\n\n /**\n * Create copy file name, used for copying unsaved files so doesn't have to be unique\n * @param originalName File name\n * @returns The file name of the copy\n */\n static getCopyFileName(originalName: string): string {\n const extensionPosition = originalName.lastIndexOf('.');\n let extension = null;\n let name = null;\n if (extensionPosition < 0) {\n // No extension\n name = originalName;\n } else {\n name = originalName.substring(0, extensionPosition);\n extension = originalName.substring(extensionPosition + 1);\n }\n const copyName = name ? `${name}-copy` : 'Copy';\n return extension !== null ? `${copyName}.${extension}` : copyName;\n }\n\n /**\n * Return a MIME type for the provided file\n * @param name The file name to get the type for\n * @returns A known MIME type if recognized\n */\n static getMimeType(name: string): MIME_TYPE {\n const extension = this.getExtension(name).toLowerCase();\n switch (extension) {\n case 'groovy':\n return MIME_TYPE.GROOVY;\n case 'py':\n return MIME_TYPE.PYTHON;\n case 'pyc':\n return MIME_TYPE.PYTHON_COMPILED;\n case 'scala':\n return MIME_TYPE.SCALA;\n case 'txt':\n return MIME_TYPE.PLAIN_TEXT;\n default:\n return MIME_TYPE.UNKNOWN;\n }\n }\n\n /**\n * Pop the last part of the filename component to return the parent path\n * @param name The file name to get the parent path of\n */\n static getParent(name: string): string {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid name provided: ${name}`);\n }\n\n const parts = name.split('/');\n while (parts.pop() === '');\n if (parts.length === 0) {\n throw new Error(`No parent for path provided: ${name}`);\n }\n return `${parts.join('/')}/`;\n }\n\n /**\n * Get the path name portion of the file\n * @param name The full path with or without filename to get the path of\n * @returns Just the path with out the file name part, including trailing slash\n */\n static getPath(name: string): string {\n if (!FileUtils.hasPath(name)) {\n throw new Error(`Invalid filename provided: ${name}`);\n }\n const parts = name.split('/');\n parts.pop();\n return `${parts.join('/')}/`;\n }\n\n /**\n * Check if a given file name includes the full path\n * @param name The file name to check\n * @returns True if it's a full path, false otherwise\n */\n static hasPath(name: string): boolean {\n return name.startsWith('/');\n }\n\n /**\n * Check a given file name is a path\n * @param name The file name to check\n * @returns True if it's a full path, false otherwise\n */\n static isPath(name: string): boolean {\n return name.startsWith('/') && name.endsWith('/');\n }\n\n /**\n * Turns a directory file name into a path. Basically ensures there's a trailing slash\n * @param name The directory name to make a path\n */\n static makePath(name: string): string {\n if (!name.endsWith('/')) {\n return `${name}/`;\n }\n return name;\n }\n\n /**\n * Replace extension in the item name\n * @param name Name to replace the extension in\n * @param newExtension New extension, defaults to no extension\n */\n static replaceExtension(name: string, newExtension = ''): string {\n const index = name.lastIndexOf('.');\n const nameWithoutExtension = index > -1 ? name.substring(0, index) : name;\n const extensionString = FileUtils.fileExtensionToString(newExtension);\n return `${nameWithoutExtension}${extensionString}`;\n }\n\n /**\n * Validate the provided name. Throws an error if validation fails\n * @param name The item name to validate\n */\n static validateName(name: string): void {\n // Static checks\n const reservedNames = ['.', '..'];\n // Global flag to show all invalid chars, not just the first match\n const invalidCharsRegex = /[\\\\/\\0]/g;\n const invalidCharLabels = new Map([['\\0', 'null']]);\n\n if (!name) {\n throw new ValidationError(`Name cannot be empty`);\n }\n if (reservedNames.includes(name)) {\n throw new ValidationError(`\"${name}\" is a reserved name`);\n }\n if (invalidCharsRegex.test(name)) {\n throw new ValidationError(\n `Invalid characters in name: \"${(name.match(invalidCharsRegex) ?? [])\n // Filter out duplicates\n .reduce(\n (acc, next) => (acc.includes(next) ? acc : [...acc, next]),\n [] as string[]\n )\n .map(char =>\n invalidCharLabels.has(char) ? invalidCharLabels.get(char) : char\n )\n .join('\", \"')}\"`\n );\n }\n }\n\n /**\n * Reduce the provided paths to the minimum selection.\n * Removes any nested files or directories if a parent is already selected.\n * @param paths The paths to reduce\n */\n static reducePaths(paths: string[]): string[] {\n const folders = paths.filter(path => FileUtils.isPath(path));\n return paths.filter(\n path =>\n !folders.some(folder => path !== folder && path.startsWith(folder))\n );\n }\n}\n\nexport default FileUtils;\n"],"file":"FileUtils.js"}
|