lupine.api 1.1.58 → 1.1.60
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 -3
- package/admin/admin-about.tsx +12 -16
- package/admin/admin-config.tsx +47 -44
- package/admin/admin-css.tsx +3 -3
- package/admin/admin-db.tsx +75 -75
- package/admin/admin-frame-helper.tsx +364 -364
- package/admin/admin-frame.tsx +164 -164
- package/admin/admin-index.tsx +65 -65
- package/admin/admin-login.tsx +111 -111
- package/admin/admin-menu-edit.tsx +637 -637
- package/admin/admin-menu-list.tsx +87 -87
- package/admin/admin-page-edit.tsx +564 -564
- package/admin/admin-page-list.tsx +83 -83
- package/admin/admin-performance.tsx +28 -28
- package/admin/admin-release.tsx +427 -426
- package/admin/admin-resources.tsx +382 -382
- package/admin/admin-shell.tsx +89 -89
- package/admin/admin-table-data.tsx +146 -146
- package/admin/admin-table-list.tsx +230 -230
- package/admin/admin-test-animations.tsx +395 -395
- package/admin/admin-test-component.tsx +823 -808
- package/admin/admin-test-edit.tsx +319 -319
- package/admin/admin-test-themes.tsx +56 -56
- package/admin/admin-tokens.tsx +338 -338
- package/admin/design/admin-design.tsx +174 -174
- package/admin/design/block-grid.tsx +36 -36
- package/admin/design/block-grid1.tsx +21 -21
- package/admin/design/block-paragraph.tsx +19 -19
- package/admin/design/block-title.tsx +19 -19
- package/admin/design/design-block-box.tsx +140 -140
- package/admin/design/drag-data.tsx +24 -24
- package/admin/index.ts +9 -9
- package/admin/package.json +15 -15
- package/admin/tsconfig.json +127 -127
- package/dev/copy-folder.js +32 -32
- package/dev/cp-index-html.js +69 -69
- package/dev/file-utils.js +12 -12
- package/dev/index.js +18 -19
- package/dev/package.json +12 -12
- package/dev/plugin-ifelse.js +168 -168
- package/dev/plugin-ifelse.test.js +37 -37
- package/dev/run-cmd.js +14 -14
- package/dev/send-request.js +12 -12
- package/package.json +55 -55
- package/src/admin-api/admin-api-helper.ts +210 -205
- package/src/admin-api/admin-api.ts +65 -65
- package/src/admin-api/admin-auth.ts +152 -146
- package/src/admin-api/admin-config.ts +94 -84
- package/src/admin-api/admin-csv.ts +94 -94
- package/src/admin-api/admin-db.ts +269 -269
- package/src/admin-api/admin-menu.ts +135 -135
- package/src/admin-api/admin-page.ts +135 -135
- package/src/admin-api/admin-performance.ts +128 -128
- package/src/admin-api/admin-release.ts +706 -700
- package/src/admin-api/admin-resources.ts +318 -318
- package/src/admin-api/admin-token-helper.ts +82 -79
- package/src/admin-api/admin-tokens.ts +90 -90
- package/src/admin-api/index.ts +2 -2
- package/src/admin-api/web-config-api.ts +19 -19
- package/src/api/api-cache.ts +103 -103
- package/src/api/api-helper.ts +44 -44
- package/src/api/api-module.ts +67 -60
- package/src/api/api-router.ts +177 -177
- package/src/api/api-shared-storage.ts +64 -64
- package/src/api/async-storage.ts +5 -5
- package/src/api/debug-service.ts +56 -56
- package/src/api/encode-html.ts +27 -27
- package/src/api/handle-status.ts +75 -75
- package/src/api/index.ts +15 -16
- package/src/api/mini-web-socket.ts +270 -270
- package/src/api/server-content-type.ts +82 -82
- package/src/api/server-render.ts +235 -215
- package/src/api/shell-service.ts +74 -74
- package/src/api/simple-storage.ts +80 -80
- package/src/api/static-server.ts +128 -125
- package/src/api/to-client-delivery.ts +26 -26
- package/src/app/app-cache.ts +55 -55
- package/src/app/app-helper.ts +62 -62
- package/src/app/app-message.ts +109 -109
- package/src/app/app-shared-storage.ts +363 -363
- package/src/app/app-start.ts +136 -136
- package/src/app/cleanup-exit.ts +16 -16
- package/src/app/host-to-path.ts +38 -38
- package/src/app/index.ts +11 -11
- package/src/app/process-dev-requests.ts +130 -130
- package/src/app/web-listener.ts +294 -294
- package/src/app/web-processor.ts +47 -42
- package/src/app/web-server.ts +100 -100
- package/src/common-js/web-env.js +104 -104
- package/src/index.ts +7 -7
- package/src/lang/api-lang-en.ts +26 -26
- package/src/lang/api-lang-zh-cn.ts +27 -27
- package/src/lang/index.ts +2 -2
- package/src/lang/lang-helper.ts +76 -76
- package/src/lang/lang-props.ts +6 -6
- package/src/lib/db/db-helper.ts +23 -23
- package/src/lib/db/db-mysql.ts +249 -250
- package/src/lib/db/db-sqlite.ts +101 -101
- package/src/lib/db/db.spec.ts +28 -28
- package/src/lib/db/db.ts +325 -325
- package/src/lib/db/index.ts +5 -5
- package/src/lib/index.ts +3 -3
- package/src/lib/logger.spec.ts +214 -214
- package/src/lib/logger.ts +281 -281
- package/src/lib/runtime-require.ts +37 -37
- package/src/lib/utils/cookie-util.ts +34 -34
- package/src/lib/utils/crypto.ts +58 -58
- package/src/lib/utils/date-utils.ts +317 -317
- package/src/lib/utils/deep-merge.ts +37 -37
- package/src/lib/utils/delay.ts +12 -12
- package/src/lib/utils/file-setting.ts +55 -55
- package/src/lib/utils/format-bytes.ts +11 -11
- package/src/lib/utils/fs-utils.ts +158 -158
- package/src/lib/utils/get-env.ts +27 -27
- package/src/lib/utils/index.ts +12 -12
- package/src/lib/utils/is-type.ts +48 -48
- package/src/lib/utils/load-env.ts +14 -14
- package/src/lib/utils/pad.ts +6 -6
- package/src/models/api-base.ts +5 -5
- package/src/models/api-module-props.ts +10 -11
- package/src/models/api-router-props.ts +26 -26
- package/src/models/app-cache-props.ts +33 -33
- package/src/models/app-data-props.ts +10 -10
- package/src/models/app-helper-props.ts +6 -6
- package/src/models/app-shared-storage-props.ts +38 -38
- package/src/models/app-start-props.ts +18 -18
- package/src/models/async-storage-props.ts +13 -13
- package/src/models/db-config.ts +30 -30
- package/src/models/host-to-path-props.ts +12 -12
- package/src/models/index.ts +16 -16
- package/src/models/json-object.ts +8 -8
- package/src/models/locals-props.ts +36 -36
- package/src/models/logger-props.ts +84 -84
- package/src/models/simple-storage-props.ts +13 -14
- package/src/models/to-client-delivery-props.ts +6 -6
- package/tsconfig.json +115 -115
- package/dev/plugin-gen-versions.js +0 -20
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple object check.
|
|
3
|
-
* @param item
|
|
4
|
-
* @returns {boolean}
|
|
5
|
-
*/
|
|
6
|
-
const needMerge = (item: any) => {
|
|
7
|
-
return item && typeof item === 'object' && !Array.isArray(item);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Deep merge two objects.
|
|
12
|
-
* target must be a object, and array will be replaced
|
|
13
|
-
* @param target
|
|
14
|
-
* @param ...sources
|
|
15
|
-
*/
|
|
16
|
-
export const deepMerge = (target: any, ...sources: any[]): any => {
|
|
17
|
-
if (!sources.length) return target;
|
|
18
|
-
const source = sources.shift();
|
|
19
|
-
|
|
20
|
-
if (needMerge(target) && needMerge(source)) {
|
|
21
|
-
for (const key in source) {
|
|
22
|
-
if (needMerge(source[key])) {
|
|
23
|
-
if (!target[key]) Object.assign(target, { [key]: {} });
|
|
24
|
-
deepMerge(target[key], source[key]);
|
|
25
|
-
} else {
|
|
26
|
-
Object.assign(target, { [key]: source[key] });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return deepMerge(target, ...sources);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// Clone data object only
|
|
35
|
-
export const cloneJson = (json: any) => {
|
|
36
|
-
return JSON.parse(JSON.stringify(json));
|
|
37
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Simple object check.
|
|
3
|
+
* @param item
|
|
4
|
+
* @returns {boolean}
|
|
5
|
+
*/
|
|
6
|
+
const needMerge = (item: any) => {
|
|
7
|
+
return item && typeof item === 'object' && !Array.isArray(item);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Deep merge two objects.
|
|
12
|
+
* target must be a object, and array will be replaced
|
|
13
|
+
* @param target
|
|
14
|
+
* @param ...sources
|
|
15
|
+
*/
|
|
16
|
+
export const deepMerge = (target: any, ...sources: any[]): any => {
|
|
17
|
+
if (!sources.length) return target;
|
|
18
|
+
const source = sources.shift();
|
|
19
|
+
|
|
20
|
+
if (needMerge(target) && needMerge(source)) {
|
|
21
|
+
for (const key in source) {
|
|
22
|
+
if (needMerge(source[key])) {
|
|
23
|
+
if (!target[key]) Object.assign(target, { [key]: {} });
|
|
24
|
+
deepMerge(target[key], source[key]);
|
|
25
|
+
} else {
|
|
26
|
+
Object.assign(target, { [key]: source[key] });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return deepMerge(target, ...sources);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Clone data object only
|
|
35
|
+
export const cloneJson = (json: any) => {
|
|
36
|
+
return JSON.parse(JSON.stringify(json));
|
|
37
|
+
};
|
package/src/lib/utils/delay.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*
|
|
2
|
-
delay(3000).then(() => alert('runs after 3 seconds'));
|
|
3
|
-
or
|
|
4
|
-
await delay(3000);
|
|
5
|
-
*/
|
|
6
|
-
export const delay = (ms: number) => {
|
|
7
|
-
return new Promise<void>((resolve, reject) => {
|
|
8
|
-
setTimeout(() => {
|
|
9
|
-
resolve();
|
|
10
|
-
}, ms);
|
|
11
|
-
});
|
|
12
|
-
};
|
|
1
|
+
/*
|
|
2
|
+
delay(3000).then(() => alert('runs after 3 seconds'));
|
|
3
|
+
or
|
|
4
|
+
await delay(3000);
|
|
5
|
+
*/
|
|
6
|
+
export const delay = (ms: number) => {
|
|
7
|
+
return new Promise<void>((resolve, reject) => {
|
|
8
|
+
setTimeout(() => {
|
|
9
|
+
resolve();
|
|
10
|
+
}, ms);
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { Logger } from '../logger';
|
|
2
|
-
import { FsUtils } from './fs-utils';
|
|
3
|
-
|
|
4
|
-
const logger = new Logger('setting-file');
|
|
5
|
-
|
|
6
|
-
export type FileSettingProps = {
|
|
7
|
-
[key: string]: string | number | boolean | object;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A simple settings/config class for storing key/value pairs with persistence.
|
|
12
|
-
*/
|
|
13
|
-
export class FileSetting {
|
|
14
|
-
private settings: FileSettingProps = {};
|
|
15
|
-
|
|
16
|
-
constructor() {}
|
|
17
|
-
|
|
18
|
-
async load(path: string) {
|
|
19
|
-
let json;
|
|
20
|
-
if ((json = await FsUtils.readFile(path))) {
|
|
21
|
-
try {
|
|
22
|
-
const jsonObject = JSON.parse(json);
|
|
23
|
-
Object.assign(this.settings, jsonObject);
|
|
24
|
-
} catch (e: any) {
|
|
25
|
-
logger.error('Loading json file failed', e.message);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async save(path: string) {
|
|
31
|
-
await FsUtils.writeFile(path, JSON.stringify(this.settings));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
set(key: string, value: string | number | boolean | object | undefined) {
|
|
35
|
-
if (value === undefined) {
|
|
36
|
-
delete this.settings[key];
|
|
37
|
-
} else {
|
|
38
|
-
this.settings[key] = value;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
setAll(values: FileSettingProps) {
|
|
43
|
-
for (let k in values) {
|
|
44
|
-
this.settings[k] = values[k];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
get(key: string, defaultValue: string | number | boolean | object): string | number | boolean | object {
|
|
49
|
-
return key in this.settings ? this.settings[key] : defaultValue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
get getAll(): FileSettingProps {
|
|
53
|
-
return this.settings;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
1
|
+
import { Logger } from '../logger';
|
|
2
|
+
import { FsUtils } from './fs-utils';
|
|
3
|
+
|
|
4
|
+
const logger = new Logger('setting-file');
|
|
5
|
+
|
|
6
|
+
export type FileSettingProps = {
|
|
7
|
+
[key: string]: string | number | boolean | object;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A simple settings/config class for storing key/value pairs with persistence.
|
|
12
|
+
*/
|
|
13
|
+
export class FileSetting {
|
|
14
|
+
private settings: FileSettingProps = {};
|
|
15
|
+
|
|
16
|
+
constructor() {}
|
|
17
|
+
|
|
18
|
+
async load(path: string) {
|
|
19
|
+
let json;
|
|
20
|
+
if ((json = await FsUtils.readFile(path))) {
|
|
21
|
+
try {
|
|
22
|
+
const jsonObject = JSON.parse(json);
|
|
23
|
+
Object.assign(this.settings, jsonObject);
|
|
24
|
+
} catch (e: any) {
|
|
25
|
+
logger.error('Loading json file failed', e.message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async save(path: string) {
|
|
31
|
+
await FsUtils.writeFile(path, JSON.stringify(this.settings));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
set(key: string, value: string | number | boolean | object | undefined) {
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
delete this.settings[key];
|
|
37
|
+
} else {
|
|
38
|
+
this.settings[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setAll(values: FileSettingProps) {
|
|
43
|
+
for (let k in values) {
|
|
44
|
+
this.settings[k] = values[k];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get(key: string, defaultValue: string | number | boolean | object): string | number | boolean | object {
|
|
49
|
+
return key in this.settings ? this.settings[key] : defaultValue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get getAll(): FileSettingProps {
|
|
53
|
+
return this.settings;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export const formatBytes = (bytes: number, decimals = 2) => {
|
|
2
|
-
if (!+bytes) return '0 Bytes';
|
|
3
|
-
|
|
4
|
-
const k = 1024;
|
|
5
|
-
const dm = decimals < 0 ? 0 : decimals;
|
|
6
|
-
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
7
|
-
|
|
8
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
9
|
-
|
|
10
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
11
|
-
};
|
|
1
|
+
export const formatBytes = (bytes: number, decimals = 2) => {
|
|
2
|
+
if (!+bytes) return '0 Bytes';
|
|
3
|
+
|
|
4
|
+
const k = 1024;
|
|
5
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
6
|
+
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
7
|
+
|
|
8
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
9
|
+
|
|
10
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
11
|
+
};
|
|
@@ -1,158 +1,158 @@
|
|
|
1
|
-
import { Dirent } from 'fs';
|
|
2
|
-
import * as fs from 'fs/promises';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
|
|
5
|
-
export type FileInfoProps = {
|
|
6
|
-
size: number;
|
|
7
|
-
mtime: number;
|
|
8
|
-
isFile: boolean;
|
|
9
|
-
isDir: boolean;
|
|
10
|
-
};
|
|
11
|
-
export class FsUtils {
|
|
12
|
-
static readFile = async (filePath: string): Promise<string | undefined> => {
|
|
13
|
-
try {
|
|
14
|
-
const text = await fs.readFile(filePath, 'utf-8');
|
|
15
|
-
return text;
|
|
16
|
-
} catch (e) {
|
|
17
|
-
console.log('writeFile failed', e);
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
static fileInfo = async (filePath: string): Promise<FileInfoProps | undefined> => {
|
|
23
|
-
try {
|
|
24
|
-
const stats = await fs.stat(filePath);
|
|
25
|
-
return { size: stats.size, mtime: stats.mtime.getTime(), isFile: stats.isFile(), isDir: stats.isDirectory() };
|
|
26
|
-
} catch {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
static writeFile = async (
|
|
32
|
-
filePath: string,
|
|
33
|
-
content:
|
|
34
|
-
| string
|
|
35
|
-
| NodeJS.ArrayBufferView
|
|
36
|
-
| Iterable<string | NodeJS.ArrayBufferView>
|
|
37
|
-
| AsyncIterable<string | NodeJS.ArrayBufferView>
|
|
38
|
-
): Promise<boolean> => {
|
|
39
|
-
try {
|
|
40
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
41
|
-
return true;
|
|
42
|
-
} catch (e) {
|
|
43
|
-
console.log('writeFile failed', e);
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
static appendFile = async (filePath: string, content: string | Uint8Array): Promise<boolean> => {
|
|
49
|
-
try {
|
|
50
|
-
await fs.appendFile(filePath, content, 'utf-8');
|
|
51
|
-
return true;
|
|
52
|
-
} catch (e) {
|
|
53
|
-
console.log('appendFile failed', e);
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
static pathExist = async (filePath: string) => {
|
|
59
|
-
try {
|
|
60
|
-
await fs.access(filePath);
|
|
61
|
-
return true;
|
|
62
|
-
} catch {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
static mkdir = async (dirPath: string) => {
|
|
68
|
-
try {
|
|
69
|
-
await fs.mkdir(dirPath, { recursive: true });
|
|
70
|
-
return true;
|
|
71
|
-
} catch {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
static unlinkFile = async (filePath: string) => {
|
|
77
|
-
try {
|
|
78
|
-
await fs.unlink(filePath);
|
|
79
|
-
return true;
|
|
80
|
-
} catch {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
static unlinkFolderEmpty = async (filePath: string) => {
|
|
86
|
-
try {
|
|
87
|
-
await fs.rmdir(filePath);
|
|
88
|
-
return true;
|
|
89
|
-
} catch {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
static unlinkFolderForce = async (filePath: string, recursive: boolean, force: boolean) => {
|
|
95
|
-
try {
|
|
96
|
-
await fs.rm(filePath, { recursive: recursive, force: force });
|
|
97
|
-
return true;
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
static rename = async (filePath: string, newPath: string) => {
|
|
104
|
-
try {
|
|
105
|
-
await fs.rename(filePath, newPath);
|
|
106
|
-
return true;
|
|
107
|
-
} catch {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
static getDirAndFiles = async (dirPath: string): Promise<string[]> => {
|
|
113
|
-
try {
|
|
114
|
-
const files = await fs.readdir(dirPath, { recursive: false });
|
|
115
|
-
return files;
|
|
116
|
-
} catch {
|
|
117
|
-
return [];
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
// return with fullpath list of Dirent
|
|
122
|
-
static
|
|
123
|
-
return this.
|
|
124
|
-
};
|
|
125
|
-
private static
|
|
126
|
-
try {
|
|
127
|
-
const ret = [];
|
|
128
|
-
const files = await fs.readdir(dirPath, {
|
|
129
|
-
recursive: false,
|
|
130
|
-
withFileTypes: true,
|
|
131
|
-
});
|
|
132
|
-
ret.push(...files);
|
|
133
|
-
if (depth + 1 < maxDepth) {
|
|
134
|
-
for (const entry of files) {
|
|
135
|
-
if (entry.isDirectory()) {
|
|
136
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
137
|
-
ret.push(...(await this.
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return ret;
|
|
142
|
-
} catch {
|
|
143
|
-
return [];
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
static async readPartOfFile(path: string, start: number, length: number) {
|
|
148
|
-
try {
|
|
149
|
-
const fileHandle = await fs.open(path, 'r');
|
|
150
|
-
const buffer = Buffer.alloc(length);
|
|
151
|
-
const { bytesRead } = await fileHandle.read(buffer, 0, length, start);
|
|
152
|
-
await fileHandle.close();
|
|
153
|
-
return buffer.slice(0, bytesRead);
|
|
154
|
-
} catch {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
1
|
+
import { Dirent } from 'fs';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
export type FileInfoProps = {
|
|
6
|
+
size: number;
|
|
7
|
+
mtime: number;
|
|
8
|
+
isFile: boolean;
|
|
9
|
+
isDir: boolean;
|
|
10
|
+
};
|
|
11
|
+
export class FsUtils {
|
|
12
|
+
static readFile = async (filePath: string): Promise<string | undefined> => {
|
|
13
|
+
try {
|
|
14
|
+
const text = await fs.readFile(filePath, 'utf-8');
|
|
15
|
+
return text;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.log('writeFile failed', e);
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
static fileInfo = async (filePath: string): Promise<FileInfoProps | undefined> => {
|
|
23
|
+
try {
|
|
24
|
+
const stats = await fs.stat(filePath);
|
|
25
|
+
return { size: stats.size, mtime: stats.mtime.getTime(), isFile: stats.isFile(), isDir: stats.isDirectory() };
|
|
26
|
+
} catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
static writeFile = async (
|
|
32
|
+
filePath: string,
|
|
33
|
+
content:
|
|
34
|
+
| string
|
|
35
|
+
| NodeJS.ArrayBufferView
|
|
36
|
+
| Iterable<string | NodeJS.ArrayBufferView>
|
|
37
|
+
| AsyncIterable<string | NodeJS.ArrayBufferView>
|
|
38
|
+
): Promise<boolean> => {
|
|
39
|
+
try {
|
|
40
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
41
|
+
return true;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.log('writeFile failed', e);
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
static appendFile = async (filePath: string, content: string | Uint8Array): Promise<boolean> => {
|
|
49
|
+
try {
|
|
50
|
+
await fs.appendFile(filePath, content, 'utf-8');
|
|
51
|
+
return true;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.log('appendFile failed', e);
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
static pathExist = async (filePath: string) => {
|
|
59
|
+
try {
|
|
60
|
+
await fs.access(filePath);
|
|
61
|
+
return true;
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
static mkdir = async (dirPath: string) => {
|
|
68
|
+
try {
|
|
69
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
70
|
+
return true;
|
|
71
|
+
} catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
static unlinkFile = async (filePath: string) => {
|
|
77
|
+
try {
|
|
78
|
+
await fs.unlink(filePath);
|
|
79
|
+
return true;
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
static unlinkFolderEmpty = async (filePath: string) => {
|
|
86
|
+
try {
|
|
87
|
+
await fs.rmdir(filePath);
|
|
88
|
+
return true;
|
|
89
|
+
} catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
static unlinkFolderForce = async (filePath: string, recursive: boolean, force: boolean) => {
|
|
95
|
+
try {
|
|
96
|
+
await fs.rm(filePath, { recursive: recursive, force: force });
|
|
97
|
+
return true;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
static rename = async (filePath: string, newPath: string) => {
|
|
104
|
+
try {
|
|
105
|
+
await fs.rename(filePath, newPath);
|
|
106
|
+
return true;
|
|
107
|
+
} catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
static getDirAndFiles = async (dirPath: string): Promise<string[]> => {
|
|
113
|
+
try {
|
|
114
|
+
const files = await fs.readdir(dirPath, { recursive: false });
|
|
115
|
+
return files;
|
|
116
|
+
} catch {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// return with fullpath list of Dirent
|
|
122
|
+
static getDirentFullpath = async (dirPath: string, maxDepth = 1): Promise<Dirent[]> => {
|
|
123
|
+
return this.getDirentFullpathDepthSub(dirPath, 0, maxDepth);
|
|
124
|
+
};
|
|
125
|
+
private static getDirentFullpathDepthSub = async (dirPath: string, depth = 0, maxDepth = 1): Promise<Dirent[]> => {
|
|
126
|
+
try {
|
|
127
|
+
const ret = [];
|
|
128
|
+
const files = await fs.readdir(dirPath, {
|
|
129
|
+
recursive: false,
|
|
130
|
+
withFileTypes: true,
|
|
131
|
+
});
|
|
132
|
+
ret.push(...files);
|
|
133
|
+
if (depth + 1 < maxDepth) {
|
|
134
|
+
for (const entry of files) {
|
|
135
|
+
if (entry.isDirectory()) {
|
|
136
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
137
|
+
ret.push(...(await this.getDirentFullpathDepthSub(fullPath, depth + 1, maxDepth)));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return ret;
|
|
142
|
+
} catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
static async readPartOfFile(path: string, start: number, length: number) {
|
|
148
|
+
try {
|
|
149
|
+
const fileHandle = await fs.open(path, 'r');
|
|
150
|
+
const buffer = Buffer.alloc(length);
|
|
151
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, length, start);
|
|
152
|
+
await fileHandle.close();
|
|
153
|
+
return buffer.slice(0, bytesRead);
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
package/src/lib/utils/get-env.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
function getEnv(key: string, defaultValue: number): number;
|
|
2
|
-
function getEnv(key: string, defaultValue: string): string;
|
|
3
|
-
function getEnv(key: string, defaultValue: boolean): boolean;
|
|
4
|
-
function getEnv(key: string, defaultValue: object): object;
|
|
5
|
-
function getEnv(key: string, defaultValue: any): any {
|
|
6
|
-
if (typeof process.env[key] === 'undefined') {
|
|
7
|
-
return defaultValue;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (typeof defaultValue === 'number') {
|
|
11
|
-
return Number.parseInt(process.env[key]!);
|
|
12
|
-
}
|
|
13
|
-
if (typeof defaultValue === 'boolean') {
|
|
14
|
-
return process.env[key]!.toLocaleLowerCase() === 'true' || process.env[key] === '1';
|
|
15
|
-
}
|
|
16
|
-
if (typeof defaultValue === 'object') {
|
|
17
|
-
try {
|
|
18
|
-
return JSON.parse(process.env[key]!);
|
|
19
|
-
} catch (error) {}
|
|
20
|
-
return defaultValue;
|
|
21
|
-
}
|
|
22
|
-
// if (typeof defaultValue === 'string') {
|
|
23
|
-
// return process.env[key];
|
|
24
|
-
// }
|
|
25
|
-
return process.env[key];
|
|
26
|
-
}
|
|
27
|
-
export { getEnv };
|
|
1
|
+
function getEnv(key: string, defaultValue: number): number;
|
|
2
|
+
function getEnv(key: string, defaultValue: string): string;
|
|
3
|
+
function getEnv(key: string, defaultValue: boolean): boolean;
|
|
4
|
+
function getEnv(key: string, defaultValue: object): object;
|
|
5
|
+
function getEnv(key: string, defaultValue: any): any {
|
|
6
|
+
if (typeof process.env[key] === 'undefined') {
|
|
7
|
+
return defaultValue;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (typeof defaultValue === 'number') {
|
|
11
|
+
return Number.parseInt(process.env[key]!);
|
|
12
|
+
}
|
|
13
|
+
if (typeof defaultValue === 'boolean') {
|
|
14
|
+
return process.env[key]!.toLocaleLowerCase() === 'true' || process.env[key] === '1';
|
|
15
|
+
}
|
|
16
|
+
if (typeof defaultValue === 'object') {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(process.env[key]!);
|
|
19
|
+
} catch (error) {}
|
|
20
|
+
return defaultValue;
|
|
21
|
+
}
|
|
22
|
+
// if (typeof defaultValue === 'string') {
|
|
23
|
+
// return process.env[key];
|
|
24
|
+
// }
|
|
25
|
+
return process.env[key];
|
|
26
|
+
}
|
|
27
|
+
export { getEnv };
|
package/src/lib/utils/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export * from './crypto';
|
|
2
|
-
export * from './date-utils';
|
|
3
|
-
export * from './deep-merge';
|
|
4
|
-
export * from './delay';
|
|
5
|
-
export * from './file-setting';
|
|
6
|
-
export * from './format-bytes';
|
|
7
|
-
export * from './get-env';
|
|
8
|
-
export * from './is-type';
|
|
9
|
-
export * from './load-env';
|
|
10
|
-
export * from './pad';
|
|
11
|
-
export * from './cookie-util';
|
|
12
|
-
export * from './fs-utils';
|
|
1
|
+
export * from './crypto';
|
|
2
|
+
export * from './date-utils';
|
|
3
|
+
export * from './deep-merge';
|
|
4
|
+
export * from './delay';
|
|
5
|
+
export * from './file-setting';
|
|
6
|
+
export * from './format-bytes';
|
|
7
|
+
export * from './get-env';
|
|
8
|
+
export * from './is-type';
|
|
9
|
+
export * from './load-env';
|
|
10
|
+
export * from './pad';
|
|
11
|
+
export * from './cookie-util';
|
|
12
|
+
export * from './fs-utils';
|