milkio 1.0.0-alpha.2 → 1.0.0-alpha.4
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/.co.toml +0 -0
- package/.publish/publish.json +0 -0
- package/.publish/releases/0.0.0.md +0 -0
- package/.publish/releases/0.1.0.md +0 -0
- package/.publish/releases/0.2.0.md +0 -0
- package/.publish/releases/0.3.0.md +0 -0
- package/.publish/releases/0.4.0.md +0 -0
- package/.publish/releases/0.5.0.md +0 -0
- package/.publish/releases/0.6.0.md +0 -0
- package/.publish/releases/0.8.0.md +0 -0
- package/.publish/releases-github/0.0.0.md +0 -0
- package/.publish/releases-github/0.1.0.md +0 -0
- package/.publish/releases-github/0.2.0.md +0 -0
- package/.publish/releases-github/0.3.0.md +0 -0
- package/.publish/releases-github/0.4.0.md +0 -0
- package/.publish/releases-github/0.5.0.md +0 -0
- package/.publish/releases-github/0.6.0.md +0 -0
- package/.publish/releases-github/0.8.0.md +0 -0
- package/action/index.ts +0 -0
- package/command/index.ts +0 -0
- package/context/index.ts +5 -2
- package/events/index.ts +47 -0
- package/exception/index.ts +0 -1
- package/execute/execute-id-generator.ts +0 -0
- package/execute/index.ts +18 -15
- package/index.ts +3 -1
- package/listener/index.ts +29 -19
- package/logger/index.ts +39 -28
- package/meta/index.ts +1 -1
- package/package.json +1 -1
- package/step/index.ts +36 -0
- package/stream/index.ts +0 -0
- package/types/index.ts +2 -0
- package/utils/create-id.ts +0 -0
- package/utils/headers-to-json.ts +7 -0
- package/utils/send-cookbook-event.ts +26 -0
- package/world/index.ts +48 -22
- package/middleware/index.ts +0 -19
- package/test/index.ts +0 -21
package/.co.toml
CHANGED
|
File without changes
|
package/.publish/publish.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/action/index.ts
CHANGED
|
File without changes
|
package/command/index.ts
CHANGED
|
File without changes
|
package/context/index.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { type MilkioHttpRequest, type MilkioHttpResponse, type $types, type Logger } from "..";
|
|
1
|
+
import { type MilkioHttpRequest, type MilkioHttpResponse, type $types, type Logger, Steps } from "..";
|
|
2
2
|
|
|
3
3
|
export interface $context {
|
|
4
4
|
executeId: string;
|
|
5
5
|
path: string;
|
|
6
6
|
logger: Logger;
|
|
7
7
|
http?: ContextHttp<Record<any, any>>;
|
|
8
|
+
step: Steps<{}>["step"];
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export type ContextHttp<ParamsParsed> = {
|
|
11
|
+
export type ContextHttp<ParamsParsed = any> = {
|
|
11
12
|
url: URL;
|
|
12
13
|
ip: string;
|
|
13
14
|
path: { string: keyof $types["generated"]["routeSchema"]["$types"]; array: Array<string> };
|
|
@@ -18,3 +19,5 @@ export type ContextHttp<ParamsParsed> = {
|
|
|
18
19
|
request: MilkioHttpRequest;
|
|
19
20
|
response: MilkioHttpResponse;
|
|
20
21
|
};
|
|
22
|
+
|
|
23
|
+
export type ContextCreatedHandler = (context: $context) => Promise<void> | void;
|
package/events/index.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type $context, type ContextHttp, type Results, type Logger } from "..";
|
|
2
|
+
|
|
3
|
+
export interface $events {
|
|
4
|
+
"milkio:httpRequest": { executeId: string; path: string; logger: Logger; http: ContextHttp<Record<string, any>> };
|
|
5
|
+
"milkio:httpResponse": { executeId: string; path: string; logger: Logger; http: ContextHttp<Record<string, any>>; context: $context };
|
|
6
|
+
"milkio:httpNotFound": { executeId: string; path: string; logger: Logger; http: ContextHttp<Record<string, any>> };
|
|
7
|
+
"milkio:executeBefore": { executeId: string; path: string; logger: Logger; context: $context };
|
|
8
|
+
"milkio:executeAfter": { executeId: string; path: string; logger: Logger; context: $context; results: Results<any> };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const __initEventManager = () => {
|
|
12
|
+
const handlers = new Map<(event: any) => void, string>();
|
|
13
|
+
const indexed = new Map<string, Set<(event: any) => void>>();
|
|
14
|
+
|
|
15
|
+
const eventManager = {
|
|
16
|
+
on: <Key extends keyof $events, Handler extends (event: $events[Key]) => void>(key: Key, handler: Handler) => {
|
|
17
|
+
handlers.set(handler, key as string);
|
|
18
|
+
if (indexed.has(key as string) === false) {
|
|
19
|
+
indexed.set(key as string, new Set());
|
|
20
|
+
}
|
|
21
|
+
const set = indexed.get(key as string)!;
|
|
22
|
+
set.add(handler);
|
|
23
|
+
handlers.set(handler, key as string);
|
|
24
|
+
|
|
25
|
+
return () => {
|
|
26
|
+
handlers.delete(handler);
|
|
27
|
+
set.delete(handler);
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
off: <Key extends keyof $events, Handler extends (event: $events[Key]) => void>(key: Key, handler: Handler) => {
|
|
31
|
+
const set = indexed.get(key as string);
|
|
32
|
+
if (!set) return;
|
|
33
|
+
handlers.delete(handler);
|
|
34
|
+
set.delete(handler);
|
|
35
|
+
},
|
|
36
|
+
emit: async <Key extends keyof $events, Value extends $events[Key]>(key: Key, value: Value): Promise<void> => {
|
|
37
|
+
const h = indexed.get(key as string);
|
|
38
|
+
if (h) {
|
|
39
|
+
for (const handler of h) {
|
|
40
|
+
await handler(value);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return eventManager;
|
|
47
|
+
};
|
package/exception/index.ts
CHANGED
|
@@ -8,7 +8,6 @@ export interface $rejectCode {
|
|
|
8
8
|
REQUEST_TIMEOUT: { timeout: number; message: string };
|
|
9
9
|
NOT_FOUND: { path: string };
|
|
10
10
|
PARAMS_TYPE_INCORRECT: { path: string; expected: string; value: any; message: string } | null;
|
|
11
|
-
RESULTS_TYPE_INCORRECT: { path: string; expected: string; value: any; message: string } | null;
|
|
12
11
|
UNACCEPTABLE: { expected: string; message: string };
|
|
13
12
|
PARAMS_TYPE_NOT_SUPPORTED: { expected: string };
|
|
14
13
|
INTERNAL_SERVER_ERROR: undefined;
|
|
File without changes
|
package/execute/index.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { type IValidation } from "typia";
|
|
2
2
|
import { TSON } from "@southern-aurora/tson";
|
|
3
3
|
import { createId } from "../utils/create-id";
|
|
4
|
-
import { reject, type $context, type $meta, type ExecuteOptions, type Logger, type MilkioRuntimeInit, type Results, type GeneratedInit, type MilkioInit, createLogger, exceptionHandler, Ping } from "..";
|
|
5
|
-
|
|
6
|
-
export type MilkioHttpRequest = {
|
|
7
|
-
request: Request;
|
|
8
|
-
};
|
|
4
|
+
import { reject, type $context, type $meta, type ExecuteOptions, type Logger, type MilkioRuntimeInit, type Results, type GeneratedInit, type MilkioInit, createLogger, exceptionHandler, Ping, createStep } from "..";
|
|
5
|
+
import { headersToJSON } from "../utils/headers-to-json";
|
|
9
6
|
|
|
10
7
|
export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRuntimeInit<MilkioInit>> = MilkioRuntimeInit<MilkioInit>>(generated: GeneratedInit, runtime: MilkioRuntime) => {
|
|
11
8
|
const __call = async (
|
|
@@ -37,6 +34,8 @@ export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
37
34
|
} else {
|
|
38
35
|
headers = options.headers;
|
|
39
36
|
}
|
|
37
|
+
if (!("toJSON" in headers)) (headers as any).toJSON = () => headersToJSON(headers);
|
|
38
|
+
|
|
40
39
|
let params: Record<any, unknown>;
|
|
41
40
|
if (options.paramsType === "raw") {
|
|
42
41
|
params = options.params;
|
|
@@ -54,12 +53,11 @@ export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
54
53
|
}
|
|
55
54
|
if (typeof params !== "object" || Array.isArray(params)) throw reject("PARAMS_TYPE_NOT_SUPPORTED", { expected: "json" });
|
|
56
55
|
if ("$milkioGenerateParams" in params && params.$milkioGenerateParams === "enable") {
|
|
57
|
-
if (runtime.
|
|
56
|
+
if (!runtime.develop) throw reject("NOT_DEVELOP_MODE", "This feature must be in cookbook to use.");
|
|
58
57
|
delete params.$milkioGenerateParams;
|
|
59
58
|
let paramsRand = routeSchema.randomParams();
|
|
60
59
|
if (paramsRand === undefined || paramsRand === null) paramsRand = {};
|
|
61
60
|
params = { ...paramsRand, ...params };
|
|
62
|
-
options.createdLogger.debug("[milkio]", "🪄 generate params:", options.path, TSON.stringify(params));
|
|
63
61
|
}
|
|
64
62
|
if (options.mixinContext?.http?.params?.string) options.mixinContext.http.params.parsed = params; // listen でパースしたパラメータを渡す
|
|
65
63
|
const context = {
|
|
@@ -67,24 +65,27 @@ export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
67
65
|
path: options.path,
|
|
68
66
|
logger: options.createdLogger,
|
|
69
67
|
executeId: options.createdExecuteId,
|
|
68
|
+
step: createStep(),
|
|
70
69
|
} as unknown as $context;
|
|
71
|
-
|
|
72
70
|
const results: Results<unknown> = { value: undefined };
|
|
73
71
|
|
|
72
|
+
if (runtime.develop) {
|
|
73
|
+
options.createdLogger.request(`headers - ${TSON.stringify(headers.toJSON())}`, `\nparams - ${TSON.stringify(params)}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
74
76
|
const module = await routeSchema.module();
|
|
75
77
|
let meta = (module.meta ? module.meta : {}) as unknown as Readonly<$meta>;
|
|
76
78
|
|
|
77
|
-
if (!meta.typeSafety || meta.typeSafety
|
|
79
|
+
if (!meta.typeSafety || meta.typeSafety === true) {
|
|
78
80
|
const validation = routeSchema.validateParams(params) as IValidation<any>;
|
|
79
81
|
if (!validation.success) throw reject("PARAMS_TYPE_INCORRECT", { ...validation.errors[0], message: `The value '${validation.errors[0].path}' is '${validation.errors[0].value}', which does not meet '${validation.errors[0].expected}' requirements.` });
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
await runtime.emit("milkio:executeBefore", { executeId: options.createdExecuteId, logger: options.createdLogger, path: options.path, context });
|
|
85
|
+
|
|
82
86
|
results.value = await module.default.handler(context, params);
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
const validation = routeSchema.validateResults(results.value) as IValidation<any>;
|
|
86
|
-
if (!validation.success) throw reject("RESULTS_TYPE_INCORRECT", { ...validation.errors[0], message: `The value '${validation.errors[0].path}' is '${validation.errors[0].value}', which does not meet '${validation.errors[0].expected}' requirements.` });
|
|
87
|
-
}
|
|
88
|
+
await runtime.emit("milkio:executeAfter", { executeId: options.createdExecuteId, logger: options.createdLogger, path: options.path, context, results });
|
|
88
89
|
|
|
89
90
|
return { executeId, headers, params, results, context, meta, type: module.$milkioType };
|
|
90
91
|
};
|
|
@@ -92,12 +93,14 @@ export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
92
93
|
const execute = async (path: string, options?: ExecuteOptions): Promise<any> => {
|
|
93
94
|
if (!options) options = {};
|
|
94
95
|
const executeId = createId();
|
|
95
|
-
const logger = createLogger(runtime, executeId);
|
|
96
|
+
const logger = createLogger(runtime, path, executeId);
|
|
96
97
|
runtime.runtime.request.set(executeId, { logger: logger });
|
|
97
98
|
|
|
98
99
|
try {
|
|
99
100
|
const routeSchema = generated.routeSchema.routes.get(path);
|
|
100
|
-
if (routeSchema === undefined)
|
|
101
|
+
if (routeSchema === undefined) {
|
|
102
|
+
throw reject("NOT_FOUND", { path: path });
|
|
103
|
+
}
|
|
101
104
|
|
|
102
105
|
const executed = await __call(routeSchema, {
|
|
103
106
|
createdExecuteId: executeId,
|
package/index.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from "./types";
|
|
2
|
+
export * from "./execute";
|
|
3
|
+
export * from "./events";
|
|
2
4
|
export * from "./world";
|
|
3
5
|
export * from "./command";
|
|
4
6
|
export * from "./action";
|
|
5
7
|
export * from "./stream";
|
|
6
|
-
export * from "./test";
|
|
7
8
|
export * from "./logger";
|
|
8
9
|
export * from "./context";
|
|
9
10
|
export * from "./meta";
|
|
11
|
+
export * from "./step";
|
|
10
12
|
export * from "./listener";
|
|
11
13
|
export * from "./exception";
|
package/listener/index.ts
CHANGED
|
@@ -15,14 +15,14 @@ export type MilkioHttpResponse = Mixin<
|
|
|
15
15
|
>;
|
|
16
16
|
|
|
17
17
|
export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRuntimeInit<MilkioInit>> = MilkioRuntimeInit<MilkioInit>>(generated: GeneratedInit, runtime: MilkioRuntime, executer: ReturnType<typeof __initExecuter>) => {
|
|
18
|
-
const port = runtime.port
|
|
18
|
+
const port = runtime.port;
|
|
19
19
|
const fetch = async (request: MilkioHttpRequest): Promise<Response> => {
|
|
20
20
|
if (request.method === "OPTIONS") {
|
|
21
21
|
return new Response(undefined, {
|
|
22
22
|
headers: {
|
|
23
|
-
"Access-Control-Allow-Methods": runtime.corsAllowMethods ?? "*",
|
|
24
|
-
"Access-Control-Allow-Origin": runtime.corsAllowOrigin ?? "*",
|
|
25
|
-
"Access-Control-Allow-Headers": runtime.corsAllowHeaders ?? "*",
|
|
23
|
+
"Access-Control-Allow-Methods": runtime.cors?.corsAllowMethods ?? "*",
|
|
24
|
+
"Access-Control-Allow-Origin": runtime.cors?.corsAllowOrigin ?? "*",
|
|
25
|
+
"Access-Control-Allow-Headers": runtime.cors?.corsAllowHeaders ?? "*",
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
}
|
|
@@ -31,25 +31,30 @@ export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
31
31
|
return new Response("", {
|
|
32
32
|
status: 204,
|
|
33
33
|
headers: {
|
|
34
|
-
"Access-Control-Allow-Methods": runtime.corsAllowMethods ?? "*",
|
|
35
|
-
"Access-Control-Allow-Origin": runtime.corsAllowOrigin ?? "*",
|
|
36
|
-
"Access-Control-Allow-Headers": runtime.corsAllowHeaders ?? "*",
|
|
34
|
+
"Access-Control-Allow-Methods": runtime.cors?.corsAllowMethods ?? "*",
|
|
35
|
+
"Access-Control-Allow-Origin": runtime.cors?.corsAllowOrigin ?? "*",
|
|
36
|
+
"Access-Control-Allow-Headers": runtime.cors?.corsAllowHeaders ?? "*",
|
|
37
37
|
"Cache-Control": "no-store",
|
|
38
38
|
"Content-Type": "text/plain; time=" + Date.now(),
|
|
39
39
|
},
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
const url = new URL(request.url);
|
|
44
|
+
let pathArray = url.pathname.substring(1).split("/");
|
|
45
|
+
if (runtime.ignorePathLevel !== undefined && runtime.ignorePathLevel !== 0) pathArray = pathArray.slice(runtime.ignorePathLevel);
|
|
46
|
+
const pathString = `/${pathArray.join("/")}`;
|
|
47
|
+
|
|
48
|
+
const executeId = runtime?.executeId ? await runtime.executeId(request) : createId();
|
|
49
|
+
const logger = createLogger(runtime, pathString, executeId);
|
|
45
50
|
runtime.runtime.request.set(executeId, { logger: logger });
|
|
46
51
|
const response: MilkioHttpResponse = {
|
|
47
52
|
body: "",
|
|
48
53
|
status: 200,
|
|
49
54
|
headers: {
|
|
50
|
-
"Access-Control-Allow-Methods": runtime.corsAllowMethods ?? "*",
|
|
51
|
-
"Access-Control-Allow-Origin": runtime.corsAllowOrigin ?? "*",
|
|
52
|
-
"Access-Control-Allow-Headers": runtime.corsAllowHeaders ?? "*",
|
|
55
|
+
"Access-Control-Allow-Methods": runtime.cors?.corsAllowMethods ?? "*",
|
|
56
|
+
"Access-Control-Allow-Origin": runtime.cors?.corsAllowOrigin ?? "*",
|
|
57
|
+
"Access-Control-Allow-Headers": runtime.cors?.corsAllowHeaders ?? "*",
|
|
53
58
|
"Cache-Control": "no-store",
|
|
54
59
|
"Content-Type": "application/json",
|
|
55
60
|
},
|
|
@@ -57,11 +62,7 @@ export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
57
62
|
|
|
58
63
|
try {
|
|
59
64
|
const http = (await (async () => {
|
|
60
|
-
const
|
|
61
|
-
let pathArray = url.pathname.substring(1).split("/");
|
|
62
|
-
if (runtime.ignorePathLevel !== undefined && runtime.ignorePathLevel !== 0) pathArray = pathArray.slice(runtime.ignorePathLevel);
|
|
63
|
-
const pathString = `/${pathArray.join("/")}`;
|
|
64
|
-
const ip = runtime.getRealIp ? runtime.getRealIp(request) : "::1";
|
|
65
|
+
const ip = runtime.realIp ? runtime.realIp(request) : "::1";
|
|
65
66
|
const params = {
|
|
66
67
|
string: await request.text(),
|
|
67
68
|
parsed: undefined,
|
|
@@ -74,13 +75,18 @@ export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
74
75
|
params,
|
|
75
76
|
request,
|
|
76
77
|
response,
|
|
77
|
-
} as ContextHttp
|
|
78
|
+
} as ContextHttp;
|
|
78
79
|
})())!;
|
|
79
80
|
|
|
81
|
+
await runtime.emit("milkio:httpRequest", { executeId, logger, path: http.path.string as string, http });
|
|
82
|
+
|
|
80
83
|
if (!request.headers.get("Accept")?.startsWith("text/event-stream")) {
|
|
81
84
|
// action
|
|
82
85
|
const routeSchema = generated.routeSchema.routes.get(http.path.string);
|
|
83
|
-
if (routeSchema === undefined)
|
|
86
|
+
if (routeSchema === undefined) {
|
|
87
|
+
await runtime.emit("milkio:httpNotFound", { executeId, logger, path: http.path.string as string, http });
|
|
88
|
+
throw reject("NOT_FOUND", { path: http.path.string as string });
|
|
89
|
+
}
|
|
84
90
|
if (routeSchema.type !== "action") throw reject("UNACCEPTABLE", { expected: "stream", message: `Not acceptable, the Accept in the request header should be "text/event-stream". If you are using the "@milkio/stargate" package, please add \`type: "stream"\` to the execute options.` });
|
|
85
91
|
|
|
86
92
|
const executed = await executer.__call(routeSchema, {
|
|
@@ -95,6 +101,8 @@ export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
95
101
|
|
|
96
102
|
if (executed.results.value !== undefined) response.body = TSON.stringify({ success: true, data: executed.results.value, executeId } satisfies MilkioResponseSuccess<any>);
|
|
97
103
|
|
|
104
|
+
await runtime.emit("milkio:httpResponse", { executeId, logger, path: http.path.string as string, http, context: executed.context });
|
|
105
|
+
|
|
98
106
|
runtime.runtime.request.delete(executeId);
|
|
99
107
|
return new Response(response.body, response);
|
|
100
108
|
} else {
|
|
@@ -180,6 +188,8 @@ export const __initListener = <MilkioRuntime extends MilkioRuntimeInit<MilkioRun
|
|
|
180
188
|
response.headers["Content-Type"] = "text/event-stream";
|
|
181
189
|
response.headers["Cache-Control"] = "no-cache";
|
|
182
190
|
|
|
191
|
+
await runtime.emit("milkio:httpResponse", { executeId, logger, path: http.path.string as string, http, context: executed.context });
|
|
192
|
+
|
|
183
193
|
runtime.runtime.request.delete(executeId);
|
|
184
194
|
return new Response(response.body, response);
|
|
185
195
|
}
|
package/logger/index.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { TSON } from "@southern-aurora/tson";
|
|
2
1
|
import { format } from "date-fns";
|
|
3
|
-
import { type MilkioInit, type MilkioRuntimeInit } from "..";
|
|
2
|
+
import { type $context, type MilkioInit, type MilkioRuntimeInit } from "..";
|
|
3
|
+
import { sendCookbookEvent } from "../utils/send-cookbook-event";
|
|
4
4
|
|
|
5
|
-
export type Log = [
|
|
5
|
+
export type Log = ["[DEBUG]" | "[INFO]" | "[WARN]" | "[ERROR]" | "[REQUEST]" | "[RESPONSE]", string /* executeId */, string, string, string, ...Array<unknown>];
|
|
6
6
|
|
|
7
7
|
export type Logger = {
|
|
8
8
|
_: {
|
|
9
9
|
logs: Array<Log>;
|
|
10
10
|
tags: Map<string, unknown>;
|
|
11
|
+
submit: (context: $context) => Promise<void> | void;
|
|
11
12
|
};
|
|
12
13
|
setTag: (key: string, value: unknown) => void;
|
|
13
14
|
setLog: (...log: Log) => void;
|
|
@@ -15,53 +16,63 @@ export type Logger = {
|
|
|
15
16
|
info: (description: string, ...params: Array<unknown>) => Log;
|
|
16
17
|
warn: (description: string, ...params: Array<unknown>) => Log;
|
|
17
18
|
error: (description: string, ...params: Array<unknown>) => Log;
|
|
19
|
+
request: (description: string, ...params: Array<unknown>) => Log;
|
|
20
|
+
response: (description: string, ...params: Array<unknown>) => Log;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
|
-
export
|
|
23
|
+
export type LoggerInsertingHandler = (log: Log) => boolean;
|
|
24
|
+
|
|
25
|
+
export type LoggerSubmittingHandler = (context: $context, logs: Array<Log>, tags: Map<string, unknown>) => Promise<void> | void;
|
|
26
|
+
|
|
27
|
+
export const createLogger = <MilkioRuntime extends MilkioRuntimeInit<MilkioRuntimeInit<MilkioInit>> = MilkioRuntimeInit<MilkioInit>>(runtime: MilkioRuntime, path: string, executeId: string): Logger => {
|
|
21
28
|
const logger = {} as Logger;
|
|
22
29
|
|
|
23
30
|
logger._ = {
|
|
24
31
|
logs: new Array(),
|
|
25
32
|
tags: new Map(),
|
|
33
|
+
submit: (context: $context) => {
|
|
34
|
+
if (!runtime.onLoggerSubmitting) return;
|
|
35
|
+
return runtime.onLoggerSubmitting(context, logger._.logs, logger._.tags);
|
|
36
|
+
},
|
|
26
37
|
};
|
|
27
38
|
|
|
28
39
|
const __tagPush = (key: string, value: unknown): void => {
|
|
29
40
|
logger._.tags.set(key, value);
|
|
30
41
|
};
|
|
31
42
|
const __logPush = (log: Log): Log => {
|
|
43
|
+
const inserting = runtime.onLoggerInserting
|
|
44
|
+
? runtime.onLoggerInserting
|
|
45
|
+
: (log: Log) => {
|
|
46
|
+
log = [...log];
|
|
47
|
+
log[0] = `\n${log[0]}` as any;
|
|
48
|
+
console.log(...log);
|
|
49
|
+
return true;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
if (!inserting(log)) return log;
|
|
53
|
+
|
|
32
54
|
logger._.logs.push([...log]);
|
|
33
|
-
if (runtime.
|
|
34
|
-
void (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
headers: {
|
|
39
|
-
"Content-Type": "application/json",
|
|
40
|
-
},
|
|
41
|
-
body: TSON.stringify({
|
|
42
|
-
type: "milkio@logger",
|
|
43
|
-
log: log,
|
|
44
|
-
}),
|
|
45
|
-
});
|
|
46
|
-
if (!response.ok) console.log("[COOKBOOK]", await response.text());
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.log("[COOKBOOK]", error);
|
|
49
|
-
}
|
|
50
|
-
})();
|
|
55
|
+
if (runtime.cookbook) {
|
|
56
|
+
void sendCookbookEvent(runtime, {
|
|
57
|
+
type: "milkio@logger",
|
|
58
|
+
log: log,
|
|
59
|
+
});
|
|
51
60
|
}
|
|
52
|
-
|
|
61
|
+
|
|
53
62
|
return log;
|
|
54
63
|
};
|
|
55
64
|
|
|
56
65
|
logger.setTag = (key: string, value: unknown) => __tagPush(key, value);
|
|
57
66
|
logger.setLog = (...log: Log) => __logPush(log);
|
|
58
67
|
|
|
59
|
-
const getNow = () => format(new Date(), "(yyyy-MM-dd hh:mm:ss)")
|
|
68
|
+
const getNow = () => `${format(new Date(), "(yyyy-MM-dd hh:mm:ss)")}`;
|
|
60
69
|
|
|
61
|
-
logger.debug = (description: string, ...params: Array<unknown>) => __logPush([
|
|
62
|
-
logger.info = (description: string, ...params: Array<unknown>) => __logPush([
|
|
63
|
-
logger.warn = (description: string, ...params: Array<unknown>) => __logPush([
|
|
64
|
-
logger.error = (description: string, ...params: Array<unknown>) => __logPush([
|
|
70
|
+
logger.debug = (description: string, ...params: Array<unknown>) => __logPush(["[DEBUG]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
71
|
+
logger.info = (description: string, ...params: Array<unknown>) => __logPush(["[INFO]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
72
|
+
logger.warn = (description: string, ...params: Array<unknown>) => __logPush(["[WARN]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
73
|
+
logger.error = (description: string, ...params: Array<unknown>) => __logPush(["[ERROR]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
74
|
+
logger.request = (description: string, ...params: Array<unknown>) => __logPush(["[REQUEST]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
75
|
+
logger.response = (description: string, ...params: Array<unknown>) => __logPush(["[RESPONSE]", path, executeId, getNow(), `\n${description}`, ...params]);
|
|
65
76
|
|
|
66
77
|
return logger;
|
|
67
78
|
};
|
package/meta/index.ts
CHANGED
package/package.json
CHANGED
package/step/index.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToEmptyObject } from "..";
|
|
2
|
+
|
|
3
|
+
export type Steps<StageT extends Record<any, any>> = {
|
|
4
|
+
step: StepFunction<StageT>;
|
|
5
|
+
run: () => Promise<Remove_<StageT>>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type Remove_<T> = {
|
|
9
|
+
[K in keyof T as K extends `_${string}` ? never : K]: T[K];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type StepFunction<StageT extends Record<any, any>> = <HandlerT extends (stage: Readonly<StageT>) => Record<any, any> | Promise<Record<any, any>>>(handler: HandlerT) => Steps<Awaited<StageT> & ToEmptyObject<Awaited<ReturnType<HandlerT>>>>;
|
|
13
|
+
|
|
14
|
+
export const createStep = (): Steps<{}>["step"] => {
|
|
15
|
+
const stepController = {
|
|
16
|
+
$milkioType: "step",
|
|
17
|
+
_steps: [] as Array<(stage: any) => Promise<any>>,
|
|
18
|
+
step(handler: (stage: any) => Promise<any>) {
|
|
19
|
+
stepController._steps.push(handler);
|
|
20
|
+
return stepController;
|
|
21
|
+
},
|
|
22
|
+
async run() {
|
|
23
|
+
let stage = {};
|
|
24
|
+
for (const step of stepController._steps) {
|
|
25
|
+
stage = { ...stage, ...(await step(stage)) };
|
|
26
|
+
}
|
|
27
|
+
let result: Record<any, any> = {};
|
|
28
|
+
for (const key in stage) {
|
|
29
|
+
const value = (stage as any)[key];
|
|
30
|
+
if (!key.startsWith("_")) result[key] = value;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
return stepController.step as any as Steps<{}>["step"];
|
|
36
|
+
};
|
package/stream/index.ts
CHANGED
|
File without changes
|
package/types/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type Mixin<T, U> = U & Omit<T, keyof U>;
|
|
|
10
10
|
|
|
11
11
|
export type GeneratorGeneric<T> = T extends AsyncGenerator<infer I> ? I : never;
|
|
12
12
|
|
|
13
|
+
export type ToEmptyObject<T> = T extends undefined | null | never ? {} : T extends object ? T : {};
|
|
14
|
+
|
|
13
15
|
export type ExecuteId = string | "global";
|
|
14
16
|
|
|
15
17
|
// DON'T TRY TO WRITE A MORE DETAILED TYPE FOR THIS TYPE
|
package/utils/create-id.ts
CHANGED
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Log, MilkioInit, MilkioRuntimeInit } from "..";
|
|
2
|
+
import { TSON } from "@southern-aurora/tson";
|
|
3
|
+
|
|
4
|
+
type CookbookEvent = {
|
|
5
|
+
type: "milkio@logger";
|
|
6
|
+
log: Log;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const sendCookbookEvent = async (runtime: MilkioRuntimeInit<MilkioInit>, event: CookbookEvent) => {
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(`http://localhost:${runtime.cookbook.cookbookPort}/$action`, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
headers: {
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
},
|
|
16
|
+
body: TSON.stringify(event),
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
console.log("[COOKBOOK]", await response.text());
|
|
20
|
+
console.log("[COOKBOOK]", "Is Cookbook closed? There is an abnormality in the communication with Cookbook.");
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.log("[COOKBOOK]", error);
|
|
24
|
+
console.log("[COOKBOOK]", "Is Cookbook closed? There is an abnormality in the communication with Cookbook.");
|
|
25
|
+
}
|
|
26
|
+
};
|
package/world/index.ts
CHANGED
|
@@ -1,41 +1,53 @@
|
|
|
1
|
-
import { __initCommander, __initListener, ExecuteId, type Logger, type Mixin, type GeneratedInit,
|
|
2
|
-
import { __initExecuter } from "../execute";
|
|
1
|
+
import { __initCommander, __initListener, __initExecuter, __initEventManager, type ExecuteId, type Logger, type Mixin, type GeneratedInit, type Execute, type Ping, type ContextCreatedHandler, LoggerSubmittingHandler, LoggerInsertingHandler } from "..";
|
|
3
2
|
import { defineDefaultExecuteIdGenerator } from "../execute/execute-id-generator";
|
|
4
3
|
|
|
5
4
|
export type MilkioInit = {
|
|
6
|
-
port:
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
port: number;
|
|
6
|
+
develop: boolean;
|
|
7
|
+
cookbook: {
|
|
8
|
+
cookbookPort: number;
|
|
9
|
+
};
|
|
10
|
+
cors?: {
|
|
11
|
+
corsAllowMethods?: string;
|
|
12
|
+
corsAllowHeaders?: string;
|
|
13
|
+
corsAllowOrigin?: string;
|
|
9
14
|
};
|
|
10
|
-
getRealIp?: (request: Request) => string;
|
|
11
|
-
executeIdGenerator?: (request: Request) => string | Promise<string>;
|
|
12
|
-
corsAllowMethods?: string;
|
|
13
|
-
corsAllowHeaders?: string;
|
|
14
|
-
corsAllowOrigin?: string;
|
|
15
15
|
ignorePathLevel?: number;
|
|
16
|
+
realIp?: (request: Request) => string;
|
|
17
|
+
executeId?: (request: Request) => string | Promise<string>;
|
|
18
|
+
onLoggerSubmitting?: LoggerSubmittingHandler;
|
|
19
|
+
onLoggerInserting?: LoggerInsertingHandler;
|
|
16
20
|
};
|
|
17
21
|
|
|
18
22
|
export type MilkioRuntimeInit<T extends MilkioInit> = Mixin<
|
|
19
23
|
T,
|
|
20
24
|
{
|
|
21
|
-
|
|
25
|
+
executeId: (request: Request) => string | Promise<string>;
|
|
22
26
|
runtime: {
|
|
23
27
|
request: Map<ExecuteId, { logger: Logger }>;
|
|
24
28
|
};
|
|
29
|
+
on: Awaited<ReturnType<typeof __initEventManager>>["on"];
|
|
30
|
+
off: Awaited<ReturnType<typeof __initEventManager>>["off"];
|
|
31
|
+
emit: Awaited<ReturnType<typeof __initEventManager>>["emit"];
|
|
25
32
|
}
|
|
26
33
|
>;
|
|
27
34
|
|
|
28
|
-
export const createWorld = async <
|
|
29
|
-
const
|
|
35
|
+
export const createWorld = async <MilkioOptions extends MilkioInit>(generated: GeneratedInit, options: MilkioOptions): Promise<MilkioWorld<MilkioOptions>> => {
|
|
36
|
+
const executeId = options.executeId ?? defineDefaultExecuteIdGenerator();
|
|
30
37
|
|
|
31
38
|
const runtime = {
|
|
32
39
|
request: new Map(),
|
|
33
|
-
} as MilkioRuntimeInit<
|
|
40
|
+
} as MilkioRuntimeInit<MilkioOptions>["runtime"];
|
|
41
|
+
|
|
42
|
+
const eventManager = __initEventManager();
|
|
34
43
|
|
|
35
|
-
const _: MilkioRuntimeInit<
|
|
44
|
+
const _: MilkioRuntimeInit<MilkioOptions> = {
|
|
36
45
|
...options,
|
|
37
|
-
|
|
46
|
+
executeId,
|
|
38
47
|
runtime,
|
|
48
|
+
on: eventManager.on,
|
|
49
|
+
off: eventManager.off,
|
|
50
|
+
emit: eventManager.emit,
|
|
39
51
|
};
|
|
40
52
|
|
|
41
53
|
const executer = __initExecuter(generated, _);
|
|
@@ -45,21 +57,35 @@ export const createWorld = async <CookbookOptions extends MilkioInit>(generated:
|
|
|
45
57
|
// Initialize the app
|
|
46
58
|
const app = {
|
|
47
59
|
_: _,
|
|
60
|
+
// event manager
|
|
61
|
+
on: eventManager.on,
|
|
62
|
+
off: eventManager.off,
|
|
63
|
+
emit: eventManager.emit,
|
|
64
|
+
// executer
|
|
48
65
|
_executer: executer,
|
|
49
66
|
execute: executer.execute,
|
|
50
67
|
ping: executer.ping,
|
|
68
|
+
// commander
|
|
51
69
|
commander,
|
|
70
|
+
// listener
|
|
52
71
|
listener,
|
|
53
72
|
};
|
|
54
73
|
|
|
55
|
-
return app as MilkioWorld<
|
|
74
|
+
return app as MilkioWorld<MilkioOptions>;
|
|
56
75
|
};
|
|
57
76
|
|
|
58
|
-
export type MilkioWorld<
|
|
59
|
-
_: MilkioRuntimeInit<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
export type MilkioWorld<MilkioOptions extends MilkioInit = MilkioInit> = {
|
|
78
|
+
_: MilkioRuntimeInit<MilkioOptions>;
|
|
79
|
+
// event manager
|
|
80
|
+
on: Awaited<ReturnType<typeof __initEventManager>>["on"];
|
|
81
|
+
off: Awaited<ReturnType<typeof __initEventManager>>["off"];
|
|
82
|
+
emit: Awaited<ReturnType<typeof __initEventManager>>["emit"];
|
|
83
|
+
// executer
|
|
84
|
+
_executer: Awaited<ReturnType<typeof __initExecuter<MilkioRuntimeInit<MilkioOptions>>>>;
|
|
63
85
|
execute: Execute;
|
|
64
86
|
ping: (options?: { timeout?: number }) => Promise<Ping>;
|
|
87
|
+
// commander
|
|
88
|
+
commander: Awaited<ReturnType<typeof __initCommander<MilkioRuntimeInit<MilkioOptions>>>>;
|
|
89
|
+
// listener
|
|
90
|
+
listener: Awaited<ReturnType<typeof __initListener<MilkioRuntimeInit<MilkioOptions>>>>;
|
|
65
91
|
};
|
package/middleware/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type $context, type $meta } from "..";
|
|
2
|
-
|
|
3
|
-
export const middleware = <MiddlewareInitT extends MiddlewareInit>(init: MiddlewareInitT): Middleware<MiddlewareInitT> => {
|
|
4
|
-
const middleware = init as unknown as Middleware<MiddlewareInitT>;
|
|
5
|
-
middleware.$milkioType = "middleware";
|
|
6
|
-
if (middleware.meta === undefined) middleware.meta = {};
|
|
7
|
-
return middleware;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type MiddlewareInit = {
|
|
11
|
-
meta?: $meta;
|
|
12
|
-
handler: (context: $context, params: any) => Promise<unknown>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type Middleware<MiddlewareInitT extends MiddlewareInit> = {
|
|
16
|
-
$milkioType: "middleware";
|
|
17
|
-
meta: MiddlewareInitT["meta"] extends undefined ? {} : MiddlewareInitT["meta"];
|
|
18
|
-
handler: MiddlewareInitT["handler"];
|
|
19
|
-
};
|
package/test/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { type context, type meta } from "..";
|
|
2
|
-
|
|
3
|
-
export const test = <TestInitT extends TestInit>(init: TestInitT): Test<TestInitT> => {
|
|
4
|
-
const test = init as unknown as Test<TestInitT>;
|
|
5
|
-
test.$milkioType = "test";
|
|
6
|
-
if (test.name === undefined) test.name = {};
|
|
7
|
-
return test;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type TestInit = {
|
|
11
|
-
name: meta;
|
|
12
|
-
handler: (test: TestTools) => Promise<unknown>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type Test<TestInitT extends TestInit> = {
|
|
16
|
-
$milkioType: "test";
|
|
17
|
-
name: TestInitT["name"] extends undefined ? {} : TestInitT["name"];
|
|
18
|
-
handler: TestInitT["handler"];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type TestTools = {};
|