milkio 0.8.0 → 0.8.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/.publish/releases/0.8.0.md +6 -6
- package/.publish/releases-github/0.8.0.md +126 -0
- package/README.md +2 -14
- package/api-test/index.ts +4 -2
- package/c.ts +3 -3
- package/defines/define-command-handler.ts +2 -2
- package/defines/define-config.ts +2 -2
- package/defines/define-http-handler.ts +1 -1
- package/kernel/logger.ts +1 -1
- package/kernel/validate.ts +2 -2
- package/package.json +1 -1
- package/types.ts +4 -9
- package/utils/handle-catch-error.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 0.
|
|
1
|
+
# 0.8.0 - 不再抛弃的承诺
|
|
2
2
|
|
|
3
3
|
> 黑川讨厌自己,讨厌那个因为害怕而当胆小鬼的自己。
|
|
4
4
|
> 爱丽丝把自己当做了唯一,是他,带她见到了这个色彩斑斓的世界,却又在短短数天后把她给抛弃。
|
|
@@ -63,11 +63,11 @@ async action(
|
|
|
63
63
|
```ts
|
|
64
64
|
⬇️ Meta
|
|
65
65
|
⬇️ Action
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
step: Step 1
|
|
67
|
+
step: Step 2
|
|
68
|
+
step: Step 3
|
|
69
69
|
⬇️ Tests
|
|
70
|
-
|
|
70
|
+
test: Basic
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
## VS Code:同时启动前端工程
|
|
@@ -123,6 +123,6 @@ Electron: https://milkio.fun/runtime/electron/
|
|
|
123
123
|
使用新版本时,请务必也一同升级你的客户端包的版本。
|
|
124
124
|
|
|
125
125
|
```
|
|
126
|
-
bun i milkio@0.
|
|
126
|
+
bun i milkio@0.8.0
|
|
127
127
|
cd packages/client && bun i milkio-client
|
|
128
128
|
```
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# 0.8.0 - A Promise Kept
|
|
2
|
+
|
|
3
|
+
> Kurokawa hated himself, hated the cowardly version of himself that acted out of fear.
|
|
4
|
+
> Alice treated herself as the only one, it was him who showed her this colorful world, only to abandon her a few days later.
|
|
5
|
+
> Whenever Kurokawa closed his eyes, the image of Alice leaning on his arm would appear in his mind, laughing so happily, with traces of ice cream still on the corners of her mouth.
|
|
6
|
+
> Finally, trembling, Kurokawa pressed the elevator button leading to the top floor.
|
|
7
|
+
> "No matter what... I won't abandon you..." Kurokawa took a deep breath, and as the elevator doors slowly opened, his eyes gradually hardened like steel.
|
|
8
|
+
|
|
9
|
+
## Feature: Milkio Steps
|
|
10
|
+
|
|
11
|
+
In Milkio, a new mental model for writing APIs has been introduced: Steps. It allows you to break down long API code into several small steps, which can enhance the readability of complex API code.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
async action(
|
|
15
|
+
params: {
|
|
16
|
+
by: string & typia.tags.MinLength<2> & typia.tags.MaxLength<16>;
|
|
17
|
+
},
|
|
18
|
+
context,
|
|
19
|
+
) {
|
|
20
|
+
const result = await context
|
|
21
|
+
/**
|
|
22
|
+
* Step 1
|
|
23
|
+
*/
|
|
24
|
+
.step(async (stages) => {
|
|
25
|
+
const message1 = `Step 1`;
|
|
26
|
+
|
|
27
|
+
return { message1 };
|
|
28
|
+
})
|
|
29
|
+
/**
|
|
30
|
+
* Step 2
|
|
31
|
+
*/
|
|
32
|
+
.step(async (stage) => {
|
|
33
|
+
const $message2 = `Step 2`;
|
|
34
|
+
|
|
35
|
+
return { $message2 };
|
|
36
|
+
})
|
|
37
|
+
/**
|
|
38
|
+
* Step 3
|
|
39
|
+
*/
|
|
40
|
+
.step(async (stage) => {
|
|
41
|
+
if (!stage.message1) throw reject("INTERNAL_SERVER_ERROR", undefined);
|
|
42
|
+
if (!stage.$message2) throw reject("INTERNAL_SERVER_ERROR", undefined);
|
|
43
|
+
return {};
|
|
44
|
+
})
|
|
45
|
+
.run();
|
|
46
|
+
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Each `step` is a function that returns an object, which will be merged into the next `stage`.
|
|
52
|
+
|
|
53
|
+
If an attribute in the object starts with `$`, Milkio treats it as a private property. Although it is always accessible in `stage`, it will be removed in `result`.
|
|
54
|
+
|
|
55
|
+
To avoid modifying attributes in `stage`, making it difficult to know when certain values are changed, the properties are designed to be immutable.
|
|
56
|
+
|
|
57
|
+
## VS Code: Milkio Structure
|
|
58
|
+
|
|
59
|
+
> Note: Ensure your Milkio VS Code Extension is up to date
|
|
60
|
+
|
|
61
|
+
Now, the bottom of your VS Code Explorer will display the structure of your Milkio API. You can use it to navigate through longer API codes.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
⬇️ Meta
|
|
65
|
+
⬇️ Action
|
|
66
|
+
step: Step 1
|
|
67
|
+
step: Step 2
|
|
68
|
+
step: Step 3
|
|
69
|
+
⬇️ Tests
|
|
70
|
+
test: Basic
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## VS Code: Simultaneously Launch Frontend Projects
|
|
74
|
+
|
|
75
|
+
> Note: Ensure your Milkio VS Code Extension is up to date
|
|
76
|
+
|
|
77
|
+
Milkio now supports associating with your frontend projects and synchronously launching them when starting Milkio. Configure it in `milkio.toml` as shown below.
|
|
78
|
+
|
|
79
|
+
```toml
|
|
80
|
+
[link]
|
|
81
|
+
projects = [
|
|
82
|
+
{ name = 'YourViteProject', cwd = '../your-project-path', script = 'bun run dev' },
|
|
83
|
+
]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## VS Code: Workspace Optimization
|
|
87
|
+
|
|
88
|
+
> Note: Ensure your Milkio VS Code Extension is up to date
|
|
89
|
+
|
|
90
|
+
Previously, when using a workspace, the Milkio menu bar would only appear if the files open on the screen were part of a Milkio project.
|
|
91
|
+
|
|
92
|
+
Now, if there is only one Milkio project in the workspace, the Milkio menu bar will always appear, assuming that you want to operate on that specific Milkio project.
|
|
93
|
+
|
|
94
|
+
## Configuration: Automatic Environment-Based Switching
|
|
95
|
+
|
|
96
|
+
Now, the configuration supports automatically reading different configurations based on different environments.
|
|
97
|
+
|
|
98
|
+
https://milkio.fun/essentials/config
|
|
99
|
+
|
|
100
|
+
## Testing: Support for Testing with Real Requests
|
|
101
|
+
|
|
102
|
+
Testing now includes a `client` object that allows you to use a real client package to send actual requests.
|
|
103
|
+
|
|
104
|
+
https://milkio.fun/essentials/api-test
|
|
105
|
+
|
|
106
|
+
## Templates: Cloudflare Workers Support
|
|
107
|
+
|
|
108
|
+
Milkio now supports Cloudflare Workers. You can create a Cloudflare Workers project by selecting the `cloudflare` option when running `bun create milkio`.
|
|
109
|
+
|
|
110
|
+
## Documentation: Runtime Documentation Improvements
|
|
111
|
+
|
|
112
|
+
I have written documentation for each runtime, detailing important points and deployment procedures.
|
|
113
|
+
|
|
114
|
+
Bun: https://milkio.fun/runtime/bun/
|
|
115
|
+
Node.js: https://milkio.fun/runtime/node/
|
|
116
|
+
Cloudflare: https://milkio.fun/runtime/cloudflare/
|
|
117
|
+
Electron: https://milkio.fun/runtime/electron/
|
|
118
|
+
|
|
119
|
+
## Upgrading
|
|
120
|
+
|
|
121
|
+
When using the new version, make sure to also upgrade your client package version.
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
bun i milkio@0.8.0
|
|
125
|
+
cd packages/client && bun i milkio-client
|
|
126
|
+
```
|
package/README.md
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Milkio
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
bun install
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
To run:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
bun run index.ts
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
This project was created using `bun init` in bun v1.0.3. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
|
3
|
+
Document: [milkio.fun](https://milkio.fun)
|
package/api-test/index.ts
CHANGED
|
@@ -31,7 +31,7 @@ export const executeApiTests = async <Path extends Array<keyof (typeof schema)["
|
|
|
31
31
|
for (let index = 0; index < 160; index++) {
|
|
32
32
|
let response;
|
|
33
33
|
try {
|
|
34
|
-
response = await fetch(typeof clientPackage.options.baseUrl === "string" ? clientPackage.options.baseUrl : await clientPackage.options.baseUrl(), { method: "
|
|
34
|
+
response = await fetch(typeof clientPackage.options.baseUrl === "string" ? clientPackage.options.baseUrl : await clientPackage.options.baseUrl(), { method: "GET" });
|
|
35
35
|
} catch (error: any) {
|
|
36
36
|
if (error?.status && error.status < 500) {
|
|
37
37
|
done = true;
|
|
@@ -39,6 +39,8 @@ export const executeApiTests = async <Path extends Array<keyof (typeof schema)["
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
if (response?.status && response.status < 500) {
|
|
42
|
+
console.warn(response, response.status);
|
|
43
|
+
|
|
42
44
|
done = true;
|
|
43
45
|
break;
|
|
44
46
|
}
|
|
@@ -46,7 +48,7 @@ export const executeApiTests = async <Path extends Array<keyof (typeof schema)["
|
|
|
46
48
|
continue;
|
|
47
49
|
}
|
|
48
50
|
if (!done) {
|
|
49
|
-
console.log(`🚨 The server startup exceeded the maximum waiting time (
|
|
51
|
+
console.log(`🚨 The server startup exceeded the maximum waiting time (16000ms).`);
|
|
50
52
|
console.log(`This is likely an error encountered during the startup of the Milkio Server. Please check the 'Milkio Run & Watch' tab in your VS Code terminal panel. This is only a warning, and the tests will continue, but there is a chance they might fail due to network issues.\n`);
|
|
51
53
|
}
|
|
52
54
|
}
|
package/c.ts
CHANGED
|
@@ -26,14 +26,14 @@ const commands = {
|
|
|
26
26
|
async EAR(commandBase64ed: string) {
|
|
27
27
|
try {
|
|
28
28
|
console.clear();
|
|
29
|
-
} catch (e) {
|
|
29
|
+
} catch (e) {}
|
|
30
30
|
const command = Buffer.from(commandBase64ed, "base64").toString("utf-8");
|
|
31
31
|
console.log("\x1B[2m%s\x1B[0m", `$ ${command}`);
|
|
32
32
|
console.log(``);
|
|
33
33
|
try {
|
|
34
34
|
await $`${{ raw: command }}`.env({ ...env, FORCE_COLOR: "3" });
|
|
35
|
-
} catch (e) {
|
|
36
|
-
process.on("SIGINT", () => {
|
|
35
|
+
} catch (e) {}
|
|
36
|
+
process.on("SIGINT", () => {}); // prevent users from exiting by pressing ctrl + c
|
|
37
37
|
while (true) await new Promise((resolve) => process.stdin.on("keypress", resolve));
|
|
38
38
|
},
|
|
39
39
|
};
|
|
@@ -27,13 +27,13 @@ export function defineCommandHandler(app: MilkioApp, options: CommandOptions = {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
if (argv.length === 2) params.path = `$/default`;
|
|
30
|
-
else params.path = `$/${argv[2] ??
|
|
30
|
+
else params.path = `$/${argv[2] ?? "default"}`;
|
|
31
31
|
|
|
32
32
|
// @ts-ignore
|
|
33
33
|
const result = await app.execute(params.path as any, { params: params });
|
|
34
34
|
if (!result.success) {
|
|
35
35
|
if (result.fail.code === "NOT_FOUND") {
|
|
36
|
-
if (options.notFoundHandler) await options.notFoundHandler({ ...params, name: argv.length === 2 ? "default" :
|
|
36
|
+
if (options.notFoundHandler) await options.notFoundHandler({ ...params, name: argv.length === 2 ? "default" : argv[2] ?? "default" });
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
if (result.fail.code !== "INTERNAL_SERVER_ERROR") {
|
package/defines/define-config.ts
CHANGED
|
@@ -2,7 +2,7 @@ export function defineConfig<T>(handler: (options: { config: typeof configFn })
|
|
|
2
2
|
const result = handler({ config: configFn });
|
|
3
3
|
if (!result) throw new Error("defineConfig must return a value, Did you forget to add a return statement?");
|
|
4
4
|
if (typeof result !== "object" || Array.isArray(result)) throw new Error("defineConfig must return an object.");
|
|
5
|
-
if ("environment" in result && "done" in result && typeof result["environment"] === "function" && typeof result["done"] === "function") throw new Error("Did you accidentally return the config method without adding
|
|
5
|
+
if ("environment" in result && "done" in result && typeof result["environment"] === "function" && typeof result["done"] === "function") throw new Error("Did you accidentally return the config method without adding `.done()`?");
|
|
6
6
|
return result;
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -29,4 +29,4 @@ export type Config = Record<string, unknown>;
|
|
|
29
29
|
export type ConfigMore<ConfigT extends Config> = {
|
|
30
30
|
environment: (when: () => boolean, config: Partial<ConfigT>) => ConfigMore<ConfigT>;
|
|
31
31
|
done: () => ConfigT;
|
|
32
|
-
};
|
|
32
|
+
};
|
|
@@ -137,7 +137,7 @@ export function defineHttpHandler(app: MilkioApp, options: ExecuteHttpServerOpti
|
|
|
137
137
|
else params = undefined;
|
|
138
138
|
// Doing so may pose security risks, as attackers may trigger your requests through link redirection without being protected by browser CORS.
|
|
139
139
|
// Therefore, this feature was commented out after v0.3.0.
|
|
140
|
-
// else if (request.request.method === 'GET' && fullurl.searchParams.get('params')) {
|
|
140
|
+
// else if (request.request.method === 'GET' && fullurl.searchParams.get('params')) { params = JSON.parse(decodeURIComponent(fullurl.searchParams.get('params')!)); }
|
|
141
141
|
} catch (error) {
|
|
142
142
|
const logger = useLogger(executeId);
|
|
143
143
|
logger.log("TIP: body is not json, the content is not empty, but the content is not in a valid JSON format. The original content value can be retrieved via request.request.text()");
|
package/kernel/logger.ts
CHANGED
|
@@ -40,7 +40,7 @@ export type Logger = {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export const loggerController = (() => {
|
|
43
|
-
const logs = new Map<ExecuteId, { __LOG_DETAIL__: Array<LoggerItem>;[key: string]: any }>();
|
|
43
|
+
const logs = new Map<ExecuteId, { __LOG_DETAIL__: Array<LoggerItem>; [key: string]: any }>();
|
|
44
44
|
|
|
45
45
|
const loggerPushTags = (executeId: ExecuteId, tags: Partial<MilkioLoggerTags & LoggerTags>) => {
|
|
46
46
|
if (!logs.has(executeId)) logs.set(executeId, { __LOG_DETAIL__: [] });
|
package/kernel/validate.ts
CHANGED
|
@@ -5,8 +5,8 @@ export function _validate(validator: IValidation.IFailure | IValidation.ISuccess
|
|
|
5
5
|
if (validator.success) return validator.data;
|
|
6
6
|
const error = validator.errors[0];
|
|
7
7
|
|
|
8
|
-
if (
|
|
9
|
-
if (
|
|
8
|
+
if (error.value === undefined) error.value === "undefined";
|
|
9
|
+
if (error.value === null) error.value === "null";
|
|
10
10
|
|
|
11
11
|
throw reject("TYPE_SAFE_ERROR", {
|
|
12
12
|
path: error.path,
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -53,8 +53,8 @@ export type MilkioConfig = {
|
|
|
53
53
|
export type ExecuteResult<Result> = ExecuteResultSuccess<Result> | ExecuteResultFail;
|
|
54
54
|
|
|
55
55
|
export type ExecuteStreamResult<Path, Result> = {
|
|
56
|
-
getResult: () => ExecuteResultSuccess<Result> | ExecuteResultFail
|
|
57
|
-
stream: AsyncGenerator<MilkioEvent<Path
|
|
56
|
+
getResult: () => ExecuteResultSuccess<Result> | ExecuteResultFail;
|
|
57
|
+
stream: AsyncGenerator<MilkioEvent<Path>>;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
export type ExecuteResultSuccess<Result> = {
|
|
@@ -94,13 +94,8 @@ export type ExecuteCoreOptions = Mixin<
|
|
|
94
94
|
|
|
95
95
|
export type MilkioEvent<Result> = Awaited<GeneratorGeneric<ExecuteResultSuccess<Result>["data"] extends { $type: any } ? ExecuteResultSuccess<Result>["data"]["$type"] : never>>;
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
export type ToEmptyObject<T> = T extends undefined | null | never
|
|
99
|
-
? {}
|
|
100
|
-
: T extends object
|
|
101
|
-
? T
|
|
102
|
-
: {};
|
|
97
|
+
export type ToEmptyObject<T> = T extends undefined | null | never ? {} : T extends object ? T : {};
|
|
103
98
|
|
|
104
99
|
export type Remove$<T> = {
|
|
105
100
|
[K in keyof T as K extends `$${string}` ? never : K]: T[K];
|
|
106
|
-
};
|
|
101
|
+
};
|