tangweijie 5099f2e87e Initial commit: Vue3 + TypeScript 前端项目
- Vue 3 + TypeScript + Element Plus 前端界面
- Pinia 状态管理
- Vue Router 4 路由管理
- Axios HTTP 客户端
- MSW (Mock Service Worker) 开发环境模拟
- 账户管理界面 (列表、详情、三科目余额展示)
- 交易管理界面 (列表、详情)
- 对账管理界面 (三账校验)
- 完善的 API 客户端封装
- Docker 容器化配置
- Nginx 配置用于生产环境
2026-01-05 17:57:11 +08:00

189 lines
5.2 KiB
JavaScript

import {
InterceptorError,
RequestController
} from "./chunk-JXGB54LE.mjs";
// src/utils/emitAsync.ts
async function emitAsync(emitter, eventName, ...data) {
const listeners = emitter.listeners(eventName);
if (listeners.length === 0) {
return;
}
for (const listener of listeners) {
await listener.apply(emitter, data);
}
}
// src/utils/isObject.ts
function isObject(value, loose = false) {
return loose ? Object.prototype.toString.call(value).startsWith("[object ") : Object.prototype.toString.call(value) === "[object Object]";
}
// src/utils/isPropertyAccessible.ts
function isPropertyAccessible(obj, key) {
try {
obj[key];
return true;
} catch (e) {
return false;
}
}
// src/utils/responseUtils.ts
function createServerErrorResponse(body) {
return new Response(
JSON.stringify(
body instanceof Error ? {
name: body.name,
message: body.message,
stack: body.stack
} : body
),
{
status: 500,
statusText: "Unhandled Exception",
headers: {
"Content-Type": "application/json"
}
}
);
}
function isResponseError(response) {
return response != null && response instanceof Response && isPropertyAccessible(response, "type") && response.type === "error";
}
function isResponseLike(value) {
return isObject(value, true) && isPropertyAccessible(value, "status") && isPropertyAccessible(value, "statusText") && isPropertyAccessible(value, "bodyUsed");
}
// src/utils/handleRequest.ts
import { DeferredPromise } from "@open-draft/deferred-promise";
import { until } from "@open-draft/until";
// src/utils/isNodeLikeError.ts
function isNodeLikeError(error) {
if (error == null) {
return false;
}
if (!(error instanceof Error)) {
return false;
}
return "code" in error && "errno" in error;
}
// src/utils/handleRequest.ts
async function handleRequest(options) {
const handleResponse = async (response) => {
if (response instanceof Error) {
await options.controller.errorWith(response);
return true;
}
if (isResponseError(response)) {
await options.controller.respondWith(response);
return true;
}
if (isResponseLike(response)) {
await options.controller.respondWith(response);
return true;
}
if (isObject(response)) {
await options.controller.errorWith(response);
return true;
}
return false;
};
const handleResponseError = async (error) => {
if (error instanceof InterceptorError) {
throw result.error;
}
if (isNodeLikeError(error)) {
await options.controller.errorWith(error);
return true;
}
if (error instanceof Response) {
return await handleResponse(error);
}
return false;
};
const requestAbortPromise = new DeferredPromise();
if (options.request.signal) {
if (options.request.signal.aborted) {
await options.controller.errorWith(options.request.signal.reason);
return;
}
options.request.signal.addEventListener(
"abort",
() => {
requestAbortPromise.reject(options.request.signal.reason);
},
{ once: true }
);
}
const result = await until(async () => {
const requestListenersPromise = emitAsync(options.emitter, "request", {
requestId: options.requestId,
request: options.request,
controller: options.controller
});
await Promise.race([
// Short-circuit the request handling promise if the request gets aborted.
requestAbortPromise,
requestListenersPromise,
options.controller.handled
]);
});
if (requestAbortPromise.state === "rejected") {
await options.controller.errorWith(requestAbortPromise.rejectionReason);
return;
}
if (result.error) {
if (await handleResponseError(result.error)) {
return;
}
if (options.emitter.listenerCount("unhandledException") > 0) {
const unhandledExceptionController = new RequestController(
options.request,
{
/**
* @note Intentionally empty passthrough handle.
* This controller is created within another controller and we only need
* to know if `unhandledException` listeners handled the request.
*/
passthrough() {
},
async respondWith(response) {
await handleResponse(response);
},
async errorWith(reason) {
await options.controller.errorWith(reason);
}
}
);
await emitAsync(options.emitter, "unhandledException", {
error: result.error,
request: options.request,
requestId: options.requestId,
controller: unhandledExceptionController
});
if (unhandledExceptionController.readyState !== RequestController.PENDING) {
return;
}
}
await options.controller.respondWith(
createServerErrorResponse(result.error)
);
return;
}
if (options.controller.readyState === RequestController.PENDING) {
return await options.controller.passthrough();
}
return options.controller.handled;
}
export {
isPropertyAccessible,
emitAsync,
isObject,
isResponseError,
handleRequest
};
//# sourceMappingURL=chunk-R6T7CL5E.mjs.map