milkio 1.0.0-alpha.1 → 1.0.0-alpha.100
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 +2 -2
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/action/index.ts +14 -14
- package/bootstrap/index.ts +7 -0
- package/command/index.ts +41 -37
- package/config/index.ts +33 -0
- package/context/index.ts +23 -15
- package/event/index.ts +48 -0
- package/exception/index.ts +31 -28
- package/execute/execute-id-generator.ts +5 -5
- package/execute/index.ts +99 -124
- package/flow/index.ts +70 -0
- package/handler/index.ts +7 -0
- package/index.ts +19 -11
- package/listener/index.ts +205 -119
- package/logger/index.ts +62 -51
- package/meta/index.ts +2 -2
- package/package.json +7 -7
- package/step/index.ts +36 -0
- package/stream/index.ts +14 -14
- package/tsconfig.json +19 -18
- package/type-safety/index.ts +16 -0
- package/types/index.ts +46 -51
- package/utils/create-id.ts +10 -2
- package/utils/headers-to-json.ts +7 -0
- package/utils/send-cookbook-event.ts +27 -0
- package/utils/trie.ts +54 -0
- package/world/index.ts +81 -44
- package/.publish/publish.json +0 -7
- package/.publish/releases/0.0.0.md +0 -0
- package/.publish/releases/0.1.0.md +0 -13
- package/.publish/releases/0.2.0.md +0 -33
- package/.publish/releases/0.3.0.md +0 -85
- package/.publish/releases/0.4.0.md +0 -35
- package/.publish/releases/0.5.0.md +0 -19
- package/.publish/releases/0.6.0.md +0 -41
- package/.publish/releases/0.8.0.md +0 -128
- package/.publish/releases-github/0.0.0.md +0 -0
- package/.publish/releases-github/0.1.0.md +0 -13
- package/.publish/releases-github/0.2.0.md +0 -33
- package/.publish/releases-github/0.3.0.md +0 -85
- package/.publish/releases-github/0.4.0.md +0 -35
- package/.publish/releases-github/0.5.0.md +0 -19
- package/.publish/releases-github/0.6.0.md +0 -41
- package/.publish/releases-github/0.8.0.md +0 -126
- package/middleware/index.ts +0 -19
- package/test/index.ts +0 -21
package/.co.toml
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
[
|
|
2
|
-
includes = ["co:bun"]
|
|
1
|
+
[general]
|
|
2
|
+
includes = [ "co:bun" ]
|
package/LICENSE
CHANGED
package/README.md
CHANGED
package/action/index.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { $context, $meta } from '..'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
const action = init as unknown as Action<ActionInitT
|
|
5
|
-
action.$milkioType =
|
|
6
|
-
if (action.meta === undefined) action.meta = {}
|
|
7
|
-
return action
|
|
8
|
-
}
|
|
3
|
+
export function action<ActionInitT extends ActionInit>(init: ActionInitT): Action<ActionInitT> {
|
|
4
|
+
const action = init as unknown as Action<ActionInitT>
|
|
5
|
+
action.$milkioType = 'action'
|
|
6
|
+
if (action.meta === undefined) action.meta = {}
|
|
7
|
+
return action
|
|
8
|
+
}
|
|
9
9
|
|
|
10
10
|
export type ActionInit = {
|
|
11
|
-
meta?: $meta
|
|
12
|
-
handler: (context: $context, params: any) => Promise<unknown
|
|
13
|
-
}
|
|
11
|
+
meta?: $meta
|
|
12
|
+
handler: (context: $context, params: any) => Promise<unknown>
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
export type Action<ActionInitT extends ActionInit> = {
|
|
16
|
-
$milkioType:
|
|
17
|
-
meta: ActionInitT[
|
|
18
|
-
handler: ActionInitT[
|
|
19
|
-
}
|
|
16
|
+
$milkioType: 'action'
|
|
17
|
+
meta: ActionInitT['meta'] extends undefined ? {} : ActionInitT['meta']
|
|
18
|
+
handler: ActionInitT['handler']
|
|
19
|
+
}
|
package/command/index.ts
CHANGED
|
@@ -1,53 +1,57 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { GeneratedInit } from '..'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
const command = init as unknown as Command<CommandInitT
|
|
5
|
-
command.$milkioType =
|
|
6
|
-
return command
|
|
7
|
-
}
|
|
3
|
+
export function command<CommandInitT extends CommandInit>(init: CommandInitT): Command<CommandInitT> {
|
|
4
|
+
const command = init as unknown as Command<CommandInitT>
|
|
5
|
+
command.$milkioType = 'command'
|
|
6
|
+
return command
|
|
7
|
+
}
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
handler: (commands: Array<string>, options: Record<string, string>) => Promise<unknown
|
|
11
|
-
}
|
|
9
|
+
export interface CommandInit {
|
|
10
|
+
handler: (commands: Array<string>, options: Record<string, string>) => Promise<unknown>
|
|
11
|
+
}
|
|
12
12
|
|
|
13
|
-
export
|
|
14
|
-
$milkioType:
|
|
15
|
-
handler: CommandInitT[
|
|
16
|
-
}
|
|
13
|
+
export interface Command<CommandInitT extends CommandInit> {
|
|
14
|
+
$milkioType: 'command'
|
|
15
|
+
handler: CommandInitT['handler']
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
export
|
|
18
|
+
export function __initCommander(generated: GeneratedInit, runtime: any) {
|
|
19
19
|
const commander = async (argv: Array<string>, options?: { onNotFound?: () => any }) => {
|
|
20
20
|
const params = {
|
|
21
|
-
path:
|
|
21
|
+
path: 'index',
|
|
22
22
|
commands: [] as Array<string>,
|
|
23
23
|
options: {} as Record<string, string | true>,
|
|
24
|
-
}
|
|
24
|
+
}
|
|
25
25
|
for (const v of argv.slice(3)) {
|
|
26
|
-
if (v.startsWith(
|
|
27
|
-
const vSplited = v.split(
|
|
28
|
-
params.options[vSplited[0].slice(2)] = vSplited.slice(1, vSplited.length).join(
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
params.options[
|
|
36
|
-
}
|
|
37
|
-
|
|
26
|
+
if (v.startsWith('--') && v.includes('=')) {
|
|
27
|
+
const vSplited = v.split('=')
|
|
28
|
+
params.options[vSplited[0].slice(2)] = vSplited.slice(1, vSplited.length).join('=')
|
|
29
|
+
}
|
|
30
|
+
else if (v.startsWith('--')) {
|
|
31
|
+
params.options[v.slice(2)] = '1'
|
|
32
|
+
}
|
|
33
|
+
else if (v.startsWith('-') && v.includes('=')) {
|
|
34
|
+
const vSplited = v.split('=')
|
|
35
|
+
params.options[vSplited[0].slice(1)] = vSplited.slice(1, vSplited.length).join('=')
|
|
36
|
+
}
|
|
37
|
+
else if (v.startsWith('-')) {
|
|
38
|
+
params.options[v.slice(1)] = '1'
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
params.commands.push(v)
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
|
-
if (argv.length === 2) params.path = `index
|
|
41
|
-
else params.path = `${argv[2] ??
|
|
44
|
+
if (argv.length === 2) params.path = `index`
|
|
45
|
+
else params.path = `${argv[2] ?? 'index'}`
|
|
42
46
|
|
|
43
47
|
if (!(params.path in generated.commandSchema.commands)) {
|
|
44
|
-
if (options?.onNotFound) return await options.onNotFound()
|
|
45
|
-
console.log(`\x1B[44m UwU \x1B[0m \x1B[2mCommand not found:\x1B[0m \x1B[32m${params.path}\x1B[0m`)
|
|
46
|
-
return undefined
|
|
48
|
+
if (options?.onNotFound) return await options.onNotFound()
|
|
49
|
+
console.log(`\x1B[44m UwU \x1B[0m \x1B[2mCommand not found:\x1B[0m \x1B[32m${params.path}\x1B[0m`)
|
|
50
|
+
return undefined
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
return await generated.commandSchema.commands[params.path].module.handler(params.commands, params.options)
|
|
50
|
-
}
|
|
53
|
+
return await generated.commandSchema.commands[params.path].module.handler(params.commands, params.options)
|
|
54
|
+
}
|
|
51
55
|
|
|
52
|
-
return commander
|
|
53
|
-
}
|
|
56
|
+
return commander
|
|
57
|
+
}
|
package/config/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function config<ConfigT extends Config>(config: ConfigT): ConfigT {
|
|
2
|
+
return config
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type Config = (mode: string) => Promise<Record<string, unknown>> | Record<string, unknown>
|
|
6
|
+
|
|
7
|
+
export interface ConfigEnvironments<T extends Config> {
|
|
8
|
+
[key: string]: (env: Record<string, string>) => Partial<Awaited<ReturnType<T>>> | Promise<Partial<Awaited<ReturnType<T>>>>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function envToString(value: string | number | undefined, defaultValue: string) {
|
|
12
|
+
if (value === undefined) return defaultValue
|
|
13
|
+
|
|
14
|
+
return `${value}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function envToNumber(value: string | undefined, defaultValue: number) {
|
|
18
|
+
if (value === undefined) return defaultValue
|
|
19
|
+
|
|
20
|
+
return Number.parseInt(value, 10)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function envToBoolean(value: string | number | undefined, defaultValue: boolean) {
|
|
24
|
+
if (value === 'true') return true
|
|
25
|
+
|
|
26
|
+
if (value === 'false') return false
|
|
27
|
+
|
|
28
|
+
if (value === '') return false
|
|
29
|
+
|
|
30
|
+
if (undefined === value) return defaultValue
|
|
31
|
+
|
|
32
|
+
return Boolean(value)
|
|
33
|
+
}
|
package/context/index.ts
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { MilkioHttpRequest, MilkioHttpResponse, $types, Logger, Action, MilkioRuntimeInit, MilkioInit } from '..'
|
|
2
2
|
|
|
3
3
|
export interface $context {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
_: MilkioRuntimeInit<MilkioInit>
|
|
5
|
+
develop: boolean
|
|
6
|
+
executeId: string
|
|
7
|
+
emit: MilkioRuntimeInit<MilkioInit>['emit']
|
|
8
|
+
path: string
|
|
9
|
+
logger: Logger
|
|
10
|
+
http: ContextHttp<Record<any, any>>
|
|
11
|
+
config: Readonly<Awaited<ReturnType<$types['configSchema']['get']>>>
|
|
12
|
+
call: <Module extends Promise<{ default: Action<any> }>>(module: Module, params: Parameters<Awaited<Module>['default']['handler']>[1]) => Promise<ReturnType<Awaited<Module>['default']['handler']>>
|
|
13
|
+
onFinally: (handler: () => void | Promise<void>) => void
|
|
8
14
|
}
|
|
9
15
|
|
|
10
|
-
export
|
|
11
|
-
url: URL
|
|
12
|
-
ip: string
|
|
13
|
-
path: { string: keyof $types[
|
|
16
|
+
export interface ContextHttp<ParamsParsed = any> {
|
|
17
|
+
url: URL
|
|
18
|
+
ip: string
|
|
19
|
+
path: { string: keyof $types['generated']['routeSchema'], array: Array<string> }
|
|
14
20
|
params: {
|
|
15
|
-
string: string
|
|
16
|
-
parsed: ParamsParsed
|
|
17
|
-
}
|
|
18
|
-
request: MilkioHttpRequest
|
|
19
|
-
response: MilkioHttpResponse
|
|
20
|
-
}
|
|
21
|
+
string: string
|
|
22
|
+
parsed: ParamsParsed
|
|
23
|
+
}
|
|
24
|
+
request: MilkioHttpRequest
|
|
25
|
+
response: MilkioHttpResponse
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ContextCreatedHandler = (context: $context) => Promise<void> | void
|
package/event/index.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { $context, ContextHttp, Results, Logger, $meta } from '..'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export interface $events {
|
|
5
|
+
'milkio:httpRequest': { executeId: string, path: string, logger: Logger, http: ContextHttp<Record<string, any>> }
|
|
6
|
+
'milkio:httpResponse': { executeId: string, path: string, logger: Logger, http: ContextHttp<Record<string, any>>, context: $context }
|
|
7
|
+
'milkio:httpNotFound': { executeId: string, path: string, logger: Logger, http: ContextHttp<Record<string, any>> }
|
|
8
|
+
'milkio:executeBefore': { executeId: string, path: string, logger: Logger, meta: $meta, context: $context }
|
|
9
|
+
'milkio:executeAfter': { executeId: string, path: string, logger: Logger, meta: $meta, context: $context, results: Results<any> }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function __initEventManager() {
|
|
13
|
+
const handlers = new Map<(event: any) => void, string>()
|
|
14
|
+
const indexed = new Map<string, Set<(event: any) => void>>()
|
|
15
|
+
|
|
16
|
+
const eventManager = {
|
|
17
|
+
on: <Key extends keyof $events, Handler extends (event: $events[Key]) => void>(key: Key, handler: Handler) => {
|
|
18
|
+
handlers.set(handler, key as string)
|
|
19
|
+
if (indexed.has(key as string) === false) {
|
|
20
|
+
indexed.set(key as string, new Set())
|
|
21
|
+
}
|
|
22
|
+
const set = indexed.get(key as string)!
|
|
23
|
+
set.add(handler)
|
|
24
|
+
handlers.set(handler, key as string)
|
|
25
|
+
|
|
26
|
+
return () => {
|
|
27
|
+
handlers.delete(handler)
|
|
28
|
+
set.delete(handler)
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
off: <Key extends keyof $events, Handler extends (event: $events[Key]) => void>(key: Key, handler: Handler) => {
|
|
32
|
+
const set = indexed.get(key as string)
|
|
33
|
+
if (!set) return
|
|
34
|
+
handlers.delete(handler)
|
|
35
|
+
set.delete(handler)
|
|
36
|
+
},
|
|
37
|
+
emit: async <Key extends keyof $events, Value extends $events[Key]>(key: Key, value: Value): Promise<void> => {
|
|
38
|
+
const h = indexed.get(key as string)
|
|
39
|
+
if (h) {
|
|
40
|
+
for (const handler of h) {
|
|
41
|
+
await handler(value)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return eventManager
|
|
48
|
+
}
|
package/exception/index.ts
CHANGED
|
@@ -1,45 +1,48 @@
|
|
|
1
|
-
import { TSON } from
|
|
2
|
-
import {
|
|
1
|
+
import { TSON } from '@southern-aurora/tson'
|
|
2
|
+
import type { MilkioResponseReject, Logger } from '..'
|
|
3
3
|
|
|
4
4
|
export interface $rejectCode {
|
|
5
|
-
FAIL: string
|
|
6
|
-
REQUEST_FAIL: any
|
|
7
|
-
NOT_DEVELOP_MODE: string
|
|
8
|
-
REQUEST_TIMEOUT: { timeout: number
|
|
9
|
-
NOT_FOUND: { path: string }
|
|
10
|
-
PARAMS_TYPE_INCORRECT: { path: string
|
|
11
|
-
RESULTS_TYPE_INCORRECT: { path: string
|
|
12
|
-
UNACCEPTABLE: { expected: string
|
|
13
|
-
PARAMS_TYPE_NOT_SUPPORTED: { expected: string }
|
|
14
|
-
|
|
5
|
+
FAIL: string
|
|
6
|
+
REQUEST_FAIL: any
|
|
7
|
+
NOT_DEVELOP_MODE: string
|
|
8
|
+
REQUEST_TIMEOUT: { timeout: number, message: string }
|
|
9
|
+
NOT_FOUND: { path: string }
|
|
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
|
+
UNACCEPTABLE: { expected: string, message: string }
|
|
13
|
+
PARAMS_TYPE_NOT_SUPPORTED: { expected: string }
|
|
14
|
+
RESULTS_TYPE_NOT_SUPPORTED: { expected: string }
|
|
15
|
+
INTERNAL_SERVER_ERROR: undefined
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export function reject<Code extends keyof $rejectCode, RejectData extends $rejectCode[Code]>(code: Code, data: RejectData): MilkioRejectError<Code, RejectData> {
|
|
18
|
-
const error = { $milkioReject: true, code
|
|
19
|
-
Error.captureStackTrace(error)
|
|
20
|
-
return error
|
|
19
|
+
const error = { $milkioReject: true, code, data } as MilkioRejectError<Code, RejectData>
|
|
20
|
+
Error.captureStackTrace(error)
|
|
21
|
+
return error
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export type MilkioRejectError<Code extends keyof $rejectCode = keyof $rejectCode, RejectData extends $rejectCode[Code] = $rejectCode[Code]> = { code: Code
|
|
24
|
+
export type MilkioRejectError<Code extends keyof $rejectCode = keyof $rejectCode, RejectData extends $rejectCode[Code] = $rejectCode[Code]> = { code: Code, data: RejectData, stack: string, $milkioReject: true }
|
|
24
25
|
|
|
25
26
|
export function exceptionHandler(executeId: string, logger: Logger, error: MilkioRejectError<any, any> | any): MilkioResponseReject {
|
|
26
|
-
const name = error?.code ?? error?.name ?? error?.constructor?.name ??
|
|
27
|
+
const name = error?.code ?? error?.name ?? error?.constructor?.name ?? 'Unnamed Exception'
|
|
27
28
|
|
|
28
|
-
if (error?.$milkioReject === true && error?.code ===
|
|
29
|
-
logger.info(name, error?.data?.path ??
|
|
30
|
-
}
|
|
29
|
+
if (error?.$milkioReject === true && error?.code === 'NOT_FOUND') {
|
|
30
|
+
logger.info(name, error?.data?.path ?? 'Unknown path')
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
31
33
|
try {
|
|
32
|
-
const stack = error?.$milkioReject ? (error?.stack ??
|
|
33
|
-
logger.error(name, `\n${TSON.stringify(error?.data)}`, `\n${stack}\n`)
|
|
34
|
-
}
|
|
35
|
-
|
|
34
|
+
const stack = error?.$milkioReject ? (error?.stack ?? '').split('\n').slice(2).join('\n') : error?.stack ?? ''
|
|
35
|
+
logger.error(name, `\n${TSON.stringify(error?.data)}`, `\n${stack}\n`)
|
|
36
|
+
}
|
|
37
|
+
catch (_) {
|
|
38
|
+
logger.error(name, `\n${error?.toString()}`, `\n${error?.stack}\n`)
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
|
|
39
|
-
let result: MilkioResponseReject
|
|
42
|
+
let result: MilkioResponseReject
|
|
40
43
|
|
|
41
|
-
if (error?.$milkioReject === true) result = { success: false, code: error.code, reject: error.data, executeId }
|
|
42
|
-
else result = { success: false, code:
|
|
44
|
+
if (error?.$milkioReject === true) result = { success: false, code: error.code, reject: error.data, executeId }
|
|
45
|
+
else result = { success: false, code: 'INTERNAL_SERVER_ERROR', reject: undefined, executeId }
|
|
43
46
|
|
|
44
|
-
return result
|
|
47
|
+
return result
|
|
45
48
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __createId } from '../utils/create-id'
|
|
2
2
|
|
|
3
|
-
export type ExecuteIdGenerator = (request?: Request) => string | Promise<string
|
|
3
|
+
export type ExecuteIdGenerator = (request?: Request) => string | Promise<string>
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
return
|
|
7
|
-
}
|
|
5
|
+
export function defineDefaultExecuteIdGenerator() {
|
|
6
|
+
return __createId
|
|
7
|
+
}
|
package/execute/index.ts
CHANGED
|
@@ -1,160 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { TSON } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const __initExecuter = <MilkioRuntime extends MilkioRuntimeInit<MilkioRuntimeInit<MilkioInit>> = MilkioRuntimeInit<MilkioInit>>(generated: GeneratedInit, runtime: MilkioRuntime) => {
|
|
11
|
-
const __call = async (
|
|
1
|
+
import type { IValidation } from 'typia'
|
|
2
|
+
import { TSON } from '@southern-aurora/tson'
|
|
3
|
+
import { reject } from '..'
|
|
4
|
+
import type { $context, $meta, Logger, Results, GeneratedInit } from '..'
|
|
5
|
+
import { headersToJSON } from '../utils/headers-to-json'
|
|
6
|
+
|
|
7
|
+
export function __initExecuter(generated: GeneratedInit, runtime: any) {
|
|
8
|
+
const __execute = async (
|
|
12
9
|
routeSchema: any,
|
|
13
10
|
options: {
|
|
14
|
-
createdExecuteId: string
|
|
15
|
-
createdLogger: Logger
|
|
16
|
-
path: string
|
|
17
|
-
headers: Record<string, string> | Headers
|
|
18
|
-
mixinContext: Record<any, any> | undefined
|
|
11
|
+
createdExecuteId: string
|
|
12
|
+
createdLogger: Logger
|
|
13
|
+
path: string
|
|
14
|
+
headers: Record<string, string> | Headers
|
|
15
|
+
mixinContext: Record<any, any> | undefined
|
|
19
16
|
} & (
|
|
20
17
|
| {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
params: Record<any, any>
|
|
19
|
+
paramsType: 'raw'
|
|
20
|
+
}
|
|
24
21
|
| {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
params: string
|
|
23
|
+
paramsType: 'string'
|
|
24
|
+
}
|
|
28
25
|
),
|
|
29
|
-
): Promise<{ executeId: string
|
|
30
|
-
const executeId = options.createdExecuteId
|
|
31
|
-
let headers: Headers
|
|
26
|
+
): Promise<{ executeId: string, headers: Headers, params: Record<any, unknown>, results: Results<any>, context: $context, meta: Readonly<$meta>, type: 'action' | 'stream', emptyResult: boolean, resultsTypeSafety: boolean, finales: Array<() => void | Promise<void>> }> => {
|
|
27
|
+
const executeId: string = options.createdExecuteId
|
|
28
|
+
let headers: Headers
|
|
32
29
|
if (!(options.headers instanceof Headers)) {
|
|
33
30
|
// @ts-ignore
|
|
34
31
|
headers = new Headers({
|
|
35
32
|
...options.headers,
|
|
36
|
-
})
|
|
37
|
-
} else {
|
|
38
|
-
headers = options.headers;
|
|
33
|
+
})
|
|
39
34
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
else {
|
|
36
|
+
headers = options.headers
|
|
37
|
+
}
|
|
38
|
+
if (!('toJSON' in headers)) (headers as any).toJSON = () => headersToJSON(headers)
|
|
39
|
+
|
|
40
|
+
const finales: Array<any> = []
|
|
41
|
+
const onFinally = (handler: any) => finales.unshift(handler)
|
|
42
|
+
|
|
43
|
+
let params: Record<any, unknown>
|
|
44
|
+
if (options.paramsType === 'raw') {
|
|
45
|
+
params = options.params
|
|
46
|
+
if (typeof params === 'undefined') params = {}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
if (options.params === '') {
|
|
50
|
+
params = {}
|
|
51
|
+
}
|
|
47
52
|
else {
|
|
48
53
|
try {
|
|
49
|
-
params = TSON.parse(options.params)
|
|
50
|
-
} catch (error) {
|
|
51
|
-
throw reject("PARAMS_TYPE_NOT_SUPPORTED", { expected: "json" });
|
|
54
|
+
params = TSON.parse(options.params)
|
|
52
55
|
}
|
|
53
|
-
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw reject('PARAMS_TYPE_NOT_SUPPORTED', { expected: 'json' })
|
|
58
|
+
}
|
|
59
|
+
if (typeof params === 'undefined') params = {}
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
|
-
if (typeof params !==
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
if (typeof params !== 'object' || Array.isArray(params)) throw reject('PARAMS_TYPE_NOT_SUPPORTED', { expected: 'json' })
|
|
63
|
+
if ('$milkioGenerateParams' in params && params.$milkioGenerateParams === 'enable') {
|
|
64
|
+
if (!runtime.develop) throw reject('NOT_DEVELOP_MODE', 'This feature must be in cookbook to use.')
|
|
65
|
+
delete params.$milkioGenerateParams
|
|
66
|
+
let paramsRand = routeSchema.randomParams()
|
|
67
|
+
if (paramsRand === undefined || paramsRand === null) paramsRand = {}
|
|
68
|
+
params = { ...paramsRand, ...params }
|
|
63
69
|
}
|
|
64
|
-
if (options.mixinContext?.http?.params?.string) options.mixinContext.http.params.parsed = params
|
|
70
|
+
if (options.mixinContext?.http?.params?.string) options.mixinContext.http.params.parsed = params // listen でパースしたパラメータを渡す
|
|
65
71
|
const context = {
|
|
66
72
|
...(options.mixinContext ? options.mixinContext : {}),
|
|
73
|
+
develop: runtime.develop,
|
|
67
74
|
path: options.path,
|
|
68
75
|
logger: options.createdLogger,
|
|
76
|
+
emit: runtime.emit,
|
|
69
77
|
executeId: options.createdExecuteId,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
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.` });
|
|
78
|
+
config: runtime.runtime.config,
|
|
79
|
+
call: (module: any, options: any) => __call(context, module, options),
|
|
80
|
+
onFinally: onFinally,
|
|
81
|
+
_: runtime
|
|
82
|
+
} as unknown as $context
|
|
83
|
+
const results: Results<any> = { value: undefined }
|
|
84
|
+
|
|
85
|
+
if (runtime.develop) {
|
|
86
|
+
options.createdLogger.request(`headers - ${TSON.stringify(headers.toJSON())}`, `\nparams - ${TSON.stringify(params)}`)
|
|
80
87
|
}
|
|
81
88
|
|
|
82
|
-
|
|
89
|
+
const module = routeSchema.module
|
|
90
|
+
const meta = (module.default?.meta ? module.default?.meta : {}) as unknown as Readonly<$meta>
|
|
83
91
|
|
|
84
|
-
if (
|
|
85
|
-
const validation = routeSchema.
|
|
86
|
-
if (!validation.success) throw reject(
|
|
92
|
+
if (meta.typeSafety === undefined || meta.typeSafety === true) {
|
|
93
|
+
const validation = routeSchema.validateParams(params) as IValidation<any>
|
|
94
|
+
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.` })
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const execute = async (path: string, options?: ExecuteOptions): Promise<any> => {
|
|
93
|
-
if (!options) options = {};
|
|
94
|
-
const executeId = createId();
|
|
95
|
-
const logger = createLogger(runtime, executeId);
|
|
96
|
-
runtime.runtime.request.set(executeId, { logger: logger });
|
|
97
|
+
await runtime.emit('milkio:executeBefore', { executeId: options.createdExecuteId, logger: options.createdLogger, path: options.path, meta, context })
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
const routeSchema = generated.routeSchema.routes.get(path);
|
|
100
|
-
if (routeSchema === undefined) throw reject("NOT_FOUND", { path: path });
|
|
99
|
+
results.value = await module.default.handler(context, params)
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
paramsType: "raw",
|
|
110
|
-
});
|
|
101
|
+
let resultsTypeSafety = false
|
|
102
|
+
if (results?.value?.$milkioType === 'type-safety') {
|
|
103
|
+
resultsTypeSafety = true
|
|
104
|
+
const validation = routeSchema.validateResults(results.value.value) as IValidation<any>
|
|
105
|
+
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.` })
|
|
106
|
+
results.value = results.value.value
|
|
107
|
+
}
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const reject = exceptionHandler(executeId, logger, error);
|
|
124
|
-
const result: any = {};
|
|
125
|
-
result[reject.code] = reject.reject;
|
|
109
|
+
let emptyResult = false
|
|
110
|
+
if (results.value === undefined || results.value === null || results.value === '') {
|
|
111
|
+
emptyResult = true
|
|
112
|
+
results.value = {}
|
|
113
|
+
}
|
|
114
|
+
else if (Array.isArray(results.value)) {
|
|
115
|
+
throw reject('FAIL', 'The return type of the handler must be an object, which is currently an array.')
|
|
116
|
+
}
|
|
117
|
+
else if (typeof results.value !== 'object') {
|
|
118
|
+
throw reject('FAIL', 'The return type of the handler must be an object, which is currently a primitive type.')
|
|
119
|
+
}
|
|
126
120
|
|
|
127
|
-
|
|
128
|
-
return undefined;
|
|
129
|
-
}
|
|
130
|
-
})(),
|
|
131
|
-
{ executeId: executeId },
|
|
132
|
-
];
|
|
133
|
-
} else {
|
|
134
|
-
// action
|
|
135
|
-
return [null, executed.results.value, { executeId: executeId }];
|
|
136
|
-
}
|
|
137
|
-
} catch (error) {
|
|
138
|
-
const reject = exceptionHandler(executeId, logger, error);
|
|
139
|
-
const result: any = {};
|
|
140
|
-
result[reject.code] = reject.reject;
|
|
121
|
+
await runtime.emit('milkio:executeAfter', { executeId: options.createdExecuteId, logger: options.createdLogger, path: options.path, meta, context, results })
|
|
141
122
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
};
|
|
123
|
+
return { executeId, headers, params, results, context, meta, type: module.$milkioType, emptyResult, resultsTypeSafety, finales }
|
|
124
|
+
}
|
|
145
125
|
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
delay: 0,
|
|
151
|
-
serverTimestamp: Date.now(),
|
|
152
|
-
},
|
|
153
|
-
];
|
|
126
|
+
const __call = async (context: $context, module: { default: any }, params?: any): Promise<any> => {
|
|
127
|
+
const moduleAwaited = await module
|
|
128
|
+
return await moduleAwaited.default.handler(context, params)
|
|
129
|
+
}
|
|
154
130
|
|
|
155
131
|
return {
|
|
156
132
|
__call,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
};
|
|
133
|
+
__execute,
|
|
134
|
+
}
|
|
135
|
+
}
|