@etsoo/shared 1.2.13 → 1.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/__tests__/Utils.ts +25 -0
- package/lib/cjs/Utils.d.ts +21 -0
- package/lib/cjs/Utils.js +84 -0
- package/lib/mjs/Utils.d.ts +21 -0
- package/lib/mjs/Utils.js +84 -0
- package/package.json +1 -1
- package/src/Utils.ts +87 -0
package/README.md
CHANGED
|
@@ -278,6 +278,7 @@ String and other related utilities
|
|
|
278
278
|
|formatInitial|Format inital character to lower case or upper case|
|
|
279
279
|
|formatString|Format string with parameters|
|
|
280
280
|
|getDataChanges|Get data changed fields with input data updated|
|
|
281
|
+
|getNestedValue|Get nested value from object|
|
|
281
282
|
|getTimeZone|Get time zone|
|
|
282
283
|
|hideData|Hide data|
|
|
283
284
|
|hideEmail|Hide email data|
|
|
@@ -291,11 +292,13 @@ String and other related utilities
|
|
|
291
292
|
|objectEqual|Test two objects are equal or not|
|
|
292
293
|
|objectKeys|Get two object's unqiue properties|
|
|
293
294
|
|objectUpdated|Get the new object's updated fields contrast to the previous object|
|
|
295
|
+
|parseJsonArray|Try to parse JSON input to array|
|
|
294
296
|
|parsePath|Parse path similar with node.js path.parse|
|
|
295
297
|
|parseString|Parse string (JSON) to specific type|
|
|
296
298
|
|removeNonLetters|Remove non letters (0-9, a-z, A-Z)|
|
|
297
299
|
|replaceNullOrEmpty|Replace null or empty with default value|
|
|
298
300
|
|setLabels|Set source with new labels|
|
|
301
|
+
|setNestedValue|Set nested value to object|
|
|
299
302
|
|snakeNameToWord|Snake name to works, 'snake_name' to 'Snake Name'|
|
|
300
303
|
|sortByFavor|Sort array by favored values|
|
|
301
304
|
|sortByFieldFavor|Sort array by favored field values|
|
package/__tests__/Utils.ts
CHANGED
|
@@ -188,6 +188,12 @@ test('Tests for objectEqual', () => {
|
|
|
188
188
|
expect(Utils.objectEqual(obj1, obj2, ['a'], 2)).toBeFalsy();
|
|
189
189
|
});
|
|
190
190
|
|
|
191
|
+
test('Tests for parseJsonArray', () => {
|
|
192
|
+
expect(Utils.parseJsonArray('[1, 3, "a"]', 0)).toBeUndefined();
|
|
193
|
+
expect(Utils.parseJsonArray('[1, 3, "a"]')).not.toBeUndefined();
|
|
194
|
+
expect(Utils.parseJsonArray('1, 3, 9')).not.toBeUndefined();
|
|
195
|
+
});
|
|
196
|
+
|
|
191
197
|
test('Tests for objectUpdated', () => {
|
|
192
198
|
const objPrev = { a: 1, b: 'abc', c: true, d: null, f: [1, 2] };
|
|
193
199
|
const objNew = { a: 2, b: 'abc', d: new Date(), f: [1, 2, 3], g: true };
|
|
@@ -230,6 +236,15 @@ test('Tests for mergeClasses', () => {
|
|
|
230
236
|
expect(Utils.mergeClasses('a', '', 'b ', undefined, 'c')).toBe('a b c');
|
|
231
237
|
});
|
|
232
238
|
|
|
239
|
+
test('Tests for getNestedValue', () => {
|
|
240
|
+
const obj = { jsonData: { photoSize: [200, 100], supportResizing: true } };
|
|
241
|
+
expect(Utils.getNestedValue(obj, 'jsonData.supportResizing')).toBeTruthy();
|
|
242
|
+
expect(
|
|
243
|
+
Array.isArray(Utils.getNestedValue(obj, 'jsonData.photoSize'))
|
|
244
|
+
).toBeTruthy();
|
|
245
|
+
expect(Utils.getNestedValue(obj, 'jsonData.unknown')).toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
|
|
233
248
|
test('Tests for getResult', () => {
|
|
234
249
|
// Arrange
|
|
235
250
|
type test = ((visible: boolean) => number) | number;
|
|
@@ -281,6 +296,16 @@ test('Tests for parsePath, Windows path', () => {
|
|
|
281
296
|
expect(result.name).toBe('file');
|
|
282
297
|
});
|
|
283
298
|
|
|
299
|
+
test('Tests for setNestedValue', () => {
|
|
300
|
+
const obj = { jsonData: { photoSize: [200, 100], supportResizing: true } };
|
|
301
|
+
|
|
302
|
+
Utils.setNestedValue(obj, 'jsonData.supportResizing', false);
|
|
303
|
+
expect(obj.jsonData.supportResizing).toBeFalsy();
|
|
304
|
+
|
|
305
|
+
Utils.setNestedValue(obj, 'jsonData.newProperty.value', 125);
|
|
306
|
+
expect(Reflect.get((obj.jsonData as any).newProperty, 'value')).toBe(125);
|
|
307
|
+
});
|
|
308
|
+
|
|
284
309
|
test('Tests for sortByFavor', () => {
|
|
285
310
|
const items = [1, 2, 3, 4, 5, 6, 7];
|
|
286
311
|
expect(Utils.sortByFavor(items, [5, 1, 3])).toStrictEqual([
|
package/lib/cjs/Utils.d.ts
CHANGED
|
@@ -135,6 +135,13 @@ export declare namespace Utils {
|
|
|
135
135
|
* @returns
|
|
136
136
|
*/
|
|
137
137
|
function getDataChanges(input: object, initData: object, ignoreFields?: string[]): string[];
|
|
138
|
+
/**
|
|
139
|
+
* Get nested value from object
|
|
140
|
+
* @param data Data
|
|
141
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
142
|
+
* @returns Result
|
|
143
|
+
*/
|
|
144
|
+
function getNestedValue(data: object, name: string): any;
|
|
138
145
|
/**
|
|
139
146
|
* Get input function or value result
|
|
140
147
|
* @param input Input function or value
|
|
@@ -207,6 +214,13 @@ export declare namespace Utils {
|
|
|
207
214
|
* @returns Updated fields
|
|
208
215
|
*/
|
|
209
216
|
function objectUpdated(objNew: object, objPrev: object, ignoreFields?: string[], strict?: number): string[];
|
|
217
|
+
/**
|
|
218
|
+
* Try to parse JSON input to array
|
|
219
|
+
* @param input JSON input
|
|
220
|
+
* @param checkValue Type check value
|
|
221
|
+
* @returns Result
|
|
222
|
+
*/
|
|
223
|
+
function parseJsonArray<T>(input: string, checkValue?: T): T[] | undefined;
|
|
210
224
|
/**
|
|
211
225
|
* Parse string (JSON) to specific type, no type conversion
|
|
212
226
|
* For type conversion, please use DataTypes.convert
|
|
@@ -248,6 +262,13 @@ export declare namespace Utils {
|
|
|
248
262
|
* @param firstOnly Only convert the first word to upper case
|
|
249
263
|
*/
|
|
250
264
|
const snakeNameToWord: (name: string, firstOnly?: boolean) => string;
|
|
265
|
+
/**
|
|
266
|
+
* Set nested value to object
|
|
267
|
+
* @param data Data
|
|
268
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
269
|
+
* @param value Value
|
|
270
|
+
*/
|
|
271
|
+
function setNestedValue(data: object, name: string, value: unknown): void;
|
|
251
272
|
/**
|
|
252
273
|
* Parse path similar with node.js path.parse
|
|
253
274
|
* @param path Input path
|
package/lib/cjs/Utils.js
CHANGED
|
@@ -239,6 +239,36 @@ var Utils;
|
|
|
239
239
|
return changes;
|
|
240
240
|
}
|
|
241
241
|
Utils.getDataChanges = getDataChanges;
|
|
242
|
+
/**
|
|
243
|
+
* Get nested value from object
|
|
244
|
+
* @param data Data
|
|
245
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
246
|
+
* @returns Result
|
|
247
|
+
*/
|
|
248
|
+
function getNestedValue(data, name) {
|
|
249
|
+
const properties = name.split('.');
|
|
250
|
+
const len = properties.length;
|
|
251
|
+
if (len === 1) {
|
|
252
|
+
return Reflect.get(data, name);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
let curr = data;
|
|
256
|
+
for (let i = 0; i < len; i++) {
|
|
257
|
+
const property = properties[i];
|
|
258
|
+
if (i + 1 === len) {
|
|
259
|
+
return Reflect.get(curr, property);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
let p = Reflect.get(curr, property);
|
|
263
|
+
if (p == null) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
curr = p;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
Utils.getNestedValue = getNestedValue;
|
|
242
272
|
/**
|
|
243
273
|
* Get input function or value result
|
|
244
274
|
* @param input Input function or value
|
|
@@ -389,6 +419,30 @@ var Utils;
|
|
|
389
419
|
return fields;
|
|
390
420
|
}
|
|
391
421
|
Utils.objectUpdated = objectUpdated;
|
|
422
|
+
/**
|
|
423
|
+
* Try to parse JSON input to array
|
|
424
|
+
* @param input JSON input
|
|
425
|
+
* @param checkValue Type check value
|
|
426
|
+
* @returns Result
|
|
427
|
+
*/
|
|
428
|
+
function parseJsonArray(input, checkValue) {
|
|
429
|
+
try {
|
|
430
|
+
if (!input.startsWith('['))
|
|
431
|
+
input = `[${input}]`;
|
|
432
|
+
const array = JSON.parse(input);
|
|
433
|
+
const type = typeof checkValue;
|
|
434
|
+
if (Array.isArray(array) &&
|
|
435
|
+
(checkValue == null ||
|
|
436
|
+
!array.some((item) => typeof item !== type))) {
|
|
437
|
+
return array;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch (e) {
|
|
441
|
+
console.log('parseJsonArray', input, e);
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
Utils.parseJsonArray = parseJsonArray;
|
|
392
446
|
/**
|
|
393
447
|
* Parse string (JSON) to specific type, no type conversion
|
|
394
448
|
* When return type depends on parameter value, uses function overloading, otherwise uses conditional type
|
|
@@ -484,6 +538,36 @@ var Utils;
|
|
|
484
538
|
return -1;
|
|
485
539
|
return n1 - n2;
|
|
486
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Set nested value to object
|
|
543
|
+
* @param data Data
|
|
544
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
545
|
+
* @param value Value
|
|
546
|
+
*/
|
|
547
|
+
function setNestedValue(data, name, value) {
|
|
548
|
+
const properties = name.split('.');
|
|
549
|
+
const len = properties.length;
|
|
550
|
+
if (len === 1)
|
|
551
|
+
Reflect.set(data, name, value);
|
|
552
|
+
else {
|
|
553
|
+
let curr = data;
|
|
554
|
+
for (let i = 0; i < len; i++) {
|
|
555
|
+
const property = properties[i];
|
|
556
|
+
if (i + 1 === len) {
|
|
557
|
+
Reflect.set(curr, property, value);
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
let p = Reflect.get(curr, property);
|
|
561
|
+
if (p == null) {
|
|
562
|
+
p = {};
|
|
563
|
+
Reflect.set(curr, property, p);
|
|
564
|
+
}
|
|
565
|
+
curr = p;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
Utils.setNestedValue = setNestedValue;
|
|
487
571
|
/**
|
|
488
572
|
* Parse path similar with node.js path.parse
|
|
489
573
|
* @param path Input path
|
package/lib/mjs/Utils.d.ts
CHANGED
|
@@ -135,6 +135,13 @@ export declare namespace Utils {
|
|
|
135
135
|
* @returns
|
|
136
136
|
*/
|
|
137
137
|
function getDataChanges(input: object, initData: object, ignoreFields?: string[]): string[];
|
|
138
|
+
/**
|
|
139
|
+
* Get nested value from object
|
|
140
|
+
* @param data Data
|
|
141
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
142
|
+
* @returns Result
|
|
143
|
+
*/
|
|
144
|
+
function getNestedValue(data: object, name: string): any;
|
|
138
145
|
/**
|
|
139
146
|
* Get input function or value result
|
|
140
147
|
* @param input Input function or value
|
|
@@ -207,6 +214,13 @@ export declare namespace Utils {
|
|
|
207
214
|
* @returns Updated fields
|
|
208
215
|
*/
|
|
209
216
|
function objectUpdated(objNew: object, objPrev: object, ignoreFields?: string[], strict?: number): string[];
|
|
217
|
+
/**
|
|
218
|
+
* Try to parse JSON input to array
|
|
219
|
+
* @param input JSON input
|
|
220
|
+
* @param checkValue Type check value
|
|
221
|
+
* @returns Result
|
|
222
|
+
*/
|
|
223
|
+
function parseJsonArray<T>(input: string, checkValue?: T): T[] | undefined;
|
|
210
224
|
/**
|
|
211
225
|
* Parse string (JSON) to specific type, no type conversion
|
|
212
226
|
* For type conversion, please use DataTypes.convert
|
|
@@ -248,6 +262,13 @@ export declare namespace Utils {
|
|
|
248
262
|
* @param firstOnly Only convert the first word to upper case
|
|
249
263
|
*/
|
|
250
264
|
const snakeNameToWord: (name: string, firstOnly?: boolean) => string;
|
|
265
|
+
/**
|
|
266
|
+
* Set nested value to object
|
|
267
|
+
* @param data Data
|
|
268
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
269
|
+
* @param value Value
|
|
270
|
+
*/
|
|
271
|
+
function setNestedValue(data: object, name: string, value: unknown): void;
|
|
251
272
|
/**
|
|
252
273
|
* Parse path similar with node.js path.parse
|
|
253
274
|
* @param path Input path
|
package/lib/mjs/Utils.js
CHANGED
|
@@ -233,6 +233,36 @@ export var Utils;
|
|
|
233
233
|
return changes;
|
|
234
234
|
}
|
|
235
235
|
Utils.getDataChanges = getDataChanges;
|
|
236
|
+
/**
|
|
237
|
+
* Get nested value from object
|
|
238
|
+
* @param data Data
|
|
239
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
240
|
+
* @returns Result
|
|
241
|
+
*/
|
|
242
|
+
function getNestedValue(data, name) {
|
|
243
|
+
const properties = name.split('.');
|
|
244
|
+
const len = properties.length;
|
|
245
|
+
if (len === 1) {
|
|
246
|
+
return Reflect.get(data, name);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
let curr = data;
|
|
250
|
+
for (let i = 0; i < len; i++) {
|
|
251
|
+
const property = properties[i];
|
|
252
|
+
if (i + 1 === len) {
|
|
253
|
+
return Reflect.get(curr, property);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
let p = Reflect.get(curr, property);
|
|
257
|
+
if (p == null) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
curr = p;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
Utils.getNestedValue = getNestedValue;
|
|
236
266
|
/**
|
|
237
267
|
* Get input function or value result
|
|
238
268
|
* @param input Input function or value
|
|
@@ -383,6 +413,30 @@ export var Utils;
|
|
|
383
413
|
return fields;
|
|
384
414
|
}
|
|
385
415
|
Utils.objectUpdated = objectUpdated;
|
|
416
|
+
/**
|
|
417
|
+
* Try to parse JSON input to array
|
|
418
|
+
* @param input JSON input
|
|
419
|
+
* @param checkValue Type check value
|
|
420
|
+
* @returns Result
|
|
421
|
+
*/
|
|
422
|
+
function parseJsonArray(input, checkValue) {
|
|
423
|
+
try {
|
|
424
|
+
if (!input.startsWith('['))
|
|
425
|
+
input = `[${input}]`;
|
|
426
|
+
const array = JSON.parse(input);
|
|
427
|
+
const type = typeof checkValue;
|
|
428
|
+
if (Array.isArray(array) &&
|
|
429
|
+
(checkValue == null ||
|
|
430
|
+
!array.some((item) => typeof item !== type))) {
|
|
431
|
+
return array;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch (e) {
|
|
435
|
+
console.log('parseJsonArray', input, e);
|
|
436
|
+
}
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
Utils.parseJsonArray = parseJsonArray;
|
|
386
440
|
/**
|
|
387
441
|
* Parse string (JSON) to specific type, no type conversion
|
|
388
442
|
* When return type depends on parameter value, uses function overloading, otherwise uses conditional type
|
|
@@ -478,6 +532,36 @@ export var Utils;
|
|
|
478
532
|
return -1;
|
|
479
533
|
return n1 - n2;
|
|
480
534
|
}
|
|
535
|
+
/**
|
|
536
|
+
* Set nested value to object
|
|
537
|
+
* @param data Data
|
|
538
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
539
|
+
* @param value Value
|
|
540
|
+
*/
|
|
541
|
+
function setNestedValue(data, name, value) {
|
|
542
|
+
const properties = name.split('.');
|
|
543
|
+
const len = properties.length;
|
|
544
|
+
if (len === 1)
|
|
545
|
+
Reflect.set(data, name, value);
|
|
546
|
+
else {
|
|
547
|
+
let curr = data;
|
|
548
|
+
for (let i = 0; i < len; i++) {
|
|
549
|
+
const property = properties[i];
|
|
550
|
+
if (i + 1 === len) {
|
|
551
|
+
Reflect.set(curr, property, value);
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
let p = Reflect.get(curr, property);
|
|
555
|
+
if (p == null) {
|
|
556
|
+
p = {};
|
|
557
|
+
Reflect.set(curr, property, p);
|
|
558
|
+
}
|
|
559
|
+
curr = p;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
Utils.setNestedValue = setNestedValue;
|
|
481
565
|
/**
|
|
482
566
|
* Parse path similar with node.js path.parse
|
|
483
567
|
* @param path Input path
|
package/package.json
CHANGED
package/src/Utils.ts
CHANGED
|
@@ -352,6 +352,36 @@ export namespace Utils {
|
|
|
352
352
|
return changes;
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
+
/**
|
|
356
|
+
* Get nested value from object
|
|
357
|
+
* @param data Data
|
|
358
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
359
|
+
* @returns Result
|
|
360
|
+
*/
|
|
361
|
+
export function getNestedValue(data: object, name: string) {
|
|
362
|
+
const properties = name.split('.');
|
|
363
|
+
const len = properties.length;
|
|
364
|
+
if (len === 1) {
|
|
365
|
+
return Reflect.get(data, name);
|
|
366
|
+
} else {
|
|
367
|
+
let curr = data;
|
|
368
|
+
for (let i = 0; i < len; i++) {
|
|
369
|
+
const property = properties[i];
|
|
370
|
+
|
|
371
|
+
if (i + 1 === len) {
|
|
372
|
+
return Reflect.get(curr, property);
|
|
373
|
+
} else {
|
|
374
|
+
let p = Reflect.get(curr, property);
|
|
375
|
+
if (p == null) {
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
curr = p;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
355
385
|
/**
|
|
356
386
|
* Get input function or value result
|
|
357
387
|
* @param input Input function or value
|
|
@@ -541,6 +571,33 @@ export namespace Utils {
|
|
|
541
571
|
return fields;
|
|
542
572
|
}
|
|
543
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Try to parse JSON input to array
|
|
576
|
+
* @param input JSON input
|
|
577
|
+
* @param checkValue Type check value
|
|
578
|
+
* @returns Result
|
|
579
|
+
*/
|
|
580
|
+
export function parseJsonArray<T>(
|
|
581
|
+
input: string,
|
|
582
|
+
checkValue?: T
|
|
583
|
+
): T[] | undefined {
|
|
584
|
+
try {
|
|
585
|
+
if (!input.startsWith('[')) input = `[${input}]`;
|
|
586
|
+
const array = JSON.parse(input);
|
|
587
|
+
const type = typeof checkValue;
|
|
588
|
+
if (
|
|
589
|
+
Array.isArray(array) &&
|
|
590
|
+
(checkValue == null ||
|
|
591
|
+
!array.some((item) => typeof item !== type))
|
|
592
|
+
) {
|
|
593
|
+
return array;
|
|
594
|
+
}
|
|
595
|
+
} catch (e) {
|
|
596
|
+
console.log('parseJsonArray', input, e);
|
|
597
|
+
}
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
544
601
|
/**
|
|
545
602
|
* Parse string (JSON) to specific type, no type conversion
|
|
546
603
|
* For type conversion, please use DataTypes.convert
|
|
@@ -673,6 +730,36 @@ export namespace Utils {
|
|
|
673
730
|
return n1 - n2;
|
|
674
731
|
}
|
|
675
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Set nested value to object
|
|
735
|
+
* @param data Data
|
|
736
|
+
* @param name Field name, support property chain like 'jsonData.logSize'
|
|
737
|
+
* @param value Value
|
|
738
|
+
*/
|
|
739
|
+
export function setNestedValue(data: object, name: string, value: unknown) {
|
|
740
|
+
const properties = name.split('.');
|
|
741
|
+
const len = properties.length;
|
|
742
|
+
if (len === 1) Reflect.set(data, name, value);
|
|
743
|
+
else {
|
|
744
|
+
let curr = data;
|
|
745
|
+
for (let i = 0; i < len; i++) {
|
|
746
|
+
const property = properties[i];
|
|
747
|
+
|
|
748
|
+
if (i + 1 === len) {
|
|
749
|
+
Reflect.set(curr, property, value);
|
|
750
|
+
} else {
|
|
751
|
+
let p = Reflect.get(curr, property);
|
|
752
|
+
if (p == null) {
|
|
753
|
+
p = {};
|
|
754
|
+
Reflect.set(curr, property, p);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
curr = p;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
676
763
|
/**
|
|
677
764
|
* Parse path similar with node.js path.parse
|
|
678
765
|
* @param path Input path
|