@finesoft/front 0.5.1 → 0.5.3
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/README.md +4 -4
- package/dist/Outlet.svelte +39 -0
- package/dist/Outlet.svelte.d.ts +7 -0
- package/dist/browser-CR5vhgXg.mjs +1317 -0
- package/dist/browser-kFMjlLGT.d.mts +262 -0
- package/dist/browser.d.mts +7 -2
- package/dist/browser.mjs +9 -1
- package/dist/controller-types-CgmJ6-le.d.mts +16 -0
- package/dist/cookies-BiRlUanX.d.mts +786 -0
- package/dist/fetch-policy-BHT8RtrL.mjs +82 -0
- package/dist/host-guard-DDWxLpFL.mjs +222 -0
- package/dist/http-B6CJqDyf.d.mts +46 -0
- package/dist/http-CaxrMD1A.d.mts +1 -0
- package/dist/http-D70PL72H.mjs +257 -0
- package/dist/http.d.mts +3 -0
- package/dist/http.mjs +2 -0
- package/dist/index-node.d.mts +15 -0
- package/dist/index-node.mjs +15 -0
- package/dist/index.d.mts +48 -697
- package/dist/index.mjs +44 -261
- package/dist/load-node.d.mts +5 -0
- package/dist/load-node.mjs +10 -0
- package/dist/load-portable.d.mts +5 -0
- package/dist/load-portable.mjs +8 -0
- package/dist/lru-map-BKoUAySU.mjs +50 -0
- package/dist/messages-CAt2QdGr.mjs +140 -0
- package/dist/native-contract-DuR25hYB.d.mts +14 -0
- package/dist/native-contract.d.mts +2 -0
- package/dist/native-contract.mjs +1 -0
- package/dist/node-D9hB4dsz.d.mts +35 -0
- package/dist/node.d.mts +2 -0
- package/dist/node.mjs +59 -0
- package/dist/path-CGFl2w7D.mjs +113 -0
- package/dist/path-CXT6xGPO.d.mts +261 -0
- package/dist/portable-CaxrMD1A.d.mts +1 -0
- package/dist/portable.d.mts +11 -0
- package/dist/portable.mjs +12 -0
- package/dist/proxy-2dSWO-Xw.d.mts +53 -0
- package/dist/proxy-z02VvGIj.mjs +7520 -0
- package/dist/public-types-BcJM-AYc.mjs +835 -0
- package/dist/react-DhwBRw01.d.mts +16 -0
- package/dist/react.d.mts +3 -0
- package/dist/react.mjs +29 -0
- package/dist/rolldown-runtime-B4iAMlE-.mjs +35 -0
- package/dist/secure-fetch-Xlht2jd7.d.mts +30 -0
- package/dist/server-controller-proxy-BkVuVWVD.d.mts +38 -0
- package/dist/session-DnB4ZC3x.d.mts +1279 -0
- package/dist/src-BQBfaaPO.mjs +3825 -0
- package/dist/src-Ftl_0rhu.mjs +28 -0
- package/dist/ssr-BLzYP4wU.d.mts +207 -0
- package/dist/ssr-Tn4YkuxM.mjs +357 -0
- package/dist/ssr.d.mts +3 -0
- package/dist/ssr.mjs +3 -0
- package/dist/svelte-Dr5to3SE.d.mts +16 -0
- package/dist/svelte.d.mts +3 -0
- package/dist/svelte.mjs +13 -0
- package/dist/typegen-C-WeJCtf.d.mts +12 -0
- package/dist/typegen-cli.d.mts +1 -0
- package/dist/typegen-cli.mjs +11 -0
- package/dist/typegen.d.mts +3 -0
- package/dist/typegen.mjs +2 -0
- package/dist/types-B1BT0N3t.mjs +402 -0
- package/dist/undici-CPfL25Hr.mjs +22262 -0
- package/dist/vite-Cj4SPA8D.d.mts +277 -0
- package/dist/vite.d.mts +4 -0
- package/dist/vite.mjs +2354 -0
- package/dist/vue-DGmzuKho.d.mts +32 -0
- package/dist/vue.d.mts +3 -0
- package/dist/vue.mjs +56 -0
- package/dist/web.d.mts +6 -0
- package/dist/web.mjs +8 -0
- package/dist/worker.d.mts +2 -0
- package/dist/worker.mjs +2 -0
- package/docs/01-getting-started.md +67 -199
- package/docs/02-routing-and-controllers.md +163 -241
- package/docs/03-middleware.md +10 -212
- package/docs/04-rendering-and-hydration.md +7 -332
- package/docs/05-i18n.md +7 -237
- package/docs/06-http-client.md +20 -263
- package/docs/07-di-container.md +23 -257
- package/docs/08-observability.md +6 -286
- package/docs/09-server-and-deployment.md +59 -219
- package/docs/10-features-platform-pwa.md +7 -231
- package/docs/11-navigation.md +143 -288
- package/docs/12-session-restoration.md +6 -214
- package/docs/README.md +7 -7
- package/docs/advanced/custom-action-handler.md +29 -229
- package/docs/advanced/custom-adapter.md +7 -259
- package/docs/advanced/custom-event-recorder.md +7 -312
- package/docs/advanced/inline-proxy-codegen.md +6 -185
- package/docs/advanced/multi-tenant-scopes.md +10 -323
- package/docs/engineering/ci-release-flow.md +35 -222
- package/docs/engineering/project-structure.md +34 -277
- package/docs/engineering/testing.md +8 -310
- package/docs/pitfalls/container-scope-leak.md +2 -214
- package/docs/pitfalls/i18n-bundle-size.md +6 -176
- package/docs/pitfalls/proxy-binary-payloads.md +8 -12
- package/docs/pitfalls/ssr-hydration-mismatch.md +9 -155
- package/docs/pitfalls/ssr-vs-csr-globals.md +9 -170
- package/docs/zh/01-getting-started.md +67 -199
- package/docs/zh/02-routing-and-controllers.md +166 -244
- package/docs/zh/03-middleware.md +10 -212
- package/docs/zh/04-rendering-and-hydration.md +7 -332
- package/docs/zh/05-i18n.md +7 -237
- package/docs/zh/06-http-client.md +20 -263
- package/docs/zh/07-di-container.md +23 -257
- package/docs/zh/08-observability.md +6 -283
- package/docs/zh/09-server-and-deployment.md +59 -219
- package/docs/zh/10-features-platform-pwa.md +7 -231
- package/docs/zh/11-navigation.md +130 -290
- package/docs/zh/12-session-restoration.md +6 -214
- package/docs/zh/README.md +4 -4
- package/docs/zh/advanced/custom-action-handler.md +29 -229
- package/docs/zh/advanced/custom-adapter.md +7 -259
- package/docs/zh/advanced/custom-event-recorder.md +7 -312
- package/docs/zh/advanced/inline-proxy-codegen.md +6 -185
- package/docs/zh/advanced/multi-tenant-scopes.md +10 -323
- package/docs/zh/engineering/ci-release-flow.md +35 -222
- package/docs/zh/engineering/project-structure.md +34 -277
- package/docs/zh/engineering/testing.md +8 -310
- package/docs/zh/pitfalls/container-scope-leak.md +2 -214
- package/docs/zh/pitfalls/i18n-bundle-size.md +6 -176
- package/docs/zh/pitfalls/proxy-binary-payloads.md +8 -12
- package/docs/zh/pitfalls/ssr-hydration-mismatch.md +9 -155
- package/docs/zh/pitfalls/ssr-vs-csr-globals.md +9 -170
- package/package.json +118 -20
- package/dist/browser-BHhVWXik.mjs +0 -2
- package/dist/browser-BV2BBXm7.d.mts +0 -2811
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { Bt as secureFetch, Xt as isMultiValueSchema } from "./src-BQBfaaPO.mjs";
|
|
2
|
+
import { i as HttpError } from "./host-guard-DDWxLpFL.mjs";
|
|
3
|
+
//#region ../core/src/schema/standard.ts
|
|
4
|
+
/** 工厂:从一个 validate 函数构造实现了 ~standard 的 codec */
|
|
5
|
+
function makeSchema(validate) {
|
|
6
|
+
return { "~standard": {
|
|
7
|
+
version: 1,
|
|
8
|
+
vendor: "finesoft",
|
|
9
|
+
validate
|
|
10
|
+
} };
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ../core/src/schema/primitives.ts
|
|
14
|
+
const fail = (message) => ({ issues: [{ message }] });
|
|
15
|
+
function str(opts = {}) {
|
|
16
|
+
return makeSchema((value) => {
|
|
17
|
+
if (typeof value !== "string") return fail("expected a string");
|
|
18
|
+
if (opts.minLength !== void 0 && value.length < opts.minLength) return fail(`must be at least ${opts.minLength} characters`);
|
|
19
|
+
if (opts.maxLength !== void 0 && value.length > opts.maxLength) return fail(`must be at most ${opts.maxLength} characters`);
|
|
20
|
+
if (opts.pattern && !opts.pattern.test(value)) return fail(`must match ${opts.pattern}`);
|
|
21
|
+
return { value };
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function inRange(n, opts) {
|
|
25
|
+
if (opts.min !== void 0 && n < opts.min) return fail(`must be >= ${opts.min}`);
|
|
26
|
+
if (opts.max !== void 0 && n > opts.max) return fail(`must be <= ${opts.max}`);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function int(opts = {}) {
|
|
30
|
+
return makeSchema((value) => {
|
|
31
|
+
if (typeof value !== "string" || !/^-?\d+$/.test(value)) return fail(`"${String(value)}" is not an integer`);
|
|
32
|
+
const n = Number(value);
|
|
33
|
+
return inRange(n, opts) ?? { value: n };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function num(opts = {}) {
|
|
37
|
+
return makeSchema((value) => {
|
|
38
|
+
if (typeof value !== "string" || !/^-?\d+(\.\d+)?$/.test(value)) return fail(`"${String(value)}" is not a number`);
|
|
39
|
+
const n = Number(value);
|
|
40
|
+
return inRange(n, opts) ?? { value: n };
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const TRUE = /* @__PURE__ */ new Set(["true", "1"]);
|
|
44
|
+
const FALSE = /* @__PURE__ */ new Set(["false", "0"]);
|
|
45
|
+
function bool() {
|
|
46
|
+
return makeSchema((value) => {
|
|
47
|
+
if (typeof value === "string" && TRUE.has(value)) return { value: true };
|
|
48
|
+
if (typeof value === "string" && FALSE.has(value)) return { value: false };
|
|
49
|
+
return fail(`"${String(value)}" is not a boolean (true/false/1/0)`);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function oneOf(values) {
|
|
53
|
+
return makeSchema((value) => {
|
|
54
|
+
if (typeof value === "string" && values.includes(value)) return { value };
|
|
55
|
+
return fail(`"${String(value)}" is not one of: ${values.join(", ")}`);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
59
|
+
function uuid() {
|
|
60
|
+
return makeSchema((value) => {
|
|
61
|
+
if (typeof value === "string" && UUID_RE.test(value)) return { value };
|
|
62
|
+
return fail(`"${String(value)}" is not a valid UUID`);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region ../core/src/schema/modifiers.ts
|
|
67
|
+
function onMissing(codec, fallback) {
|
|
68
|
+
const multi = isMultiValueSchema(codec);
|
|
69
|
+
return {
|
|
70
|
+
...multi ? { multi: true } : {},
|
|
71
|
+
"~standard": {
|
|
72
|
+
version: 1,
|
|
73
|
+
vendor: "finesoft",
|
|
74
|
+
validate(value) {
|
|
75
|
+
if (value === void 0 || multi && Array.isArray(value) && value.length === 0) return { value: fallback };
|
|
76
|
+
return codec["~standard"].validate(value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function optional(codec) {
|
|
82
|
+
return onMissing(codec, void 0);
|
|
83
|
+
}
|
|
84
|
+
function withDefault(codec, fallback) {
|
|
85
|
+
return onMissing(codec, fallback);
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region ../core/src/http/client.ts
|
|
89
|
+
/**
|
|
90
|
+
* 通用 HTTP 客户端基类
|
|
91
|
+
*
|
|
92
|
+
* 使用方式: 创建子类继承 HttpClient,定义业务方法调用 this.get() / this.post() 等。
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* class MyApiClient extends HttpClient {
|
|
97
|
+
* async getUser(id: string) {
|
|
98
|
+
* return this.get<User>(`/users/${id}`);
|
|
99
|
+
* }
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
var HttpClient = class {
|
|
104
|
+
baseUrl;
|
|
105
|
+
defaultHeaders;
|
|
106
|
+
fetchFn;
|
|
107
|
+
requestInterceptors;
|
|
108
|
+
responseInterceptors;
|
|
109
|
+
contextSignal;
|
|
110
|
+
constructor(config) {
|
|
111
|
+
this.baseUrl = config.baseUrl;
|
|
112
|
+
this.defaultHeaders = config.defaultHeaders ?? {};
|
|
113
|
+
if (!config.fetch && !config.context) throw new TypeError("HttpClient requires fetch or an execution context");
|
|
114
|
+
this.fetchFn = secureFetch(config.fetch ?? config.context.fetch, config);
|
|
115
|
+
this.contextSignal = config.context?.signal;
|
|
116
|
+
this.requestInterceptors = [...config.requestInterceptors ?? []];
|
|
117
|
+
this.responseInterceptors = [...config.responseInterceptors ?? []];
|
|
118
|
+
}
|
|
119
|
+
/** 动态添加请求拦截器 */
|
|
120
|
+
useRequestInterceptor(interceptor) {
|
|
121
|
+
this.requestInterceptors.push(interceptor);
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
/** 动态添加响应拦截器 */
|
|
125
|
+
useResponseInterceptor(interceptor) {
|
|
126
|
+
this.responseInterceptors.push(interceptor);
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
/** GET 请求,返回解析后的 JSON */
|
|
130
|
+
async get(path, params, options) {
|
|
131
|
+
return this.request("GET", path, {
|
|
132
|
+
...options,
|
|
133
|
+
params
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** POST 请求,自动序列化 body 为 JSON */
|
|
137
|
+
async post(path, body, params, options) {
|
|
138
|
+
return this.request("POST", path, {
|
|
139
|
+
...options,
|
|
140
|
+
body,
|
|
141
|
+
params
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/** PUT 请求 */
|
|
145
|
+
async put(path, body, params, options) {
|
|
146
|
+
return this.request("PUT", path, {
|
|
147
|
+
...options,
|
|
148
|
+
body,
|
|
149
|
+
params
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** DELETE 请求 */
|
|
153
|
+
async del(path, params, options) {
|
|
154
|
+
return this.request("DELETE", path, {
|
|
155
|
+
...options,
|
|
156
|
+
params
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 底层请求方法 — 子类可覆写以自定义行为
|
|
161
|
+
*
|
|
162
|
+
* 自动处理:
|
|
163
|
+
* - URL 拼接 (baseUrl + path + params)
|
|
164
|
+
* - SSRF 防护(IP 字面量同步校验 + 可选 DNS 解析校验)
|
|
165
|
+
* - 默认 headers 合并
|
|
166
|
+
* - JSON body 序列化
|
|
167
|
+
* - 响应 JSON 解析
|
|
168
|
+
* - 非 2xx 状态码抛出 HttpError
|
|
169
|
+
*/
|
|
170
|
+
async request(method, path, options) {
|
|
171
|
+
options?.signal?.throwIfAborted();
|
|
172
|
+
const url = this.buildUrl(path, options?.params);
|
|
173
|
+
const headers = {
|
|
174
|
+
...this.defaultHeaders,
|
|
175
|
+
...options?.headers
|
|
176
|
+
};
|
|
177
|
+
let init = {
|
|
178
|
+
method,
|
|
179
|
+
headers,
|
|
180
|
+
signal: options?.signal
|
|
181
|
+
};
|
|
182
|
+
if (options?.body !== void 0) {
|
|
183
|
+
if (!Object.keys(headers).some((k) => k.toLowerCase() === "content-type")) headers["Content-Type"] = "application/json";
|
|
184
|
+
init.body = JSON.stringify(options.body);
|
|
185
|
+
}
|
|
186
|
+
for (const interceptor of this.requestInterceptors) init = await interceptor(url, init);
|
|
187
|
+
const signals = [
|
|
188
|
+
options?.signal,
|
|
189
|
+
init.signal,
|
|
190
|
+
this.contextSignal
|
|
191
|
+
].filter((signal) => !!signal);
|
|
192
|
+
const signal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];
|
|
193
|
+
signal?.throwIfAborted();
|
|
194
|
+
init = {
|
|
195
|
+
...init,
|
|
196
|
+
signal
|
|
197
|
+
};
|
|
198
|
+
let response = await this.fetchFn(url, init);
|
|
199
|
+
signal?.throwIfAborted();
|
|
200
|
+
for (const interceptor of this.responseInterceptors) response = await interceptor(response, url);
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
const body = await response.text().catch(() => void 0);
|
|
203
|
+
throw new HttpError(response.status, response.statusText, body);
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
const result = await response.json();
|
|
207
|
+
signal?.throwIfAborted();
|
|
208
|
+
return result;
|
|
209
|
+
} catch (e) {
|
|
210
|
+
if (e instanceof SyntaxError) throw new HttpError(response.status, "Invalid JSON response", await response.text().catch(() => void 0));
|
|
211
|
+
throw e;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/** 构建完整 URL — 子类可覆写以自定义 URL 拼接逻辑 */
|
|
215
|
+
buildUrl(path, params) {
|
|
216
|
+
const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
|
|
217
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
218
|
+
const url = new URL(`${base}${normalizedPath}`, "http://placeholder");
|
|
219
|
+
if (params) for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
|
|
220
|
+
if (this.baseUrl.startsWith("http")) return url.toString();
|
|
221
|
+
return `${url.pathname}${url.search}`;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region ../core/src/data/mapper.ts
|
|
226
|
+
function pipe(...mappers) {
|
|
227
|
+
return (input) => mappers.reduce((acc, mapper) => mapper(acc), input);
|
|
228
|
+
}
|
|
229
|
+
function pipeAsync(...mappers) {
|
|
230
|
+
return async (input) => {
|
|
231
|
+
let acc = input;
|
|
232
|
+
for (const mapper of mappers) acc = await mapper(acc);
|
|
233
|
+
return acc;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* 将一个 Mapper 应用到数组的每个元素
|
|
238
|
+
*/
|
|
239
|
+
function mapEach(mapper) {
|
|
240
|
+
return (items) => items.map(mapper);
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region ../core/src/utils/optional.ts
|
|
244
|
+
function isSome(value) {
|
|
245
|
+
return value !== null && value !== void 0;
|
|
246
|
+
}
|
|
247
|
+
function isNone(value) {
|
|
248
|
+
return value === null || value === void 0;
|
|
249
|
+
}
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region ../core/src/utils/url.ts
|
|
252
|
+
/**
|
|
253
|
+
* URL 工具函数
|
|
254
|
+
*/
|
|
255
|
+
/** 移除 URL scheme (https://, http://) */
|
|
256
|
+
function removeScheme(url) {
|
|
257
|
+
return url.replace(/^https?:\/\//, "");
|
|
258
|
+
}
|
|
259
|
+
/** 移除 URL host 部分,保留路径 */
|
|
260
|
+
function removeHost(url) {
|
|
261
|
+
try {
|
|
262
|
+
const parsed = new URL(url);
|
|
263
|
+
return parsed.pathname + parsed.search + parsed.hash;
|
|
264
|
+
} catch {
|
|
265
|
+
return url;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/** 移除 query 参数 */
|
|
269
|
+
function removeQueryParams(url) {
|
|
270
|
+
return url.split("?")[0];
|
|
271
|
+
}
|
|
272
|
+
/** 获取 URL 的基础路径(无 query、hash) */
|
|
273
|
+
function getBaseUrl(url) {
|
|
274
|
+
return url.split("?")[0].split("#")[0];
|
|
275
|
+
}
|
|
276
|
+
/** 构建 URL(路径 + query 参数) */
|
|
277
|
+
function buildUrl(path, params) {
|
|
278
|
+
if (!params) return path;
|
|
279
|
+
const searchParams = new URLSearchParams();
|
|
280
|
+
for (const [key, value] of Object.entries(params)) if (value !== void 0) searchParams.set(key, value);
|
|
281
|
+
const qs = searchParams.toString();
|
|
282
|
+
return qs ? `${path}?${qs}` : path;
|
|
283
|
+
}
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region ../core/src/metrics/composite-recorder.ts
|
|
286
|
+
var CompositeEventRecorder = class {
|
|
287
|
+
recorders;
|
|
288
|
+
constructor(recorders) {
|
|
289
|
+
this.recorders = recorders;
|
|
290
|
+
}
|
|
291
|
+
record(type, fields) {
|
|
292
|
+
for (const recorder of this.recorders) recorder.record(type, fields);
|
|
293
|
+
}
|
|
294
|
+
async flush() {
|
|
295
|
+
const pending = [];
|
|
296
|
+
for (const recorder of this.recorders) if (recorder.flush) pending.push(recorder.flush());
|
|
297
|
+
await Promise.all(pending);
|
|
298
|
+
}
|
|
299
|
+
destroy() {
|
|
300
|
+
for (const recorder of this.recorders) recorder.destroy?.();
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region ../core/src/metrics/console-recorder.ts
|
|
305
|
+
var ConsoleEventRecorder = class {
|
|
306
|
+
prefix;
|
|
307
|
+
constructor(prefix = "Metrics") {
|
|
308
|
+
this.prefix = prefix;
|
|
309
|
+
}
|
|
310
|
+
record(type, fields) {
|
|
311
|
+
console.info(`[${this.prefix}:${type}]`, fields ?? "");
|
|
312
|
+
}
|
|
313
|
+
async flush() {}
|
|
314
|
+
destroy() {}
|
|
315
|
+
};
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region ../core/src/metrics/void-recorder.ts
|
|
318
|
+
var VoidEventRecorder = class {
|
|
319
|
+
record() {}
|
|
320
|
+
async flush() {}
|
|
321
|
+
destroy() {}
|
|
322
|
+
};
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region ../core/src/metrics/with-fields-recorder.ts
|
|
325
|
+
var WithFieldsRecorder = class {
|
|
326
|
+
inner;
|
|
327
|
+
providers;
|
|
328
|
+
constructor(inner, providers) {
|
|
329
|
+
this.inner = inner;
|
|
330
|
+
this.providers = providers;
|
|
331
|
+
}
|
|
332
|
+
record(type, fields) {
|
|
333
|
+
let merged = {};
|
|
334
|
+
for (const provider of this.providers) Object.assign(merged, provider.getFields());
|
|
335
|
+
if (fields) Object.assign(merged, fields);
|
|
336
|
+
this.inner.record(type, merged);
|
|
337
|
+
}
|
|
338
|
+
async flush() {
|
|
339
|
+
return this.inner.flush?.();
|
|
340
|
+
}
|
|
341
|
+
destroy() {
|
|
342
|
+
this.inner.destroy?.();
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region ../web/src/models/safe-error-page.ts
|
|
347
|
+
function formatDevError(devError) {
|
|
348
|
+
if (devError instanceof Error) return devError.stack ?? `${devError.name}: ${devError.message}`;
|
|
349
|
+
if (typeof devError === "string") return devError;
|
|
350
|
+
try {
|
|
351
|
+
return JSON.stringify(devError);
|
|
352
|
+
} catch {
|
|
353
|
+
return String(devError);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Build a BasePage for an error condition. In production, only `publicMessage`
|
|
358
|
+
* makes it into the page. In dev, `devError` (if provided) is appended.
|
|
359
|
+
*/
|
|
360
|
+
function safeErrorPage(options) {
|
|
361
|
+
const { status, publicMessage, devError, isProduction = true } = options;
|
|
362
|
+
const showDevError = !isProduction && devError !== void 0;
|
|
363
|
+
return {
|
|
364
|
+
id: "error",
|
|
365
|
+
pageType: "error",
|
|
366
|
+
title: `Error ${status}`,
|
|
367
|
+
description: showDevError ? `${publicMessage}\n\n[dev only]\n${formatDevError(devError)}` : publicMessage
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region ../web/src/middleware/types.ts
|
|
372
|
+
/** 继续执行 */
|
|
373
|
+
function next() {
|
|
374
|
+
return { kind: "next" };
|
|
375
|
+
}
|
|
376
|
+
/** 重定向到新 URL */
|
|
377
|
+
function redirect(url, status = 302) {
|
|
378
|
+
return {
|
|
379
|
+
kind: "redirect",
|
|
380
|
+
url,
|
|
381
|
+
status
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/** URL 重写(不重新加载数据) */
|
|
385
|
+
function rewrite(url) {
|
|
386
|
+
return {
|
|
387
|
+
kind: "rewrite",
|
|
388
|
+
url
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
/** 拒绝访问 */
|
|
392
|
+
function deny(status = 403, message = "Forbidden") {
|
|
393
|
+
return {
|
|
394
|
+
kind: "deny",
|
|
395
|
+
status,
|
|
396
|
+
message
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
//#endregion
|
|
400
|
+
export { bool as C, str as D, oneOf as E, uuid as O, withDefault as S, num as T, mapEach as _, safeErrorPage as a, HttpClient as b, ConsoleEventRecorder as c, getBaseUrl as d, removeHost as f, isSome as g, isNone as h, rewrite as i, makeSchema as k, CompositeEventRecorder as l, removeScheme as m, next as n, WithFieldsRecorder as o, removeQueryParams as p, redirect as r, VoidEventRecorder as s, deny as t, buildUrl as u, pipe as v, int as w, optional as x, pipeAsync as y };
|
|
401
|
+
|
|
402
|
+
//# sourceMappingURL=types-B1BT0N3t.mjs.map
|