From 8658fea0a3e3423710fc214ae89182cd2fda0f07 Mon Sep 17 00:00:00 2001 From: QCQCQC <1220204124@zust.edu.cn> Date: Mon, 25 Nov 2024 22:08:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8F=92=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E4=B8=8EaspectService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oak.config.json | 29 ++++++++++++++ src/aspects/AspectService.ts | 73 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 oak.config.json create mode 100644 src/aspects/AspectService.ts diff --git a/oak.config.json b/oak.config.json new file mode 100644 index 00000000..726fb4f9 --- /dev/null +++ b/oak.config.json @@ -0,0 +1,29 @@ +{ + "projectDir": "./", + "checker": { + "onInvalidReturn": "warn", + "onInvalidDestructuring": "error", + "onNeedPromiseCheck": "error" + }, + "trigger": { + "onReturnLiteral": "warn", + "onNoAsyncFn": "error", + "onNoAwaitContext": "error" + }, + "i18n": { + "onMissingKey": "error", + "onKeyBlank": "warn", + "onParamError": "warn", + "onParamMissing": "error", + "onParamRedundant": "warn" + }, + "oakComponent": { + "onInvalidEntity": "error", + "onInvalidIsList": "error", + "onMissingDataAttrs": "warn", + "onMissingMethods": "error" + }, + "oakPath": { + "onInvalidPath": "error" + } +} \ No newline at end of file diff --git a/src/aspects/AspectService.ts b/src/aspects/AspectService.ts new file mode 100644 index 00000000..959613cc --- /dev/null +++ b/src/aspects/AspectService.ts @@ -0,0 +1,73 @@ +import { BasicFeatures } from "../features"; +import assert from "assert"; +import { AspectDict as CommonAspectDict } from "oak-common-aspect/es/AspectDict"; +import { AsyncContext } from "oak-domain/lib/store/AsyncRowStore"; +import { EntityDict as BaseEntityDict } from "oak-domain/lib/base-app-domain"; + +type AspectDict< + ED extends BaseEntityDict, + BCT extends AsyncContext +> = Record Promise>; + +type TransformAspectDict< + T extends AspectDict, + ED extends BaseEntityDict, + BCT extends AsyncContext +> = { + [K in keyof T]: T[K] extends (params: infer P, context: BCT) => infer R + ? R extends Promise + ? (params: P) => R + : never + : never; +}; + +export type AspectDictTrans< + ED extends BaseEntityDict, + AD extends AspectDict, + BCT extends AsyncContext +> = TransformAspectDict, ED, BCT>; + +export const createService = < + ED extends BaseEntityDict, + AD extends AspectDict +>( + cache: BasicFeatures["cache"] +) => { + return new Proxy({} as Record, { + get: (target, prop) => { + assert( + typeof prop === "string", + "Aspect service name must be a string" + ); + if (process.env.NODE_ENV === "development") { + const service = target[prop]; + if (typeof service !== "function") { + console.log( + "Calling a aspect which is not in this Project:", + prop + ); + } + } + return (params: unknown) => { + const paramsCopy = structuredClone(params); + if (process.env.NODE_ENV === "development") { + console.log("Aspect call:", prop, paramsCopy); + } + return new Promise((resolve, reject) => { + cache + .exec(prop, paramsCopy) + .then((res) => { + resolve(res.result); + }) + .catch((err) => { + reject(err); + }); + }); + }; + }, + // 禁止任何set + set: () => { + throw new Error("Aspect service is readonly"); + }, + }) as unknown as AspectDictTrans; +};