@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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/FileNotFoundError.ts"],"names":["FileNotFoundError","Error"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;IAAMA,iB;;;;;AACJ,+BAAc;AAAA;;AAAA;;AACZ,8BAAM,sCAAN;;AADY,qEAIG,IAJH;;AAAA;AAEb;;;iCAH6BC,K;;AAQhC,eAAeD,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"}
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 var FileUtils = /*#__PURE__*/function () {
39
- function FileUtils() {
40
- _classCallCheck(this, FileUtils);
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
- _createClass(FileUtils, null, [{
44
- key: "fileExtensionToString",
45
- value:
46
- /**
47
- * Format file extension
48
- * @param extension File extension to format, defaults to empty string
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
- key: "getExtension",
81
- value: function getExtension(name) {
82
- var components = this.getBaseName(name).split('.');
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
- return (_components$pop = components.pop()) !== null && _components$pop !== void 0 ? _components$pop : '';
88
- }
54
+ static getExtension(name) {
55
+ var components = this.getBaseName(name).split('.');
89
56
 
90
- return '';
91
- }
92
- /**
93
- * Get the base name portion of the file, eg '/foo/bar.txt' => 'bar.txt'
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
- key: "getMimeType",
137
- value: function getMimeType(name) {
138
- var basename = this.getBaseName(name).toLowerCase();
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
- case 'py':
145
- return MIME_TYPE.PYTHON;
72
+ static getBaseName(name) {
73
+ var _name$split$pop;
146
74
 
147
- case 'pyc':
148
- return MIME_TYPE.PYTHON_COMPILED;
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
- case 'scala':
151
- return MIME_TYPE.SCALA;
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
- default:
157
- return MIME_TYPE.UNKNOWN;
158
- }
159
- }
160
- /**
161
- * Pop the last part of the filename component to return the parent path
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
- key: "getParent",
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
- var parts = name.split('/');
117
+ case 'pyc':
118
+ return MIME_TYPE.PYTHON_COMPILED;
173
119
 
174
- while (parts.pop() === '') {
175
- ;
176
- }
120
+ case 'scala':
121
+ return MIME_TYPE.SCALA;
177
122
 
178
- if (parts.length === 0) {
179
- throw new Error("No parent for path provided: ".concat(name));
180
- }
123
+ case 'txt':
124
+ return MIME_TYPE.PLAIN_TEXT;
181
125
 
182
- return "".concat(parts.join('/'), "/");
126
+ default:
127
+ return MIME_TYPE.UNKNOWN;
183
128
  }
184
- /**
185
- * Get the path name portion of the file
186
- * @param name The full path with or without filename to get the path of
187
- * @returns Just the path with out the file name part, including trailing slash
188
- */
189
-
190
- }, {
191
- key: "getPath",
192
- value: function getPath(name) {
193
- if (!FileUtils.hasPath(name)) {
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
- * Check if a given file name includes the full path
203
- * @param name The file name to check
204
- * @returns True if it's a full path, false otherwise
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
- * Check a given file name is a path
214
- * @param name The file name to check
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
- * Turns a directory file name into a path. Basically ensures there's a trailing slash
225
- * @param name The directory name to make a path
226
- */
227
-
228
- }, {
229
- key: "makePath",
230
- value: function makePath(name) {
231
- if (!name.endsWith('/')) {
232
- return "".concat(name, "/");
233
- }
234
-
235
- return name;
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
- * Replace extension in the item name
239
- * @param name Name to replace the extension in
240
- * @param newExtension New extension, defaults to no extension
241
- */
242
-
243
- }, {
244
- key: "replaceExtension",
245
- value: function replaceExtension(name) {
246
- var newExtension = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
247
- var index = name.lastIndexOf('.');
248
- var nameWithoutExtension = index > -1 ? name.substring(0, index) : name;
249
- var extensionString = FileUtils.fileExtensionToString(newExtension);
250
- return "".concat(nameWithoutExtension).concat(extensionString);
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
- * Validate the provided name. Throws an error if validation fails
254
- * @param name The item name to validate
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
- * Reduce the provided paths to the minimum selection.
287
- * Removes any nested files or directories if a parent is already selected.
288
- * @param paths The paths to reduce
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
- return FileUtils;
306
- }();
256
+ }
307
257
  export default FileUtils;
308
258
  //# sourceMappingURL=FileUtils.js.map
@@ -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"}