milkio 0.1.2 → 0.2.0
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 -65
- package/c.ts +37 -35
- package/defines/define-api-test.ts +24 -17
- package/defines/define-api.ts +9 -9
- package/defines/define-command-handler.ts +41 -41
- package/defines/define-http-handler.ts +181 -181
- package/defines/define-middleware.ts +6 -6
- package/defines/define-use.ts +10 -10
- package/index.ts +22 -22
- package/kernel/context.ts +17 -17
- package/kernel/fail.ts +13 -13
- package/kernel/logger.ts +96 -96
- package/kernel/meta.ts +6 -6
- package/kernel/middleware.ts +32 -32
- package/kernel/milkio.ts +250 -224
- package/kernel/runtime.ts +9 -9
- package/kernel/validate.ts +9 -9
- package/package.json +1 -1
- package/scripts/gen-insignificant.ts +239 -239
- package/scripts/gen-significant.ts +118 -120
- 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,194 +1,194 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import { loggerPushTags, loggerSubmit, useLogger, runtime, MiddlewareEvent } from ".."
|
|
3
|
-
import type { ExecuteId, MilkioApp, Mixin } from ".."
|
|
4
|
-
import { hanldeCatchError } from "../utils/handle-catch-error"
|
|
5
|
-
import { routerHandler } from "../../../src/router"
|
|
6
|
-
import schema from "../../../generated/api-schema"
|
|
7
|
-
import { failCode } from "../../../src/fail-code"
|
|
8
|
-
import { TSON } from "@southern-aurora/tson"
|
|
9
|
-
import { createUlid } from "../utils/create-ulid"
|
|
10
|
-
import { configMilkio } from "../../../src/config/milkio"
|
|
11
|
-
import { headerToPlainObject } from "../utils/header-to-plain-object"
|
|
2
|
+
import { loggerPushTags, loggerSubmit, useLogger, runtime, MiddlewareEvent } from "..";
|
|
3
|
+
import type { ExecuteId, MilkioApp, Mixin } from "..";
|
|
4
|
+
import { hanldeCatchError } from "../utils/handle-catch-error";
|
|
5
|
+
import { routerHandler } from "../../../src/router";
|
|
6
|
+
import schema from "../../../generated/api-schema";
|
|
7
|
+
import { failCode } from "../../../src/fail-code";
|
|
8
|
+
import { TSON } from "@southern-aurora/tson";
|
|
9
|
+
import { createUlid } from "../utils/create-ulid";
|
|
10
|
+
import { configMilkio } from "../../../src/config/milkio";
|
|
11
|
+
import { headerToPlainObject } from "../utils/header-to-plain-object";
|
|
12
12
|
|
|
13
13
|
export type ExecuteHttpServerOptions = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The execution ID generator
|
|
16
|
+
* If you have enabled this option, the executeId will be generated each time by calling this method. Otherwise, it will be generated using the built-in method.
|
|
17
|
+
*
|
|
18
|
+
* @param request
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
executeIdGenerator?: (request: Request) => string | Promise<string>;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
export function defineHttpHandler(app: MilkioApp, options: ExecuteHttpServerOptions = {}) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
25
|
+
const fetch = async (request: MilkioHTTPRequest) => {
|
|
26
|
+
const fullurl = new URL(request.request.url, `http://${request.request.headers.get("host") ?? "localhost"}`);
|
|
27
|
+
const executeId = (options?.executeIdGenerator ? await options.executeIdGenerator(request.request) : createUlid()) as ExecuteId;
|
|
28
|
+
runtime.execute.executeIds.add(executeId);
|
|
29
|
+
const logger = useLogger(executeId);
|
|
30
|
+
const ip = (request.request.headers.get("x-forwarded-for") as string | undefined)?.split(",")[0] ?? "0.0.0.0";
|
|
31
|
+
const headers = request.request.headers;
|
|
32
|
+
|
|
33
|
+
loggerPushTags(executeId, {
|
|
34
|
+
from: "http-server",
|
|
35
|
+
fullUrl: fullurl.pathname,
|
|
36
|
+
ip,
|
|
37
|
+
method: request.request.method,
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
requestHeaders: headerToPlainObject(request.request.headers),
|
|
40
|
+
timein: new Date().getTime(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const response: MilkioHTTPResponse = {
|
|
44
|
+
body: "",
|
|
45
|
+
status: 200,
|
|
46
|
+
headers: {
|
|
47
|
+
"Content-Type": "application/json",
|
|
48
|
+
"Access-Control-Allow-Methods": configMilkio.corsAllowMethods ?? "*",
|
|
49
|
+
"Access-Control-Allow-Headers": configMilkio.corsAllowHeaders ?? "*",
|
|
50
|
+
"Access-Control-Allow-Origin": configMilkio.corsAllowOrigin ?? "*",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// Process OPTIONS pre inspection requests
|
|
56
|
+
if (request.request.method === "OPTIONS") {
|
|
57
|
+
await loggerSubmit(executeId);
|
|
58
|
+
runtime.execute.executeIds.delete(executeId);
|
|
59
|
+
|
|
60
|
+
return new Response("", {
|
|
61
|
+
headers: {
|
|
62
|
+
"Access-Control-Allow-Methods": configMilkio.corsAllowMethods ?? "*",
|
|
63
|
+
"Access-Control-Allow-Headers": configMilkio.corsAllowHeaders ?? "*",
|
|
64
|
+
"Access-Control-Allow-Origin": configMilkio.corsAllowOrigin ?? "*",
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let path = fullurl.pathname.substring(1).split("/");
|
|
70
|
+
|
|
71
|
+
// Compatible with API gateway's ability to differentiate versions by path
|
|
72
|
+
// see: /src/config/ConfigProgram.ts in "ignorePathLevel"
|
|
73
|
+
if (configMilkio.ignorePathLevel !== 0) path = path.slice(configMilkio.ignorePathLevel);
|
|
74
|
+
|
|
75
|
+
let pathstr = path.join("/") as keyof (typeof schema)["apiMethodsSchema"];
|
|
76
|
+
|
|
77
|
+
// Special processing: do not run middleware when encountering 404 and return quickly
|
|
78
|
+
if (!(pathstr in schema.apiMethodsSchema) || pathstr.startsWith("$/")) {
|
|
79
|
+
// @ts-ignore
|
|
80
|
+
const redirectPath = await routerHandler(pathstr, fullurl);
|
|
81
|
+
if (!redirectPath) {
|
|
82
|
+
const rawbody = await request.request.text();
|
|
83
|
+
loggerPushTags(executeId, {
|
|
84
|
+
body: rawbody || "no body",
|
|
85
|
+
});
|
|
86
|
+
if (!response.body) response.body = `{"executeId":"${executeId}","success":false,"fail":{"code":"NOT_FOUND","message":${JSON.stringify(failCode.NOT_FOUND())}}}`;
|
|
87
|
+
|
|
88
|
+
loggerPushTags(executeId, {
|
|
89
|
+
status: response.status,
|
|
90
|
+
responseHeaders: response.headers,
|
|
91
|
+
timeout: new Date().getTime(),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
await loggerSubmit(executeId);
|
|
95
|
+
runtime.execute.executeIds.delete(executeId);
|
|
96
|
+
|
|
97
|
+
return new Response(response.body, response);
|
|
98
|
+
}
|
|
99
|
+
pathstr = redirectPath as typeof pathstr;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
loggerPushTags(executeId, {
|
|
103
|
+
path: pathstr,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const detail = {
|
|
107
|
+
path: pathstr,
|
|
108
|
+
ip,
|
|
109
|
+
executeId,
|
|
110
|
+
fullurl,
|
|
111
|
+
request: request.request,
|
|
112
|
+
response,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// execute api
|
|
116
|
+
// after request middleware
|
|
117
|
+
await MiddlewareEvent.handle("afterHTTPRequest", [headers, detail]);
|
|
118
|
+
|
|
119
|
+
const rawbody = await request.request.text();
|
|
120
|
+
loggerPushTags(executeId, {
|
|
121
|
+
body: rawbody || "no body",
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
let params: any;
|
|
126
|
+
if (rawbody === "") {
|
|
127
|
+
params = undefined;
|
|
128
|
+
} else {
|
|
129
|
+
try {
|
|
130
|
+
params = JSON.parse(rawbody);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
const logger = useLogger(executeId);
|
|
133
|
+
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()");
|
|
134
|
+
params = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
loggerPushTags(executeId, {
|
|
139
|
+
params,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
143
|
+
// @ts-ignore
|
|
144
|
+
const result = await app._executeCoreToJson(pathstr, params, headers, {
|
|
145
|
+
executeId,
|
|
146
|
+
logger,
|
|
147
|
+
detail,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// @ts-ignore
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression, @typescript-eslint/no-explicit-any
|
|
152
|
+
if (!response.body) response.body = result;
|
|
153
|
+
|
|
154
|
+
// before response middleware
|
|
155
|
+
const middlewareResponse = {
|
|
156
|
+
value: response.body,
|
|
157
|
+
};
|
|
158
|
+
await MiddlewareEvent.handle("beforeHTTPResponse", [middlewareResponse, detail]);
|
|
159
|
+
|
|
160
|
+
if (!response.body) response.body = middlewareResponse.value;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
const result = hanldeCatchError(error, executeId);
|
|
163
|
+
if (!response.body) response.body = TSON.stringify(result);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
loggerPushTags(executeId, {
|
|
167
|
+
status: response.status,
|
|
168
|
+
responseHeaders: response.headers,
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
170
|
+
body: response.body?.toString() ?? "",
|
|
171
|
+
timeout: new Date().getTime(),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
await loggerSubmit(executeId);
|
|
175
|
+
runtime.execute.executeIds.delete(executeId);
|
|
176
|
+
|
|
177
|
+
return new Response(response.body, response);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return fetch;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
export type MilkioHTTPRequest = {
|
|
184
|
-
|
|
184
|
+
request: Request;
|
|
185
185
|
};
|
|
186
186
|
|
|
187
187
|
export type MilkioHTTPResponse = Mixin<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
ResponseInit,
|
|
189
|
+
{
|
|
190
|
+
body: string | BodyInit;
|
|
191
|
+
status: number;
|
|
192
|
+
headers: Record<string, string>;
|
|
193
|
+
}
|
|
194
194
|
>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { MiddlewareOptions } from "..";
|
|
2
2
|
|
|
3
3
|
export function defineMiddleware(options: MiddlewareOptions): () => MiddlewareOptions {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
return () => ({
|
|
5
|
+
...options,
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
isMiddleware: true,
|
|
8
|
+
});
|
|
9
9
|
}
|
package/defines/define-use.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export const defineUse = <CreatorFn extends () => Promise<unknown> | unknown>(creatorFn: CreatorFn): (() => Promise<Awaited<ReturnType<CreatorFn>>>) => {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
|
+
let use: any | undefined;
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
const getUse = async () => {
|
|
6
|
+
if (use === undefined) {
|
|
7
|
+
use = await creatorFn();
|
|
8
|
+
}
|
|
9
|
+
return use;
|
|
10
|
+
};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
}
|
|
12
|
+
return getUse;
|
|
13
|
+
};
|
package/index.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
// types
|
|
2
|
-
export * from "./types"
|
|
2
|
+
export * from "./types";
|
|
3
3
|
|
|
4
4
|
// utils
|
|
5
|
-
export * from "./utils/tson"
|
|
6
|
-
export * from "./utils/create-ulid"
|
|
7
|
-
export * from "./utils/env-to-string"
|
|
8
|
-
export * from "./utils/env-to-number"
|
|
9
|
-
export * from "./utils/env-to-boolean"
|
|
5
|
+
export * from "./utils/tson";
|
|
6
|
+
export * from "./utils/create-ulid";
|
|
7
|
+
export * from "./utils/env-to-string";
|
|
8
|
+
export * from "./utils/env-to-number";
|
|
9
|
+
export * from "./utils/env-to-boolean";
|
|
10
10
|
// export * from "./utils/create-template"
|
|
11
|
-
export * from "./utils/header-to-plain-object"
|
|
11
|
+
export * from "./utils/header-to-plain-object";
|
|
12
12
|
|
|
13
13
|
// defines
|
|
14
|
-
export * from "./defines/define-use"
|
|
15
|
-
export * from "./defines/define-api"
|
|
16
|
-
export * from "./defines/define-api-test"
|
|
17
|
-
export * from "./defines/define-middleware"
|
|
14
|
+
export * from "./defines/define-use";
|
|
15
|
+
export * from "./defines/define-api";
|
|
16
|
+
export * from "./defines/define-api-test";
|
|
17
|
+
export * from "./defines/define-middleware";
|
|
18
18
|
|
|
19
19
|
// kernel
|
|
20
|
-
export * from "./kernel/runtime"
|
|
21
|
-
export * from "./kernel/logger"
|
|
22
|
-
export * from "./kernel/fail"
|
|
23
|
-
export * from "./kernel/meta"
|
|
24
|
-
export * from "./kernel/context"
|
|
25
|
-
export * from "./kernel/validate"
|
|
26
|
-
export * from "./kernel/middleware"
|
|
20
|
+
export * from "./kernel/runtime";
|
|
21
|
+
export * from "./kernel/logger";
|
|
22
|
+
export * from "./kernel/fail";
|
|
23
|
+
export * from "./kernel/meta";
|
|
24
|
+
export * from "./kernel/context";
|
|
25
|
+
export * from "./kernel/validate";
|
|
26
|
+
export * from "./kernel/middleware";
|
|
27
27
|
|
|
28
28
|
// handler
|
|
29
|
-
export * from "./defines/define-http-handler"
|
|
30
|
-
export * from "./defines/define-command-handler"
|
|
29
|
+
export * from "./defines/define-http-handler";
|
|
30
|
+
export * from "./defines/define-command-handler";
|
|
31
31
|
|
|
32
32
|
// api test
|
|
33
|
-
export * from "./api-test/index"
|
|
33
|
+
export * from "./api-test/index";
|
|
34
34
|
|
|
35
35
|
// milkio
|
|
36
|
-
export * from "./kernel/milkio"
|
|
36
|
+
export * from "./kernel/milkio";
|
package/kernel/context.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import type { ExecuteId, Logger, MilkioHTTPResponse } from ".."
|
|
1
|
+
import type { ExecuteId, Logger, MilkioHTTPResponse } from "..";
|
|
2
2
|
|
|
3
3
|
export type MilkioContext = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
path: string;
|
|
5
|
+
executeId: ExecuteId;
|
|
6
|
+
headers: Headers;
|
|
7
|
+
logger: Logger;
|
|
8
|
+
/**
|
|
9
|
+
* Additional information about the request
|
|
10
|
+
* These are usually only fully implemented when called by an HTTP server
|
|
11
|
+
* During testing or when calling between microservices, some or all of the values may be undefined
|
|
12
|
+
*/
|
|
13
|
+
detail: Partial<FrameworkHTTPDetail>;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export type FrameworkHTTPDetail = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
path: string;
|
|
18
|
+
executeId: ExecuteId;
|
|
19
|
+
fullurl: URL;
|
|
20
|
+
ip: string;
|
|
21
|
+
request: Request;
|
|
22
|
+
response: MilkioHTTPResponse;
|
|
23
23
|
};
|
package/kernel/fail.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { failCode } from "../../../src/fail-code"
|
|
1
|
+
import { failCode } from "../../../src/fail-code";
|
|
2
2
|
|
|
3
3
|
export function reject<Code extends keyof typeof failCode, FailData extends (typeof failCode)[Code]>(code: Code, data: Parameters<FailData>[0]) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
5
|
+
const message = failCode[code]?.(data as any) ?? "";
|
|
6
|
+
const error = {
|
|
7
|
+
name: "MilkioReject",
|
|
8
|
+
code,
|
|
9
|
+
message,
|
|
10
|
+
data,
|
|
11
|
+
stack: "",
|
|
12
|
+
};
|
|
13
|
+
Error.captureStackTrace(error);
|
|
14
|
+
error.stack = error.stack.replace(/\n.*\n/, "\n");
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
return error;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export type MilkioReject = ReturnType<typeof reject>;
|