@deephaven/file-explorer 0.22.3-beta.15 → 0.22.3-beta.21
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 +0 -7
- package/dist/FileExistsError.js.map +1 -1
- package/dist/FileExplorer.d.ts +4 -4
- package/dist/FileExplorer.d.ts.map +1 -1
- package/dist/FileExplorer.js +4 -19
- package/dist/FileExplorer.js.map +1 -1
- package/dist/FileExplorerShortcuts.js.map +1 -1
- package/dist/FileExplorerToolbar.d.ts +1 -1
- package/dist/FileExplorerToolbar.d.ts.map +1 -1
- package/dist/FileExplorerToolbar.js +2 -2
- package/dist/FileExplorerToolbar.js.map +1 -1
- package/dist/FileList.d.ts +1 -1
- package/dist/FileList.d.ts.map +1 -1
- package/dist/FileList.js +18 -56
- package/dist/FileList.js.map +1 -1
- package/dist/FileListContainer.d.ts +4 -4
- package/dist/FileListContainer.d.ts.map +1 -1
- package/dist/FileListContainer.js +2 -16
- package/dist/FileListContainer.js.map +1 -1
- package/dist/FileListItemEditor.d.ts +1 -1
- package/dist/FileListItemEditor.d.ts.map +1 -1
- package/dist/FileListItemEditor.js +4 -7
- package/dist/FileListItemEditor.js.map +1 -1
- package/dist/FileNotFoundError.js +0 -4
- package/dist/FileNotFoundError.js.map +1 -1
- package/dist/FileStorage.js +2 -0
- package/dist/FileStorage.js.map +1 -1
- package/dist/FileUtils.js +19 -62
- package/dist/FileUtils.js.map +1 -1
- package/dist/NewItemModal.js +5 -65
- package/dist/NewItemModal.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/FileUtils.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ValidationError } from '@deephaven/utils';
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* A basic list of some common MIME types.
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
6
|
export var MIME_TYPE;
|
|
7
|
+
|
|
7
8
|
/**
|
|
8
9
|
* Collection of utils for operating on file names
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
11
|
(function (MIME_TYPE) {
|
|
12
12
|
MIME_TYPE["GROOVY"] = "text/x-groovy";
|
|
13
13
|
MIME_TYPE["PLAIN_TEXT"] = "text/plain";
|
|
@@ -16,7 +16,6 @@ export var MIME_TYPE;
|
|
|
16
16
|
MIME_TYPE["SCALA"] = "text/x-scala";
|
|
17
17
|
MIME_TYPE["UNKNOWN"] = "";
|
|
18
18
|
})(MIME_TYPE || (MIME_TYPE = {}));
|
|
19
|
-
|
|
20
19
|
export class FileUtils {
|
|
21
20
|
/**
|
|
22
21
|
* Format file extension
|
|
@@ -27,65 +26,54 @@ export class FileUtils {
|
|
|
27
26
|
var extension = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
28
27
|
return extension.length === 0 ? '' : ".".concat(extension);
|
|
29
28
|
}
|
|
29
|
+
|
|
30
30
|
/**
|
|
31
31
|
* Get the depth (how many directories deep it is) of the provided filename with path.
|
|
32
32
|
* @param name The full file name to get the depth of
|
|
33
33
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
34
|
static getDepth(name) {
|
|
37
35
|
var _name$match;
|
|
38
|
-
|
|
39
36
|
if (!FileUtils.hasPath(name)) {
|
|
40
37
|
throw new Error("Invalid path provided: ".concat(name));
|
|
41
38
|
}
|
|
42
|
-
|
|
43
39
|
var matches = (_name$match = name.match(/\//g)) !== null && _name$match !== void 0 ? _name$match : [];
|
|
44
40
|
return matches.length - 1;
|
|
45
41
|
}
|
|
42
|
+
|
|
46
43
|
/**
|
|
47
44
|
* Get just the extension of file name.
|
|
48
45
|
* Note that it just returns the last extension, so 'example.tar.gz' would just return 'gz'.
|
|
49
46
|
* @param name The file name with or without path to get the extension of
|
|
50
47
|
* @returns The file extension
|
|
51
48
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
49
|
static getExtension(name) {
|
|
55
50
|
var components = this.getBaseName(name).split('.');
|
|
56
|
-
|
|
57
51
|
if (components.length > 1) {
|
|
58
52
|
var _components$pop;
|
|
59
|
-
|
|
60
53
|
return (_components$pop = components.pop()) !== null && _components$pop !== void 0 ? _components$pop : '';
|
|
61
54
|
}
|
|
62
|
-
|
|
63
55
|
return '';
|
|
64
56
|
}
|
|
57
|
+
|
|
65
58
|
/**
|
|
66
59
|
* Get the base name portion of the file, eg '/foo/bar.txt' => 'bar.txt'
|
|
67
60
|
* @param name The full name including path of the file
|
|
68
61
|
* @returns Just the file name part of the file
|
|
69
62
|
*/
|
|
70
|
-
|
|
71
|
-
|
|
72
63
|
static getBaseName(name) {
|
|
73
64
|
var _name$split$pop;
|
|
74
|
-
|
|
75
65
|
return (_name$split$pop = name.split('/').pop()) !== null && _name$split$pop !== void 0 ? _name$split$pop : '';
|
|
76
66
|
}
|
|
67
|
+
|
|
77
68
|
/**
|
|
78
69
|
* Create copy file name, used for copying unsaved files so doesn't have to be unique
|
|
79
70
|
* @param originalName File name
|
|
80
71
|
* @returns The file name of the copy
|
|
81
72
|
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
73
|
static getCopyFileName(originalName) {
|
|
85
74
|
var extensionPosition = originalName.lastIndexOf('.');
|
|
86
75
|
var extension = null;
|
|
87
76
|
var name = null;
|
|
88
|
-
|
|
89
77
|
if (extensionPosition < 0) {
|
|
90
78
|
// No extension
|
|
91
79
|
name = originalName;
|
|
@@ -93,119 +81,99 @@ export class FileUtils {
|
|
|
93
81
|
name = originalName.substring(0, extensionPosition);
|
|
94
82
|
extension = originalName.substring(extensionPosition + 1);
|
|
95
83
|
}
|
|
96
|
-
|
|
97
84
|
var copyName = name ? "".concat(name, "-copy") : 'Copy';
|
|
98
85
|
return extension !== null ? "".concat(copyName, ".").concat(extension) : copyName;
|
|
99
86
|
}
|
|
87
|
+
|
|
100
88
|
/**
|
|
101
89
|
* Return a MIME type for the provided file
|
|
102
90
|
* @param name The file name to get the type for
|
|
103
91
|
* @returns A known MIME type if recognized
|
|
104
92
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
107
93
|
static getMimeType(name) {
|
|
108
94
|
var extension = this.getExtension(name).toLowerCase();
|
|
109
|
-
|
|
110
95
|
switch (extension) {
|
|
111
96
|
case 'groovy':
|
|
112
97
|
return MIME_TYPE.GROOVY;
|
|
113
|
-
|
|
114
98
|
case 'py':
|
|
115
99
|
return MIME_TYPE.PYTHON;
|
|
116
|
-
|
|
117
100
|
case 'pyc':
|
|
118
101
|
return MIME_TYPE.PYTHON_COMPILED;
|
|
119
|
-
|
|
120
102
|
case 'scala':
|
|
121
103
|
return MIME_TYPE.SCALA;
|
|
122
|
-
|
|
123
104
|
case 'txt':
|
|
124
105
|
return MIME_TYPE.PLAIN_TEXT;
|
|
125
|
-
|
|
126
106
|
default:
|
|
127
107
|
return MIME_TYPE.UNKNOWN;
|
|
128
108
|
}
|
|
129
109
|
}
|
|
110
|
+
|
|
130
111
|
/**
|
|
131
112
|
* Pop the last part of the filename component to return the parent path
|
|
132
113
|
* @param name The file name to get the parent path of
|
|
133
114
|
*/
|
|
134
|
-
|
|
135
|
-
|
|
136
115
|
static getParent(name) {
|
|
137
116
|
if (!FileUtils.hasPath(name)) {
|
|
138
117
|
throw new Error("Invalid name provided: ".concat(name));
|
|
139
118
|
}
|
|
140
|
-
|
|
141
119
|
var parts = name.split('/');
|
|
142
|
-
|
|
143
120
|
while (parts.pop() === '') {
|
|
144
121
|
;
|
|
145
122
|
}
|
|
146
|
-
|
|
147
123
|
if (parts.length === 0) {
|
|
148
124
|
throw new Error("No parent for path provided: ".concat(name));
|
|
149
125
|
}
|
|
150
|
-
|
|
151
126
|
return "".concat(parts.join('/'), "/");
|
|
152
127
|
}
|
|
128
|
+
|
|
153
129
|
/**
|
|
154
130
|
* Get the path name portion of the file
|
|
155
131
|
* @param name The full path with or without filename to get the path of
|
|
156
132
|
* @returns Just the path with out the file name part, including trailing slash
|
|
157
133
|
*/
|
|
158
|
-
|
|
159
|
-
|
|
160
134
|
static getPath(name) {
|
|
161
135
|
if (!FileUtils.hasPath(name)) {
|
|
162
136
|
throw new Error("Invalid filename provided: ".concat(name));
|
|
163
137
|
}
|
|
164
|
-
|
|
165
138
|
var parts = name.split('/');
|
|
166
139
|
parts.pop();
|
|
167
140
|
return "".concat(parts.join('/'), "/");
|
|
168
141
|
}
|
|
142
|
+
|
|
169
143
|
/**
|
|
170
144
|
* Check if a given file name includes the full path
|
|
171
145
|
* @param name The file name to check
|
|
172
146
|
* @returns True if it's a full path, false otherwise
|
|
173
147
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
176
148
|
static hasPath(name) {
|
|
177
149
|
return name.startsWith('/');
|
|
178
150
|
}
|
|
151
|
+
|
|
179
152
|
/**
|
|
180
153
|
* Check a given file name is a path
|
|
181
154
|
* @param name The file name to check
|
|
182
155
|
* @returns True if it's a full path, false otherwise
|
|
183
156
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
157
|
static isPath(name) {
|
|
187
158
|
return name.startsWith('/') && name.endsWith('/');
|
|
188
159
|
}
|
|
160
|
+
|
|
189
161
|
/**
|
|
190
162
|
* Turns a directory file name into a path. Basically ensures there's a trailing slash
|
|
191
163
|
* @param name The directory name to make a path
|
|
192
164
|
*/
|
|
193
|
-
|
|
194
|
-
|
|
195
165
|
static makePath(name) {
|
|
196
166
|
if (!name.endsWith('/')) {
|
|
197
167
|
return "".concat(name, "/");
|
|
198
168
|
}
|
|
199
|
-
|
|
200
169
|
return name;
|
|
201
170
|
}
|
|
171
|
+
|
|
202
172
|
/**
|
|
203
173
|
* Replace extension in the item name
|
|
204
174
|
* @param name Name to replace the extension in
|
|
205
175
|
* @param newExtension New extension, defaults to no extension
|
|
206
176
|
*/
|
|
207
|
-
|
|
208
|
-
|
|
209
177
|
static replaceExtension(name) {
|
|
210
178
|
var newExtension = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
211
179
|
var index = name.lastIndexOf('.');
|
|
@@ -213,75 +181,64 @@ export class FileUtils {
|
|
|
213
181
|
var extensionString = FileUtils.fileExtensionToString(newExtension);
|
|
214
182
|
return "".concat(nameWithoutExtension).concat(extensionString);
|
|
215
183
|
}
|
|
184
|
+
|
|
216
185
|
/**
|
|
217
186
|
* Validate the provided name. Throws an error if validation fails
|
|
218
187
|
* @param name The item name to validate
|
|
219
188
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
189
|
static validateName(name) {
|
|
223
190
|
// Static checks
|
|
224
|
-
var reservedNames = ['.', '..'];
|
|
225
|
-
|
|
191
|
+
var reservedNames = ['.', '..'];
|
|
192
|
+
// Global flag to show all invalid chars, not just the first match
|
|
226
193
|
var invalidCharsRegex = /[\\/\0]/g;
|
|
227
194
|
var invalidCharLabels = new Map([['\0', 'null']]);
|
|
228
|
-
|
|
229
195
|
if (!name) {
|
|
230
196
|
throw new ValidationError("Name cannot be empty");
|
|
231
197
|
}
|
|
232
|
-
|
|
233
198
|
if (reservedNames.includes(name)) {
|
|
234
199
|
throw new ValidationError("\"".concat(name, "\" is a reserved name"));
|
|
235
200
|
}
|
|
236
|
-
|
|
237
201
|
if (invalidCharsRegex.test(name)) {
|
|
238
202
|
var _name$match2;
|
|
239
|
-
|
|
240
203
|
throw new ValidationError("Invalid characters in name: \"".concat(((_name$match2 = name.match(invalidCharsRegex)) !== null && _name$match2 !== void 0 ? _name$match2 : [] // Filter out duplicates
|
|
241
204
|
).reduce((acc, next) => acc.includes(next) ? acc : [...acc, next], []).map(char => invalidCharLabels.has(char) ? invalidCharLabels.get(char) : char).join('", "'), "\""));
|
|
242
205
|
}
|
|
243
206
|
}
|
|
207
|
+
|
|
244
208
|
/**
|
|
245
209
|
* Reduce the provided paths to the minimum selection.
|
|
246
210
|
* Removes any nested files or directories if a parent is already selected.
|
|
247
211
|
* @param paths The paths to reduce
|
|
248
212
|
*/
|
|
249
|
-
|
|
250
|
-
|
|
251
213
|
static reducePaths(paths) {
|
|
252
214
|
var folders = paths.filter(path => FileUtils.isPath(path));
|
|
253
215
|
return paths.filter(path => !folders.some(folder => path !== folder && path.startsWith(folder)));
|
|
254
216
|
}
|
|
217
|
+
|
|
255
218
|
/**
|
|
256
219
|
* Removes the root path from the provided file name. Throws if the filename does not start with root.
|
|
257
220
|
* @param root The root to remove
|
|
258
221
|
* @param filename Filename to remove the root path from
|
|
259
222
|
* @returns Filename without the root
|
|
260
223
|
*/
|
|
261
|
-
|
|
262
|
-
|
|
263
224
|
static removeRoot(root, filename) {
|
|
264
225
|
if (root.length === 0) {
|
|
265
226
|
return filename;
|
|
266
227
|
}
|
|
267
|
-
|
|
268
228
|
if (!filename.startsWith(root)) {
|
|
269
229
|
throw new Error("Filename ".concat(filename, " does not start with expected root ").concat(root));
|
|
270
230
|
}
|
|
271
|
-
|
|
272
231
|
return filename.substring(root.length);
|
|
273
232
|
}
|
|
233
|
+
|
|
274
234
|
/**
|
|
275
235
|
* Add root to the filename as prefix
|
|
276
236
|
* @param path Filename to prefix root to
|
|
277
237
|
* @returns Filename with root at the prefix
|
|
278
238
|
*/
|
|
279
|
-
|
|
280
|
-
|
|
281
239
|
static addRoot(root, path) {
|
|
282
240
|
return "".concat(root).concat(path);
|
|
283
241
|
}
|
|
284
|
-
|
|
285
242
|
}
|
|
286
243
|
export default FileUtils;
|
|
287
244
|
//# sourceMappingURL=FileUtils.js.map
|
package/dist/FileUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileUtils.js","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","removeRoot","root","filename","addRoot"],"sources":["../src/FileUtils.ts"],"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 /**\n * Removes the root path from the provided file name. Throws if the filename does not start with root.\n * @param root The root to remove\n * @param filename Filename to remove the root path from\n * @returns Filename without the root\n */\n static removeRoot(root: string, filename: string): string {\n if (root.length === 0) {\n return filename;\n }\n if (!filename.startsWith(root)) {\n throw new Error(\n `Filename ${filename} does not start with expected root ${root}`\n );\n }\n\n return filename.substring(root.length);\n }\n\n /**\n * Add root to the filename as prefix\n * @param path Filename to prefix root to\n * @returns Filename with root at the prefix\n */\n static addRoot(root: string, path: string): string {\n return `${root}${path}`;\n }\n}\n\nexport default FileUtils;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileUtils.js","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","removeRoot","root","filename","addRoot"],"sources":["../src/FileUtils.ts"],"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 /**\n * Removes the root path from the provided file name. Throws if the filename does not start with root.\n * @param root The root to remove\n * @param filename Filename to remove the root path from\n * @returns Filename without the root\n */\n static removeRoot(root: string, filename: string): string {\n if (root.length === 0) {\n return filename;\n }\n if (!filename.startsWith(root)) {\n throw new Error(\n `Filename ${filename} does not start with expected root ${root}`\n );\n }\n\n return filename.substring(root.length);\n }\n\n /**\n * Add root to the filename as prefix\n * @param path Filename to prefix root to\n * @returns Filename with root at the prefix\n */\n static addRoot(root: string, path: string): string {\n return `${root}${path}`;\n }\n}\n\nexport default FileUtils;\n"],"mappings":"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"}
|