milkio 0.1.2 → 0.2.1
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/api-test/index.ts +65 -67
- package/c.ts +37 -37
- package/defines/define-api-test.ts +24 -17
- package/defines/define-api.ts +9 -9
- package/defines/define-command-handler.ts +41 -42
- package/defines/define-http-handler.ts +188 -184
- package/defines/define-middleware.ts +6 -6
- package/defines/define-use.ts +10 -10
- package/index.ts +22 -22
- package/kernel/context.ts +18 -18
- package/kernel/fail.ts +13 -13
- package/kernel/logger.ts +96 -98
- package/kernel/meta.ts +6 -6
- package/kernel/middleware.ts +37 -36
- package/kernel/milkio.ts +250 -225
- package/kernel/runtime.ts +9 -9
- package/kernel/validate.ts +9 -11
- package/package.json +1 -1
- package/scripts/gen-insignificant.ts +239 -241
- package/scripts/gen-significant.ts +118 -122
- package/types.ts +32 -34
- package/utils/create-ulid.ts +3 -3
- package/utils/env-to-boolean.ts +5 -5
- package/utils/env-to-number.ts +2 -2
- package/utils/env-to-string.ts +2 -2
- package/utils/exec.ts +18 -18
- package/utils/handle-catch-error.ts +37 -37
- package/utils/header-to-plain-object.ts +7 -7
- package/utils/remove-dir.ts +19 -19
- package/utils/tson.ts +2 -2
- package/.co.toml +0 -2
|
@@ -1,94 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { $, Glob } from "bun"
|
|
10
|
-
import { MilkioConfig } from ".."
|
|
1
|
+
import ejs from "ejs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
4
|
+
import { cwd, exit } from "node:process";
|
|
5
|
+
import { unlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { camel, hyphen } from "@poech/camel-hump-under";
|
|
7
|
+
import { $, Glob } from "bun";
|
|
8
|
+
import type { MilkioConfig } from "..";
|
|
11
9
|
|
|
12
10
|
export default async () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
11
|
+
// Delete the files generated in the past and regenerate them
|
|
12
|
+
try {
|
|
13
|
+
await unlink(join(cwd(), "generated", "api-schema.ts"));
|
|
14
|
+
} catch (error) {} // Maybe the file does not exist
|
|
15
|
+
|
|
16
|
+
// Make sure that the existing directories are all present
|
|
17
|
+
existsSync(join("generated")) || mkdirSync(join("generated"));
|
|
18
|
+
existsSync(join("generated", "raw")) || mkdirSync(join("generated", "raw"));
|
|
19
|
+
existsSync(join("generated", "raw", "apps")) || mkdirSync(join("generated", "raw", "apps"));
|
|
20
|
+
|
|
21
|
+
if (!existsSync(join("generated", "README.md"))) {
|
|
22
|
+
await writeFile(join("generated", "README.md"), "⚠️ All files in this directory are generated by milkio. Please do not modify the content, otherwise your modifications will be overwritten in the next generation.");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const utils = {
|
|
26
|
+
camel: (str: string) => camel(str).replaceAll("-", "").replaceAll("_", ""),
|
|
27
|
+
hyphen: (str: string) => hyphen(str).replaceAll("_", ""),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Write a basic framework to ensure that there are no errors when reading later
|
|
31
|
+
const apiSchemaSkeleton = `
|
|
34
32
|
export default {
|
|
35
33
|
apiValidator: {},
|
|
36
34
|
apiMethodsSchema: {},
|
|
37
35
|
apiMethodsTypeSchema: {},
|
|
38
36
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
importPath = importPath + "src/apps"
|
|
91
|
-
const template = `
|
|
37
|
+
`;
|
|
38
|
+
await writeFile(join(cwd(), "generated", "api-schema.ts"), ejs.render(apiSchemaSkeleton, { utils }));
|
|
39
|
+
|
|
40
|
+
// Generate api-schema.ts file through templates
|
|
41
|
+
const templateVars = {
|
|
42
|
+
utils,
|
|
43
|
+
apiPaths: [] as Array<string>,
|
|
44
|
+
apiTestPaths: [] as Array<string>,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const glob = new Glob("**/*.ts");
|
|
48
|
+
const appFiles = await Array.fromAsync(glob.scan({ cwd: join(cwd(), "src", "apps") }));
|
|
49
|
+
|
|
50
|
+
console.time(`File Stage`);
|
|
51
|
+
|
|
52
|
+
for (const path of appFiles) {
|
|
53
|
+
if (!path.endsWith(".ts")) continue;
|
|
54
|
+
const module = await import(/* @vite-ignore */ join(cwd(), "src", "apps", path));
|
|
55
|
+
|
|
56
|
+
if (module?.api?.isApi === true) {
|
|
57
|
+
// Exclude disallowed characters
|
|
58
|
+
if (path.includes("_")) {
|
|
59
|
+
console.error(`\n\nPath: "${path.slice(0, -3)}"`);
|
|
60
|
+
console.error(`Do not use "_" in the path. If you want to add a separator between words, please use "-".\n`);
|
|
61
|
+
exit(1);
|
|
62
|
+
}
|
|
63
|
+
if (!/^[a-z0-9/$/-]+$/.test(path.slice(0, -3))) {
|
|
64
|
+
console.error(`\n\nPath: "${path.slice(0, -3)}"`);
|
|
65
|
+
console.error(`The path can only contain lowercase letters, numbers, and "-".\n`);
|
|
66
|
+
exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
templateVars.apiPaths.push(path);
|
|
70
|
+
|
|
71
|
+
if (module?.test?.isApiTest === true) {
|
|
72
|
+
templateVars.apiTestPaths.push(path);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// typia
|
|
76
|
+
const filePath = join(cwd(), "generated", "raw", "apps", path);
|
|
77
|
+
const dirPath = join(cwd(), "generated", "raw", "apps", path).split("/").slice(0, -1).join("/");
|
|
78
|
+
if (!existsSync(dirPath)) {
|
|
79
|
+
mkdirSync(dirPath, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
let importPath = "../../../";
|
|
82
|
+
|
|
83
|
+
for (let i = 0; i < path.split("/").length - 1; i++) {
|
|
84
|
+
importPath = `${importPath}../`;
|
|
85
|
+
}
|
|
86
|
+
importPath = `${importPath}src/apps`;
|
|
87
|
+
const template = `
|
|
92
88
|
import typia from "typia";
|
|
93
89
|
import { _validate, type ExecuteResultFail, type ExecuteResultSuccess } from "milkio";
|
|
94
90
|
import { type TSONEncode } from "@southern-aurora/tson";
|
|
@@ -99,17 +95,17 @@ export const validateParams = async (params: any) => typia.misc.validatePrune<Pa
|
|
|
99
95
|
type ResultsT = Awaited<ReturnType<typeof <%= utils.camel(path.replaceAll('/', '$').slice(0, -${3})) %>['api']['action']>>;
|
|
100
96
|
export const validateResults = async (results: any) => { _validate(typia.validate<TSONEncode<ExecuteResultSuccess<ResultsT> | ExecuteResultFail>>(results)); return typia.json.stringify<TSONEncode<ExecuteResultSuccess<ResultsT> | ExecuteResultFail>>(results); };
|
|
101
97
|
export const randParams = async () => typia.random<ParamsT>();
|
|
102
|
-
`.trim()
|
|
103
|
-
|
|
98
|
+
`.trim();
|
|
99
|
+
// export const paramsSchema = typia.json.application<[{ data: ParamsT }], "swagger">();
|
|
104
100
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
await writeFile(filePath, ejs.render(template, { ...templateVars, path }));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
108
104
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
await writeFile(
|
|
106
|
+
join(cwd(), "generated", "api-schema.ts"),
|
|
107
|
+
ejs.render(
|
|
108
|
+
`
|
|
113
109
|
/**
|
|
114
110
|
* ⚠️ This file is generated and modifications will be overwritten
|
|
115
111
|
*/
|
|
@@ -135,12 +131,12 @@ export default {
|
|
|
135
131
|
},
|
|
136
132
|
}
|
|
137
133
|
`.trim(),
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
134
|
+
templateVars,
|
|
135
|
+
),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// api
|
|
139
|
+
const apiValidatorTemplate = `/**
|
|
144
140
|
* ⚠️This file is generated and modifications will be overwritten
|
|
145
141
|
*/
|
|
146
142
|
|
|
@@ -151,26 +147,26 @@ export default {
|
|
|
151
147
|
<% } %>
|
|
152
148
|
},
|
|
153
149
|
}
|
|
154
|
-
`.trim()
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
150
|
+
`.trim();
|
|
151
|
+
await writeFile(join(cwd(), "generated", "raw", "api-validator.ts"), ejs.render(apiValidatorTemplate, templateVars));
|
|
152
|
+
|
|
153
|
+
console.timeEnd(`File Stage`);
|
|
154
|
+
console.log(``);
|
|
155
|
+
|
|
156
|
+
// typia
|
|
157
|
+
console.time(`Typia Stage`);
|
|
158
|
+
await $`bun run ./node_modules/typia/lib/executable/typia.js generate --input generated/raw --output generated/products --project tsconfig.json`;
|
|
159
|
+
console.timeEnd(`Typia Stage`);
|
|
160
|
+
console.log(``);
|
|
161
|
+
|
|
162
|
+
if (!existsSync(join(cwd(), "milkio.toml"))) return;
|
|
163
|
+
const milkioConfig = (await import(join(cwd(), "milkio.toml"))).default as MilkioConfig;
|
|
164
|
+
if (!milkioConfig?.generate?.significant) return;
|
|
165
|
+
let i = 0;
|
|
166
|
+
for (const command of milkioConfig.generate.significant) {
|
|
167
|
+
++i;
|
|
168
|
+
console.time(`Significant Stage (LINE ${i})`);
|
|
169
|
+
await $`${{ raw: command }}`;
|
|
170
|
+
console.timeEnd(`Significant Stage (LINE ${i})`);
|
|
171
|
+
}
|
|
172
|
+
};
|
package/types.ts
CHANGED
|
@@ -1,50 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
import type { createMilkioApp } from ".";
|
|
2
|
+
import type { failCode } from "../../src/fail-code";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
import type { failCode } from "../../src/fail-code"
|
|
4
|
+
export type MilkioApp = Awaited<ReturnType<typeof createMilkioApp>>;
|
|
5
5
|
|
|
6
|
-
export type
|
|
6
|
+
export type ExecuteId = string | "global";
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type FailEnumerates = typeof failCode;
|
|
9
9
|
|
|
10
|
-
export type
|
|
10
|
+
export type HttpRequest = Request;
|
|
11
11
|
|
|
12
|
-
export type
|
|
13
|
-
|
|
14
|
-
export type HTTPResponse = Override<ResponseInit & { body: string | null | undefined }, { headers: NonNullable<ResponseInit["headers"]> }>
|
|
12
|
+
export type HttpResponse = Override<ResponseInit & { body: string | null | undefined }, { headers: NonNullable<ResponseInit["headers"]> }>;
|
|
15
13
|
|
|
16
14
|
export type Fail<FailCode extends keyof FailEnumerates> = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
15
|
+
code: FailCode;
|
|
16
|
+
message: string;
|
|
17
|
+
data: Parameters<FailEnumerates[FailCode]>[0];
|
|
18
|
+
};
|
|
21
19
|
|
|
22
20
|
export type MilkioMeta = {
|
|
23
|
-
|
|
24
|
-
}
|
|
21
|
+
//
|
|
22
|
+
};
|
|
25
23
|
|
|
26
|
-
export type Cookbook = Record<string, CookbookItem
|
|
24
|
+
export type Cookbook = Record<string, CookbookItem>;
|
|
27
25
|
|
|
28
26
|
export type CookbookItem = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
27
|
+
title?: string;
|
|
28
|
+
desc?: string;
|
|
29
|
+
params: string;
|
|
30
|
+
cases: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
handler: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
37
35
|
|
|
38
|
-
export type Override<P, S> = Omit<P, keyof S> & S
|
|
36
|
+
export type Override<P, S> = Omit<P, keyof S> & S;
|
|
39
37
|
|
|
40
|
-
export type Mixin<T, U> = U & Omit<T, keyof U
|
|
38
|
+
export type Mixin<T, U> = U & Omit<T, keyof U>;
|
|
41
39
|
|
|
42
40
|
export type MilkioConfig = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
41
|
+
generate?: {
|
|
42
|
+
significant?: Array<string>;
|
|
43
|
+
insignificant?: Array<string>;
|
|
44
|
+
};
|
|
45
|
+
menubar?: {
|
|
46
|
+
commands?: Array<{ name?: string; script?: string; icon?: string }>;
|
|
47
|
+
};
|
|
48
|
+
};
|
package/utils/create-ulid.ts
CHANGED
package/utils/env-to-boolean.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export function envToBoolean(value: string | number | undefined, defaultValue: boolean) {
|
|
2
|
-
|
|
2
|
+
if (value === "true") return true;
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
if (value === "false") return false;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
if (value === "") return false;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
if (undefined === value) return defaultValue;
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
return Boolean(value);
|
|
11
11
|
}
|
package/utils/env-to-number.ts
CHANGED
package/utils/env-to-string.ts
CHANGED
package/utils/exec.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { env, type SpawnOptions } from "bun"
|
|
1
|
+
import { env, type SpawnOptions } from "bun";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This is a legacy wrapper that was written before $ Shell was created.
|
|
@@ -6,22 +6,22 @@ import { env, type SpawnOptions } from "bun"
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export const exec = async (cwd: string, command: Array<string>, options: Partial<SpawnOptions.OptionsObject> = {}) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
if (!("cwd" in options)) options.cwd = cwd;
|
|
11
|
+
if (!("stdin" in options)) options.stdin = "inherit";
|
|
12
|
+
if (!("stdout" in options)) options.stdout = "inherit";
|
|
13
|
+
if (!("env" in options)) options.env = { ...env };
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
options.onExit = (proc, exitCode, signalCode, error) => {
|
|
16
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
17
|
+
if (exitCode !== 0) reject({ proc, exitCode, signalCode, error });
|
|
18
|
+
else resolve({ proc, exitCode, signalCode, error });
|
|
19
|
+
};
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
21
|
+
try {
|
|
22
|
+
Bun.spawn(command, options);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
reject(error);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
};
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { failCode } from "../../../src/fail-code"
|
|
2
|
-
import { useLogger, type ExecuteId, type ExecuteResult } from ".."
|
|
3
|
-
import { configMilkio } from "../../../src/config/milkio"
|
|
1
|
+
import { failCode } from "../../../src/fail-code";
|
|
2
|
+
import { useLogger, type ExecuteId, type ExecuteResult } from "..";
|
|
3
|
+
import { configMilkio } from "../../../src/config/milkio";
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
6
|
export function hanldeCatchError(error: any, executeId: ExecuteId): ExecuteResult<any> {
|
|
7
|
-
|
|
7
|
+
const logger = useLogger(executeId);
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
if (configMilkio.debug === true) {
|
|
10
|
+
logger.error(`\nError Data: ${JSON.stringify(error)}`);
|
|
11
|
+
if (error.stack) logger.error("\nError Stack: ", error.stack);
|
|
12
|
+
else logger.error("\nError Stack: ", error);
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
if (error.name !== "MilkioReject") {
|
|
16
|
+
if (configMilkio.debug === true) {
|
|
17
|
+
// If it is not MilkioReject, it is considered an internal server error that should not be exposed
|
|
18
|
+
logger.error(`FailCode: INTERNAL_SERVER_ERROR`);
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (configMilkio.debug === true) {
|
|
32
|
-
logger.error(`FailCode: ${error.code}`)
|
|
33
|
-
}
|
|
21
|
+
return {
|
|
22
|
+
executeId,
|
|
23
|
+
success: false,
|
|
24
|
+
fail: {
|
|
25
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
26
|
+
message: failCode.INTERNAL_SERVER_ERROR(),
|
|
27
|
+
data: undefined,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
if (configMilkio.debug === true) {
|
|
33
|
+
logger.error(`FailCode: ${error.code}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
executeId,
|
|
38
|
+
success: false,
|
|
39
|
+
fail: {
|
|
40
|
+
code: error.code,
|
|
41
|
+
message: error.message,
|
|
42
|
+
data: error.data,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
45
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export const headerToPlainObject = (headers: Headers) => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
2
|
+
if (headers.toJSON) return headers.toJSON();
|
|
3
|
+
const plainHeaders: Record<string, string> = {};
|
|
4
|
+
headers.forEach((value, key) => {
|
|
5
|
+
plainHeaders[key] = value;
|
|
6
|
+
});
|
|
7
|
+
return headers;
|
|
8
|
+
};
|
package/utils/remove-dir.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { existsSync, lstatSync, readdirSync, rmdirSync, unlinkSync } from "node:fs"
|
|
2
|
-
import path from "node:path"
|
|
1
|
+
import { existsSync, lstatSync, readdirSync, rmdirSync, unlinkSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
export function removeDir(pathstr: string, skips: Array<string> = []) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
5
|
+
if (!existsSync(pathstr)) return;
|
|
6
|
+
const files = readdirSync(pathstr);
|
|
7
|
+
files.forEach((file) => {
|
|
8
|
+
const dirname = path.resolve(pathstr, file);
|
|
9
|
+
const stats = lstatSync(dirname);
|
|
10
|
+
for (const skip of skips) {
|
|
11
|
+
if (dirname.startsWith(skip)) return;
|
|
12
|
+
}
|
|
13
|
+
if (stats.isDirectory()) {
|
|
14
|
+
removeDir(dirname);
|
|
15
|
+
} else {
|
|
16
|
+
unlinkSync(dirname);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
try {
|
|
20
|
+
rmdirSync(pathstr);
|
|
21
|
+
} catch (error) {}
|
|
22
22
|
}
|
package/utils/tson.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { TSON as _TSON } from "@southern-aurora/tson"
|
|
1
|
+
import { TSON as _TSON } from "@southern-aurora/tson";
|
|
2
2
|
|
|
3
|
-
export const TSON = _TSON
|
|
3
|
+
export const TSON = _TSON;
|
package/.co.toml
DELETED