vome-core 0.0.9 → 0.0.12
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/dist/admin/api/client.d.ts +32 -0
- package/dist/admin/api/client.js +1 -0
- package/dist/admin/config/plugin-dev.d.ts +30 -0
- package/dist/admin/config/plugin-dev.js +1 -0
- package/dist/admin/crud/config.d.ts +5 -0
- package/dist/admin/crud/config.js +1 -0
- package/dist/admin/crud/confirm.d.ts +11 -0
- package/dist/admin/crud/confirm.js +1 -0
- package/dist/admin/crud/dict.d.ts +3 -0
- package/dist/admin/crud/dict.js +1 -0
- package/dist/admin/crud/index.d.ts +40 -0
- package/dist/admin/crud/index.js +1 -0
- package/dist/admin/crud/key.d.ts +22 -0
- package/dist/admin/crud/key.js +1 -0
- package/dist/admin/crud/mitt.d.ts +10 -0
- package/dist/admin/crud/mitt.js +1 -0
- package/dist/admin/crud/plugins.d.ts +48 -0
- package/dist/admin/crud/plugins.js +1 -0
- package/dist/admin/crud/registry.d.ts +5 -0
- package/dist/admin/crud/registry.js +26 -0
- package/dist/admin/crud/span.d.ts +17 -0
- package/dist/admin/crud/span.js +1 -0
- package/dist/admin/crud/style.d.ts +36 -0
- package/dist/admin/crud/style.js +1 -0
- package/dist/admin/crud/useCrud.d.ts +18 -0
- package/dist/admin/crud/useCrud.js +1 -0
- package/dist/admin/crud/validate.d.ts +14 -0
- package/dist/admin/crud/validate.js +1 -0
- package/dist/admin/directives/perm.d.ts +3 -0
- package/dist/admin/directives/perm.js +1 -0
- package/dist/admin/hooks/useBrowser.d.ts +5 -0
- package/dist/admin/hooks/useBrowser.js +1 -0
- package/dist/admin/hooks/useUpload.d.ts +8 -0
- package/dist/admin/hooks/useUpload.js +1 -0
- package/dist/admin/hooks/useVome.d.ts +8 -0
- package/dist/admin/hooks/useVome.js +1 -0
- package/dist/admin/index.d.ts +26 -0
- package/dist/admin/index.js +1 -0
- package/dist/admin/lib/browser.d.ts +3 -0
- package/dist/admin/lib/browser.js +1 -0
- package/dist/admin/lib/cn.d.ts +2 -0
- package/dist/admin/lib/cn.js +1 -0
- package/dist/admin/lib/dialog-float.d.ts +4 -0
- package/dist/admin/lib/dialog-float.js +1 -0
- package/dist/admin/lib/eps.d.ts +11 -0
- package/dist/admin/lib/eps.js +1 -0
- package/dist/admin/lib/menu.d.ts +2 -0
- package/dist/admin/lib/menu.js +1 -0
- package/dist/admin/lib/module.d.ts +21 -0
- package/dist/admin/lib/module.js +1 -0
- package/dist/admin/lib/tree.d.ts +2 -0
- package/dist/admin/lib/tree.js +1 -0
- package/dist/admin/lib/upload.d.ts +13 -0
- package/dist/admin/lib/upload.js +1 -0
- package/dist/admin/router/index.d.ts +3 -0
- package/dist/admin/router/index.js +1 -0
- package/dist/admin/router/menu-routes.d.ts +7 -0
- package/dist/admin/router/menu-routes.js +1 -0
- package/dist/admin/service/base.d.ts +27 -0
- package/dist/admin/service/base.js +1 -0
- package/dist/admin/service/index.d.ts +15 -0
- package/dist/admin/service/index.js +1 -0
- package/dist/admin/stores/app.d.ts +1 -0
- package/dist/admin/stores/app.js +1 -0
- package/dist/admin/stores/tags.d.ts +1 -0
- package/dist/admin/stores/tags.js +1 -0
- package/dist/admin/stores/user.d.ts +1 -0
- package/dist/admin/stores/user.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -236
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -3261
- package/dist/shared/index.js +1 -0
- package/dist/shared/tree.d.ts +18 -0
- package/dist/shared/tree.js +1 -0
- package/package.json +12 -10
- package/src/shared/tree.d.ts +18 -0
- package/typings/admin/base/auth.d.ts +20 -0
- package/typings/admin/base/permission.d.ts +19 -0
- package/typings/admin/comm/crud.d.ts +282 -0
- package/typings/admin/comm/request.d.ts +11 -0
- package/typings/admin/comm/service.d.ts +40 -0
- package/typings/admin/comm/upload.d.ts +26 -0
- package/typings/admin/vome/browser.d.ts +10 -0
- package/typings/admin/vome/module.d.ts +13 -0
- package/src/admin/api/client.ts +0 -184
- package/src/admin/config/plugin-dev.ts +0 -31
- package/src/admin/crud/config.ts +0 -38
- package/src/admin/crud/confirm.ts +0 -135
- package/src/admin/crud/dict.ts +0 -49
- package/src/admin/crud/index.ts +0 -79
- package/src/admin/crud/key.ts +0 -47
- package/src/admin/crud/mitt.ts +0 -27
- package/src/admin/crud/plugins.ts +0 -298
- package/src/admin/crud/registry.ts +0 -45
- package/src/admin/crud/span.ts +0 -48
- package/src/admin/crud/style.ts +0 -112
- package/src/admin/crud/useCrud.ts +0 -81
- package/src/admin/crud/validate.ts +0 -109
- package/src/admin/directives/perm.ts +0 -18
- package/src/admin/hooks/useBrowser.ts +0 -27
- package/src/admin/hooks/useUpload.ts +0 -82
- package/src/admin/hooks/useVome.ts +0 -13
- package/src/admin/index.ts +0 -59
- package/src/admin/lib/browser.ts +0 -28
- package/src/admin/lib/cn.ts +0 -7
- package/src/admin/lib/dialog-float.ts +0 -14
- package/src/admin/lib/eps.ts +0 -44
- package/src/admin/lib/menu.ts +0 -14
- package/src/admin/lib/module.ts +0 -112
- package/src/admin/lib/tree.ts +0 -2
- package/src/admin/lib/upload.ts +0 -102
- package/src/admin/router/index.ts +0 -68
- package/src/admin/router/menu-routes.ts +0 -126
- package/src/admin/service/base.ts +0 -96
- package/src/admin/service/index.ts +0 -413
- package/src/admin/stores/app.ts +0 -30
- package/src/admin/stores/tags.ts +0 -73
- package/src/admin/stores/user.ts +0 -52
- /package/{src → dist}/admin/components/vm-aside.vue +0 -0
- /package/{src → dist}/admin/components/vm-auto-perm-dialog.vue +0 -0
- /package/{src → dist}/admin/components/vm-check-tree.vue +0 -0
- /package/{src → dist}/admin/components/vm-dept-tree.vue +0 -0
- /package/{src → dist}/admin/components/vm-empty.vue +0 -0
- /package/{src → dist}/admin/components/vm-eps-perm-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-group-cascader.vue +0 -0
- /package/{src → dist}/admin/components/vm-icon-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-markdown.vue +0 -0
- /package/{src → dist}/admin/components/vm-ri-icon.vue +0 -0
- /package/{src → dist}/admin/components/vm-role-picker.vue +0 -0
- /package/{src → dist}/admin/components/vm-view-path-picker.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-column-custom.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-context-menu.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-picker.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-range.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-date-text.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-dict-tag.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-file-icon.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-multi-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-number-range.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-radio.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-switch.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-tree-select.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-upload-item.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-upload.vue +0 -0
- /package/{src → dist}/admin/crud/components/vm-user-select.vue +0 -0
- /package/{src → dist}/admin/crud/vm-add-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-adv-search.vue +0 -0
- /package/{src → dist}/admin/crud/vm-crud.vue +0 -0
- /package/{src → dist}/admin/crud/vm-dialog.vue +0 -0
- /package/{src → dist}/admin/crud/vm-flex1.vue +0 -0
- /package/{src → dist}/admin/crud/vm-form.vue +0 -0
- /package/{src → dist}/admin/crud/vm-multi-delete-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-pagination.vue +0 -0
- /package/{src → dist}/admin/crud/vm-refresh-btn.vue +0 -0
- /package/{src → dist}/admin/crud/vm-row.vue +0 -0
- /package/{src → dist}/admin/crud/vm-search-key.vue +0 -0
- /package/{src → dist}/admin/crud/vm-search.vue +0 -0
- /package/{src → dist}/admin/crud/vm-table.vue +0 -0
- /package/{src → dist}/admin/crud/vm-toolbar.vue +0 -0
- /package/{src → dist}/admin/crud/vm-upsert.vue +0 -0
- /package/{src → dist}/admin/data/remixicon-all.json +0 -0
- /package/{src → dist}/admin/env.d.ts +0 -0
- /package/{src → dist}/admin/static/fileicon/demo.css +0 -0
- /package/{src → dist}/admin/static/fileicon/demo_index.html +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.css +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.js +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.json +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.ttf +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.woff +0 -0
- /package/{src → dist}/admin/static/fileicon/iconfont.woff2 +0 -0
- /package/{src → dist}/admin/static/scarce//344/270/213/350/275/275/345/244/261/350/264/245.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/224/257/344/273/230/346/210/220/345/212/237.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/344/274/230/346/203/240/345/210/270.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/206/205/345/256/271.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/217/221/347/245/250.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/233/276/347/211/207.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/234/260/345/235/200.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/345/272/227/351/223/272.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/216/250/351/200/201.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/220/234/347/264/242/347/273/223/346/236/234.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/224/266/350/227/217.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/225/260/346/215/256.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/235/203/351/231/220.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/346/266/210/346/201/257.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/244/274/347/211/251.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/247/257/345/210/206.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/347/275/221/347/273/234.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/247/206/351/242/221.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/256/242/345/215/225.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/350/257/204/350/256/272.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/205/215/351/200/201.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/223/266/350/241/214/345/215/241.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//346/232/202/346/227/240/351/237/263/344/271/220.svg" +0 -0
- /package/{src → dist}/admin/static/scarce//351/241/265/351/235/242/344/270/215/345/255/230/345/234/250.svg" +0 -0
- /package/{src → dist}/admin/styles/base.css +0 -0
- /package/{src → dist}/admin/tsconfig.json +0 -0
package/dist/server/index.js
CHANGED
|
@@ -1,3261 +1 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
// src/core/config.ts
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { pathToFileURL } from "url";
|
|
5
|
-
|
|
6
|
-
// src/comm/env.ts
|
|
7
|
-
function getEnv() {
|
|
8
|
-
return Bun.env.NODE_ENV === "dev" ? "dev" : "prod";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// src/comm/merge.ts
|
|
12
|
-
function merge(base, override) {
|
|
13
|
-
const result = { ...base };
|
|
14
|
-
for (const key of Object.keys(override)) {
|
|
15
|
-
const baseVal = result[key];
|
|
16
|
-
const overrideVal = override[key];
|
|
17
|
-
if (baseVal && overrideVal && typeof baseVal === "object" && typeof overrideVal === "object" && !Array.isArray(baseVal) && !Array.isArray(overrideVal)) {
|
|
18
|
-
result[key] = merge(baseVal, overrideVal);
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
result[key] = overrideVal;
|
|
22
|
-
}
|
|
23
|
-
return result;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// src/core/config.ts
|
|
27
|
-
async function loadConfig(configDir = join(process.cwd(), "src/config")) {
|
|
28
|
-
const envFile = getEnv() === "dev" ? "dev.ts" : "prod.ts";
|
|
29
|
-
const defaultMod = await import(pathToFileURL(join(configDir, "default.ts")).href);
|
|
30
|
-
const envMod = await import(pathToFileURL(join(configDir, envFile)).href);
|
|
31
|
-
return merge(defaultMod.default, envMod.default);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// src/core/vome-config.ts
|
|
35
|
-
var VomeConfig = await loadConfig();
|
|
36
|
-
// src/core/app.ts
|
|
37
|
-
import { Elysia as Elysia2 } from "elysia";
|
|
38
|
-
|
|
39
|
-
// src/routing/register.ts
|
|
40
|
-
import { Elysia } from "elysia";
|
|
41
|
-
|
|
42
|
-
// src/core/context/index.ts
|
|
43
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
44
|
-
var storage = new AsyncLocalStorage;
|
|
45
|
-
var warnedOutsideRequest = false;
|
|
46
|
-
function resolveClientIp(request) {
|
|
47
|
-
const forwarded = request.headers.get("x-forwarded-for");
|
|
48
|
-
if (forwarded) {
|
|
49
|
-
const first = forwarded.split(",")[0]?.trim();
|
|
50
|
-
if (first)
|
|
51
|
-
return first;
|
|
52
|
-
}
|
|
53
|
-
return request.headers.get("x-real-ip")?.trim() || request.headers.get("cf-connecting-ip")?.trim() || "";
|
|
54
|
-
}
|
|
55
|
-
function initContextFromRequest(request) {
|
|
56
|
-
const url = new URL(request.url);
|
|
57
|
-
const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
|
|
58
|
-
const hostHeader = request.headers.get("host")?.trim();
|
|
59
|
-
return {
|
|
60
|
-
requestId: crypto.randomUUID(),
|
|
61
|
-
method: request.method,
|
|
62
|
-
path: url.pathname,
|
|
63
|
-
ip: resolveClientIp(request),
|
|
64
|
-
host: forwardedHost || hostHeader || url.host,
|
|
65
|
-
startTime: Date.now()
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function enterContextWith(ctx) {
|
|
69
|
-
storage.enterWith(ctx);
|
|
70
|
-
}
|
|
71
|
-
function getContext() {
|
|
72
|
-
return storage.getStore();
|
|
73
|
-
}
|
|
74
|
-
function assignContext(patch) {
|
|
75
|
-
const store = storage.getStore();
|
|
76
|
-
if (!store) {
|
|
77
|
-
if (getEnv() === "dev" && !warnedOutsideRequest) {
|
|
78
|
-
warnedOutsideRequest = true;
|
|
79
|
-
console.warn("[Context] \u5F53\u524D\u65E0\u8BF7\u6C42\u4E0A\u4E0B\u6587\uFF0C\u5199\u5165\u88AB\u5FFD\u7565\uFF08\u8BF7\u786E\u8BA4 asyncContextManager \u5DF2\u542F\u7528\uFF09");
|
|
80
|
-
}
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
Object.assign(store, patch);
|
|
84
|
-
}
|
|
85
|
-
function runContext(ctx, fn) {
|
|
86
|
-
return storage.run(ctx, fn);
|
|
87
|
-
}
|
|
88
|
-
var Context = Object.assign(assignContext, {
|
|
89
|
-
get: getContext,
|
|
90
|
-
run: runContext
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// src/ioc/container.ts
|
|
94
|
-
import"reflect-metadata";
|
|
95
|
-
|
|
96
|
-
// src/ioc/metadata.ts
|
|
97
|
-
var INJECT_METADATA_KEY = "vome:inject";
|
|
98
|
-
var providers = new Map;
|
|
99
|
-
function registerProvider(meta) {
|
|
100
|
-
providers.set(meta.token, meta);
|
|
101
|
-
}
|
|
102
|
-
function getProvider(token) {
|
|
103
|
-
return providers.get(token);
|
|
104
|
-
}
|
|
105
|
-
function listProviders() {
|
|
106
|
-
const seen = new Set;
|
|
107
|
-
const list = [];
|
|
108
|
-
for (const meta of providers.values()) {
|
|
109
|
-
if (seen.has(meta.useClass))
|
|
110
|
-
continue;
|
|
111
|
-
seen.add(meta.useClass);
|
|
112
|
-
list.push(meta);
|
|
113
|
-
}
|
|
114
|
-
return list;
|
|
115
|
-
}
|
|
116
|
-
function tokenLabel(token) {
|
|
117
|
-
if (typeof token === "string" || typeof token === "symbol")
|
|
118
|
-
return String(token);
|
|
119
|
-
return token.name || "(anonymous)";
|
|
120
|
-
}
|
|
121
|
-
function appendInjectMeta(target, inject) {
|
|
122
|
-
const list = Reflect.getMetadata(INJECT_METADATA_KEY, target) ?? [];
|
|
123
|
-
list.push(inject);
|
|
124
|
-
Reflect.defineMetadata(INJECT_METADATA_KEY, list, target);
|
|
125
|
-
}
|
|
126
|
-
function getInjectMetas(target) {
|
|
127
|
-
return Reflect.getMetadata(INJECT_METADATA_KEY, target) ?? [];
|
|
128
|
-
}
|
|
129
|
-
function resetProviders() {
|
|
130
|
-
providers.clear();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// src/ioc/scope.ts
|
|
134
|
-
var ScopeEnum;
|
|
135
|
-
((ScopeEnum2) => {
|
|
136
|
-
ScopeEnum2["Singleton"] = "singleton";
|
|
137
|
-
ScopeEnum2["Request"] = "request";
|
|
138
|
-
ScopeEnum2["Prototype"] = "prototype";
|
|
139
|
-
})(ScopeEnum ||= {});
|
|
140
|
-
|
|
141
|
-
// src/ioc/container.ts
|
|
142
|
-
var singletons = new Map;
|
|
143
|
-
var creating = new Set;
|
|
144
|
-
var requestCaches = new WeakMap;
|
|
145
|
-
function injectProperties(instance, useClass) {
|
|
146
|
-
for (const meta of getInjectMetas(useClass)) {
|
|
147
|
-
const { propertyKey, token: dep, resolve } = meta;
|
|
148
|
-
if (!resolve && dep == null) {
|
|
149
|
-
throw new Error(`[Ioc] ${String(propertyKey)} \u7F3A\u5C11 token \u6216 resolve`);
|
|
150
|
-
}
|
|
151
|
-
const value = resolve ? resolve() : Ioc.get(dep);
|
|
152
|
-
instance[propertyKey] = value;
|
|
153
|
-
const bind = instance.bindEntity;
|
|
154
|
-
if (resolve && typeof bind === "function") {
|
|
155
|
-
bind.call(instance, value);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
function createInstance(useClass) {
|
|
160
|
-
if (creating.has(useClass)) {
|
|
161
|
-
throw new Error(`[Ioc] \u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56: ${useClass.name}`);
|
|
162
|
-
}
|
|
163
|
-
creating.add(useClass);
|
|
164
|
-
try {
|
|
165
|
-
const instance = new useClass;
|
|
166
|
-
injectProperties(instance, useClass);
|
|
167
|
-
return instance;
|
|
168
|
-
} finally {
|
|
169
|
-
creating.delete(useClass);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function getSingleton(useClass) {
|
|
173
|
-
const cached = singletons.get(useClass);
|
|
174
|
-
if (cached)
|
|
175
|
-
return cached;
|
|
176
|
-
const instance = createInstance(useClass);
|
|
177
|
-
singletons.set(useClass, instance);
|
|
178
|
-
return instance;
|
|
179
|
-
}
|
|
180
|
-
function getRequestCache() {
|
|
181
|
-
const ctx = Context.get();
|
|
182
|
-
if (!ctx) {
|
|
183
|
-
throw new Error("[Ioc] Request \u4F5C\u7528\u57DF\u987B\u5728\u8BF7\u6C42\u4E0A\u4E0B\u6587\u4E2D\u89E3\u6790\uFF08\u8BF7\u786E\u8BA4 asyncContextManager.enable\uFF09");
|
|
184
|
-
}
|
|
185
|
-
let cache = requestCaches.get(ctx);
|
|
186
|
-
if (!cache) {
|
|
187
|
-
cache = new Map;
|
|
188
|
-
requestCaches.set(ctx, cache);
|
|
189
|
-
}
|
|
190
|
-
return cache;
|
|
191
|
-
}
|
|
192
|
-
function getRequestScoped(useClass) {
|
|
193
|
-
const cache = getRequestCache();
|
|
194
|
-
const cached = cache.get(useClass);
|
|
195
|
-
if (cached)
|
|
196
|
-
return cached;
|
|
197
|
-
const instance = createInstance(useClass);
|
|
198
|
-
cache.set(useClass, instance);
|
|
199
|
-
return instance;
|
|
200
|
-
}
|
|
201
|
-
function resolveByScope(useClass, scope) {
|
|
202
|
-
switch (scope) {
|
|
203
|
-
case "singleton" /* Singleton */:
|
|
204
|
-
return getSingleton(useClass);
|
|
205
|
-
case "prototype" /* Prototype */:
|
|
206
|
-
return createInstance(useClass);
|
|
207
|
-
case "request" /* Request */:
|
|
208
|
-
return getRequestScoped(useClass);
|
|
209
|
-
default:
|
|
210
|
-
throw new Error(`[Ioc] \u672A\u77E5\u4F5C\u7528\u57DF: ${scope}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
function resolveMeta(token) {
|
|
214
|
-
const meta = getProvider(token);
|
|
215
|
-
if (!meta) {
|
|
216
|
-
throw new Error(`[Ioc] \u672A\u6CE8\u518C\u7684 Provider: ${tokenLabel(token)}`);
|
|
217
|
-
}
|
|
218
|
-
return meta;
|
|
219
|
-
}
|
|
220
|
-
function bootstrapIoc() {
|
|
221
|
-
for (const { useClass, scope } of listProviders()) {
|
|
222
|
-
if (scope === "singleton" /* Singleton */) {
|
|
223
|
-
getSingleton(useClass);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
console.log(`[Ioc] bootstrap \u2190 ${singletons.size} singleton(s)`);
|
|
227
|
-
}
|
|
228
|
-
function get(token) {
|
|
229
|
-
const meta = resolveMeta(token);
|
|
230
|
-
return resolveByScope(meta.useClass, meta.scope);
|
|
231
|
-
}
|
|
232
|
-
function set(token, instance) {
|
|
233
|
-
if (typeof token === "function") {
|
|
234
|
-
registerProvider({
|
|
235
|
-
token,
|
|
236
|
-
useClass: token,
|
|
237
|
-
scope: "singleton" /* Singleton */
|
|
238
|
-
});
|
|
239
|
-
singletons.set(token, instance);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const ctor = instance?.constructor;
|
|
243
|
-
if (!ctor || ctor === Object) {
|
|
244
|
-
throw new Error(`[Ioc] Ioc.set(${tokenLabel(token)}) \u9700\u8981 class \u5B9E\u4F8B\uFF0C\u4EE5\u4FBF\u786E\u5B9A useClass`);
|
|
245
|
-
}
|
|
246
|
-
registerProvider({ token, useClass: ctor, scope: "singleton" /* Singleton */ });
|
|
247
|
-
registerProvider({ token: ctor, useClass: ctor, scope: "singleton" /* Singleton */ });
|
|
248
|
-
singletons.set(ctor, instance);
|
|
249
|
-
}
|
|
250
|
-
function resetIoc() {
|
|
251
|
-
singletons.clear();
|
|
252
|
-
creating.clear();
|
|
253
|
-
resetProviders();
|
|
254
|
-
}
|
|
255
|
-
var Ioc = {
|
|
256
|
-
get,
|
|
257
|
-
set
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
// src/routing/metadata.ts
|
|
261
|
-
import"reflect-metadata";
|
|
262
|
-
var controllers = new Map;
|
|
263
|
-
function registerController(meta) {
|
|
264
|
-
controllers.set(meta.token, meta);
|
|
265
|
-
}
|
|
266
|
-
function listControllers(side) {
|
|
267
|
-
const all = [...controllers.values()];
|
|
268
|
-
return side ? all.filter((c) => c.side === side) : all;
|
|
269
|
-
}
|
|
270
|
-
var ROUTE_PARAMS_KEY = "vome:controller:route-params";
|
|
271
|
-
var ROUTE_PUBLIC_KEY = "vome:controller:route-public";
|
|
272
|
-
var ROUTE_MW_KEY = "vome:controller:route-middleware";
|
|
273
|
-
var ROUTE_PERMS_KEY = "vome:controller:route-perms";
|
|
274
|
-
var ROUTE_IGNORE_PERMS_KEY = "vome:controller:route-ignore-perms";
|
|
275
|
-
function appendRouteParam(token, handler, param) {
|
|
276
|
-
const map = Reflect.getMetadata(ROUTE_PARAMS_KEY, token) ?? {};
|
|
277
|
-
const list = map[handler] ?? [];
|
|
278
|
-
list.push(param);
|
|
279
|
-
map[handler] = list;
|
|
280
|
-
Reflect.defineMetadata(ROUTE_PARAMS_KEY, map, token);
|
|
281
|
-
}
|
|
282
|
-
function getRouteParams(token, handler) {
|
|
283
|
-
const map = Reflect.getMetadata(ROUTE_PARAMS_KEY, token);
|
|
284
|
-
return map?.[handler] ?? [];
|
|
285
|
-
}
|
|
286
|
-
function clearRouteParams(token) {
|
|
287
|
-
Reflect.deleteMetadata(ROUTE_PARAMS_KEY, token);
|
|
288
|
-
}
|
|
289
|
-
function markRoutePublic(token, handler) {
|
|
290
|
-
const map = Reflect.getMetadata(ROUTE_PUBLIC_KEY, token) ?? {};
|
|
291
|
-
map[handler] = true;
|
|
292
|
-
Reflect.defineMetadata(ROUTE_PUBLIC_KEY, map, token);
|
|
293
|
-
}
|
|
294
|
-
function isRoutePublic(token, handler) {
|
|
295
|
-
const map = Reflect.getMetadata(ROUTE_PUBLIC_KEY, token);
|
|
296
|
-
return !!map?.[handler];
|
|
297
|
-
}
|
|
298
|
-
function clearRoutePublic(token) {
|
|
299
|
-
Reflect.deleteMetadata(ROUTE_PUBLIC_KEY, token);
|
|
300
|
-
}
|
|
301
|
-
function appendRouteMiddleware(token, handler, middleware) {
|
|
302
|
-
const map = Reflect.getMetadata(ROUTE_MW_KEY, token) ?? {};
|
|
303
|
-
map[handler] = [...map[handler] ?? [], ...middleware];
|
|
304
|
-
Reflect.defineMetadata(ROUTE_MW_KEY, map, token);
|
|
305
|
-
}
|
|
306
|
-
function getRouteMiddleware(token, handler) {
|
|
307
|
-
const map = Reflect.getMetadata(ROUTE_MW_KEY, token);
|
|
308
|
-
return map?.[handler] ?? [];
|
|
309
|
-
}
|
|
310
|
-
function clearRouteMiddleware(token) {
|
|
311
|
-
Reflect.deleteMetadata(ROUTE_MW_KEY, token);
|
|
312
|
-
}
|
|
313
|
-
function setRoutePerms(token, handler, perms) {
|
|
314
|
-
const map = Reflect.getMetadata(ROUTE_PERMS_KEY, token) ?? {};
|
|
315
|
-
map[handler] = perms;
|
|
316
|
-
Reflect.defineMetadata(ROUTE_PERMS_KEY, map, token);
|
|
317
|
-
}
|
|
318
|
-
function getRoutePerms(token, handler) {
|
|
319
|
-
const map = Reflect.getMetadata(ROUTE_PERMS_KEY, token);
|
|
320
|
-
return map?.[handler];
|
|
321
|
-
}
|
|
322
|
-
function clearRoutePerms(token) {
|
|
323
|
-
Reflect.deleteMetadata(ROUTE_PERMS_KEY, token);
|
|
324
|
-
}
|
|
325
|
-
function markRouteIgnorePerms(token, handler) {
|
|
326
|
-
const map = Reflect.getMetadata(ROUTE_IGNORE_PERMS_KEY, token) ?? {};
|
|
327
|
-
map[handler] = true;
|
|
328
|
-
Reflect.defineMetadata(ROUTE_IGNORE_PERMS_KEY, map, token);
|
|
329
|
-
}
|
|
330
|
-
function isRouteIgnorePerms(token, handler) {
|
|
331
|
-
const map = Reflect.getMetadata(ROUTE_IGNORE_PERMS_KEY, token);
|
|
332
|
-
return !!map?.[handler];
|
|
333
|
-
}
|
|
334
|
-
function clearRouteIgnorePerms(token) {
|
|
335
|
-
Reflect.deleteMetadata(ROUTE_IGNORE_PERMS_KEY, token);
|
|
336
|
-
}
|
|
337
|
-
function schemaFromParams(params) {
|
|
338
|
-
const schema = {};
|
|
339
|
-
for (const param of params) {
|
|
340
|
-
if (param.source === "body" && param.schema !== undefined)
|
|
341
|
-
schema.body = param.schema;
|
|
342
|
-
if (param.source === "query" && param.schema !== undefined)
|
|
343
|
-
schema.query = param.schema;
|
|
344
|
-
if (param.source === "params" && param.schema !== undefined)
|
|
345
|
-
schema.params = param.schema;
|
|
346
|
-
}
|
|
347
|
-
return Object.keys(schema).length > 0 ? schema : undefined;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// src/routing/openapi-tags.ts
|
|
351
|
-
function openApiTag(module, side) {
|
|
352
|
-
return `${module}.${side}`;
|
|
353
|
-
}
|
|
354
|
-
function sideOrder(side) {
|
|
355
|
-
if (side === "admin")
|
|
356
|
-
return 0;
|
|
357
|
-
if (side === "app")
|
|
358
|
-
return 1;
|
|
359
|
-
return 2;
|
|
360
|
-
}
|
|
361
|
-
function parseTag(tag) {
|
|
362
|
-
const i = tag.lastIndexOf(".");
|
|
363
|
-
if (i < 0)
|
|
364
|
-
return { module: tag, side: "" };
|
|
365
|
-
return { module: tag.slice(0, i), side: tag.slice(i + 1) };
|
|
366
|
-
}
|
|
367
|
-
function buildOpenApiTagDocs() {
|
|
368
|
-
const controllers2 = listControllers();
|
|
369
|
-
const tagMap = new Map;
|
|
370
|
-
const groupMap = new Map;
|
|
371
|
-
for (const meta of controllers2) {
|
|
372
|
-
const tag = openApiTag(meta.module, meta.side);
|
|
373
|
-
if (!tagMap.has(tag)) {
|
|
374
|
-
tagMap.set(tag, {
|
|
375
|
-
name: tag,
|
|
376
|
-
description: `${meta.module} ${meta.side}`,
|
|
377
|
-
"x-displayName": meta.side
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
let set2 = groupMap.get(meta.module);
|
|
381
|
-
if (!set2) {
|
|
382
|
-
set2 = new Set;
|
|
383
|
-
groupMap.set(meta.module, set2);
|
|
384
|
-
}
|
|
385
|
-
set2.add(tag);
|
|
386
|
-
}
|
|
387
|
-
const tags = [...tagMap.values()].sort((a, b) => {
|
|
388
|
-
const pa = parseTag(a.name);
|
|
389
|
-
const pb = parseTag(b.name);
|
|
390
|
-
return pa.module.localeCompare(pb.module) || sideOrder(pa.side) - sideOrder(pb.side);
|
|
391
|
-
});
|
|
392
|
-
const tagGroups = [...groupMap.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([name, set2]) => ({
|
|
393
|
-
name,
|
|
394
|
-
tags: [...set2].sort((a, b) => {
|
|
395
|
-
const sa = parseTag(a).side;
|
|
396
|
-
const sb = parseTag(b).side;
|
|
397
|
-
return sideOrder(sa) - sideOrder(sb);
|
|
398
|
-
})
|
|
399
|
-
}));
|
|
400
|
-
return { tags, tagGroups };
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// src/routing/path-utils.ts
|
|
404
|
-
function normalizePrefix(prefix) {
|
|
405
|
-
if (!prefix)
|
|
406
|
-
return "";
|
|
407
|
-
return prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
408
|
-
}
|
|
409
|
-
function joinPrefix(...parts) {
|
|
410
|
-
const segments = parts.map((part) => normalizePrefix(part).replace(/^\/+|\/+$/g, "")).filter(Boolean);
|
|
411
|
-
return segments.length ? `/${segments.join("/")}` : "/";
|
|
412
|
-
}
|
|
413
|
-
function getRouteSubPath(routePath, controllerPrefix) {
|
|
414
|
-
const ctrl = normalizePrefix(controllerPrefix).replace(/\/$/, "");
|
|
415
|
-
const full = normalizePrefix(routePath);
|
|
416
|
-
if (!ctrl)
|
|
417
|
-
return full || "/";
|
|
418
|
-
if (full === ctrl)
|
|
419
|
-
return "/";
|
|
420
|
-
if (full.startsWith(`${ctrl}/`))
|
|
421
|
-
return full.slice(ctrl.length) || "/";
|
|
422
|
-
const sub = routePath.startsWith("/") ? routePath : `/${routePath}`;
|
|
423
|
-
return sub || "/";
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// src/routing/perm.ts
|
|
427
|
-
function resolveRoutePerm(module, prefix, action) {
|
|
428
|
-
let resource = prefix.replace(/^\//, "").replace(/\/+/g, ":");
|
|
429
|
-
if (resource === module) {
|
|
430
|
-
resource = module;
|
|
431
|
-
} else if (resource.startsWith(`${module}:`)) {
|
|
432
|
-
resource = resource.slice(module.length + 1);
|
|
433
|
-
}
|
|
434
|
-
const head = `${module}-`;
|
|
435
|
-
if (resource.startsWith(head)) {
|
|
436
|
-
resource = resource.slice(head.length);
|
|
437
|
-
}
|
|
438
|
-
resource = resource.replace(/-/g, ":");
|
|
439
|
-
if (!resource)
|
|
440
|
-
resource = module;
|
|
441
|
-
return `${module}:${resource}:${action}`;
|
|
442
|
-
}
|
|
443
|
-
function actionFromSubPath(subPath) {
|
|
444
|
-
const cleaned = subPath.replace(/^\/+|\/+$/g, "");
|
|
445
|
-
if (!cleaned)
|
|
446
|
-
return "index";
|
|
447
|
-
const parts = cleaned.split("/");
|
|
448
|
-
return parts[parts.length - 1] || "index";
|
|
449
|
-
}
|
|
450
|
-
function effectivePerms(route, meta, action) {
|
|
451
|
-
if (meta.side !== "admin" || route.public || route.ignorePerms)
|
|
452
|
-
return;
|
|
453
|
-
if (route.perms?.length)
|
|
454
|
-
return route.perms;
|
|
455
|
-
const act = action ?? actionFromSubPath(getRouteSubPath(route.path ?? "/", meta.prefix));
|
|
456
|
-
return [resolveRoutePerm(meta.module, meta.prefix, act)];
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// src/routing/register.ts
|
|
460
|
-
var crudRegistrar;
|
|
461
|
-
function setCrudRegistrar(fn) {
|
|
462
|
-
crudRegistrar = fn;
|
|
463
|
-
}
|
|
464
|
-
var SIDE_PREFIX = {
|
|
465
|
-
admin: "/admin",
|
|
466
|
-
app: "/app"
|
|
467
|
-
};
|
|
468
|
-
var ADMIN_GUARD = "adminAuth";
|
|
469
|
-
var APP_GUARD = "auth";
|
|
470
|
-
var ELYSIA_METHODS = {
|
|
471
|
-
GET: "get",
|
|
472
|
-
POST: "post",
|
|
473
|
-
PUT: "put",
|
|
474
|
-
DELETE: "delete",
|
|
475
|
-
PATCH: "patch"
|
|
476
|
-
};
|
|
477
|
-
function getSidePrefix(side) {
|
|
478
|
-
return normalizePrefix(SIDE_PREFIX[side]);
|
|
479
|
-
}
|
|
480
|
-
function buildRouteSchema(route) {
|
|
481
|
-
if (route.params?.length)
|
|
482
|
-
return schemaFromParams(route.params);
|
|
483
|
-
const schema = {};
|
|
484
|
-
if (route.body !== undefined)
|
|
485
|
-
schema.body = route.body;
|
|
486
|
-
if (route.query !== undefined)
|
|
487
|
-
schema.query = route.query;
|
|
488
|
-
if (route.routeParams !== undefined)
|
|
489
|
-
schema.params = route.routeParams;
|
|
490
|
-
return Object.keys(schema).length > 0 ? schema : undefined;
|
|
491
|
-
}
|
|
492
|
-
function assertRouteParams(params, handler, controller) {
|
|
493
|
-
const seen = new Set;
|
|
494
|
-
for (const param of params) {
|
|
495
|
-
if (seen.has(param.source)) {
|
|
496
|
-
const label = param.source === "body" ? "Body" : param.source === "query" ? "Query" : "Param";
|
|
497
|
-
throw new Error(`[Router] ${controller}.${handler} \u91CD\u590D @${label}`);
|
|
498
|
-
}
|
|
499
|
-
seen.add(param.source);
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
function createParamHandler(instance, handlerName, params) {
|
|
503
|
-
const method = instance[handlerName];
|
|
504
|
-
const bound = method.bind(instance);
|
|
505
|
-
if (!params?.length)
|
|
506
|
-
return bound;
|
|
507
|
-
const sorted = [...params].sort((a, b) => a.index - b.index);
|
|
508
|
-
return (ctx) => {
|
|
509
|
-
const args = sorted.map((param) => {
|
|
510
|
-
if (param.source === "body")
|
|
511
|
-
return ctx.body;
|
|
512
|
-
if (param.source === "query")
|
|
513
|
-
return ctx.query;
|
|
514
|
-
if (param.source === "params")
|
|
515
|
-
return ctx.params;
|
|
516
|
-
throw new Error(`[Router] \u672A\u77E5\u53C2\u6570\u6765\u6E90: ${param.source}`);
|
|
517
|
-
});
|
|
518
|
-
return bound(...args, ctx);
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
function createPermsGuard(codes) {
|
|
522
|
-
return (ctx) => {
|
|
523
|
-
const status = ctx.status;
|
|
524
|
-
const store = Context.get();
|
|
525
|
-
if (store?.isSuper)
|
|
526
|
-
return;
|
|
527
|
-
const held = store?.perms ?? [];
|
|
528
|
-
if (codes.some((code) => held.includes(code)))
|
|
529
|
-
return;
|
|
530
|
-
return status(403);
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
function openApiSummary(name, remark) {
|
|
534
|
-
const title = name.replace(/^\/+|\/+$/g, "").split("/").pop() || name;
|
|
535
|
-
return remark ? `${title} ${remark}` : title;
|
|
536
|
-
}
|
|
537
|
-
function buildRouteOptions(route, meta) {
|
|
538
|
-
const schema = buildRouteSchema(route) ?? {};
|
|
539
|
-
const options = {
|
|
540
|
-
...schema,
|
|
541
|
-
detail: {
|
|
542
|
-
tags: [openApiTag(meta.module, meta.side)],
|
|
543
|
-
summary: openApiSummary(route.handler, route.summary)
|
|
544
|
-
}
|
|
545
|
-
};
|
|
546
|
-
if (meta.side === "admin" && !route.public) {
|
|
547
|
-
options[ADMIN_GUARD] = true;
|
|
548
|
-
}
|
|
549
|
-
if (meta.side === "app" && !route.public) {
|
|
550
|
-
options[APP_GUARD] = true;
|
|
551
|
-
}
|
|
552
|
-
const before = [];
|
|
553
|
-
const perms = effectivePerms(route, meta);
|
|
554
|
-
if (perms?.length)
|
|
555
|
-
before.push(createPermsGuard(perms));
|
|
556
|
-
if (route.middleware?.length)
|
|
557
|
-
before.push(...route.middleware);
|
|
558
|
-
if (before.length)
|
|
559
|
-
options.beforeHandle = before;
|
|
560
|
-
return options;
|
|
561
|
-
}
|
|
562
|
-
function normalizeCrudRouteOpts(opts) {
|
|
563
|
-
if (opts == null)
|
|
564
|
-
return {};
|
|
565
|
-
if (typeof opts === "boolean")
|
|
566
|
-
return { public: opts };
|
|
567
|
-
return opts;
|
|
568
|
-
}
|
|
569
|
-
function registerControllerPlugin(meta, _vomeConfig) {
|
|
570
|
-
const sidePrefix = getSidePrefix(meta.side);
|
|
571
|
-
const pluginPrefix = joinPrefix(sidePrefix, meta.prefix);
|
|
572
|
-
const instance = Ioc.get(meta.token);
|
|
573
|
-
let plugin = new Elysia({
|
|
574
|
-
prefix: pluginPrefix,
|
|
575
|
-
name: meta.token.name,
|
|
576
|
-
tags: [openApiTag(meta.module, meta.side)]
|
|
577
|
-
});
|
|
578
|
-
for (const mw of meta.middleware ?? []) {
|
|
579
|
-
plugin = plugin.onBeforeHandle(mw);
|
|
580
|
-
}
|
|
581
|
-
const autoRoutes = [];
|
|
582
|
-
for (const route of meta.routes) {
|
|
583
|
-
const handler = instance[route.handler];
|
|
584
|
-
if (typeof handler !== "function") {
|
|
585
|
-
throw new Error(`[Router] ${meta.token.name}.${route.handler} \u4E0D\u662F\u6709\u6548 handler`);
|
|
586
|
-
}
|
|
587
|
-
assertRouteParams(route.params ?? [], route.handler, meta.token.name);
|
|
588
|
-
const wrapped = createParamHandler(instance, route.handler, route.params);
|
|
589
|
-
const subPath = getRouteSubPath(route.path, meta.prefix);
|
|
590
|
-
const options = buildRouteOptions(route, meta);
|
|
591
|
-
const method = ELYSIA_METHODS[route.method];
|
|
592
|
-
plugin = plugin[method](subPath, wrapped, options);
|
|
593
|
-
}
|
|
594
|
-
if (meta.crud?.api?.length || meta.crud?.serviceApis?.length) {
|
|
595
|
-
if (!crudRegistrar) {
|
|
596
|
-
throw new Error(`[Router] ${meta.token.name} \u914D\u7F6E\u4E86 api/serviceApis\uFF0C\u4F46\u672A\u627E\u5230 CRUD \u5B9E\u73B0\uFF08@vome-core attachCrudRoutes \u672A\u6302\u8F7D\uFF09`);
|
|
597
|
-
}
|
|
598
|
-
plugin = crudRegistrar(plugin, meta, {
|
|
599
|
-
controller: instance,
|
|
600
|
-
routeOptions: (opts) => {
|
|
601
|
-
const { public: isPublic, action, summary } = normalizeCrudRouteOpts(opts);
|
|
602
|
-
const options = {
|
|
603
|
-
detail: {
|
|
604
|
-
tags: [openApiTag(meta.module, meta.side)],
|
|
605
|
-
summary: openApiSummary(action ?? "action", summary)
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
if (meta.side === "admin" && !isPublic) {
|
|
609
|
-
options[ADMIN_GUARD] = true;
|
|
610
|
-
if (action) {
|
|
611
|
-
const code = resolveRoutePerm(meta.module, meta.prefix, action);
|
|
612
|
-
options.beforeHandle = [createPermsGuard([code])];
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
return options;
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
for (const name of meta.crud?.api ?? []) {
|
|
619
|
-
const method = name === "info" ? "GET" : "POST";
|
|
620
|
-
autoRoutes.push({
|
|
621
|
-
method,
|
|
622
|
-
path: joinPrefix(meta.prefix, name),
|
|
623
|
-
handler: name,
|
|
624
|
-
autoCrud: true
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
for (const name of meta.crud?.serviceApis ?? []) {
|
|
628
|
-
autoRoutes.push({
|
|
629
|
-
method: "POST",
|
|
630
|
-
path: joinPrefix(meta.prefix, name),
|
|
631
|
-
handler: name,
|
|
632
|
-
autoCrud: true
|
|
633
|
-
});
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
return { plugin, pluginPrefix, autoRoutes };
|
|
637
|
-
}
|
|
638
|
-
function registerControllers(app, vomeConfig) {
|
|
639
|
-
let result = app;
|
|
640
|
-
let routeCount = 0;
|
|
641
|
-
const lines = [];
|
|
642
|
-
for (const meta of listControllers()) {
|
|
643
|
-
const { plugin, pluginPrefix, autoRoutes } = registerControllerPlugin(meta, vomeConfig);
|
|
644
|
-
result = result.use(plugin);
|
|
645
|
-
for (const route of [...meta.routes, ...autoRoutes]) {
|
|
646
|
-
routeCount += 1;
|
|
647
|
-
const subPath = getRouteSubPath(route.path, meta.prefix);
|
|
648
|
-
const fullPath = subPath === "/" ? pluginPrefix : joinPrefix(pluginPrefix, subPath.replace(/^\//, ""));
|
|
649
|
-
const flag = route.public ? " (public)" : route.autoCrud ? " (crud)" : "";
|
|
650
|
-
lines.push(`${route.method} ${fullPath}${flag}`);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
if (routeCount > 0) {
|
|
654
|
-
console.log(`[Router] registered \u2190 ${routeCount} route(s)`);
|
|
655
|
-
for (const line of lines)
|
|
656
|
-
console.log(` ${line}`);
|
|
657
|
-
}
|
|
658
|
-
return result;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// src/comm/scan.ts
|
|
662
|
-
var {Glob } = globalThis.Bun;
|
|
663
|
-
var DEFAULT_EXT = /\.tsx?$/;
|
|
664
|
-
async function scanFiles(patterns, options = {}) {
|
|
665
|
-
const { cwd = process.cwd(), ext = DEFAULT_EXT } = options;
|
|
666
|
-
const list = Array.isArray(patterns) ? patterns : [patterns];
|
|
667
|
-
const files = [];
|
|
668
|
-
for (const pattern of list) {
|
|
669
|
-
const glob = new Glob(pattern);
|
|
670
|
-
for await (const path of glob.scan({ cwd, onlyFiles: true })) {
|
|
671
|
-
if (ext.test(path))
|
|
672
|
-
files.push(path);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
return [...new Set(files)].sort();
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// src/routing/context.ts
|
|
679
|
-
var context = null;
|
|
680
|
-
function setControllerScanContext(next) {
|
|
681
|
-
context = next;
|
|
682
|
-
}
|
|
683
|
-
function getControllerScanContext() {
|
|
684
|
-
return context;
|
|
685
|
-
}
|
|
686
|
-
function parseModuleFromPath(file) {
|
|
687
|
-
const matched = file.match(/modules\/([^/]+)\/controller\//);
|
|
688
|
-
if (!matched)
|
|
689
|
-
return "unknown";
|
|
690
|
-
return matched[1];
|
|
691
|
-
}
|
|
692
|
-
function parseControllerAutoPrefix(file) {
|
|
693
|
-
const matched = file.replace(/\\/g, "/").match(/modules\/([^/]+)\/controller\/(?:admin|app)\/(.+)\.tsx?$/);
|
|
694
|
-
if (!matched)
|
|
695
|
-
return "";
|
|
696
|
-
const module = matched[1];
|
|
697
|
-
const rest = matched[2].replace(/\/+/g, "/").replace(/^\/|\/$/g, "");
|
|
698
|
-
if (!rest)
|
|
699
|
-
return `/${module}`;
|
|
700
|
-
return `/${module}/${rest}`;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// src/comm/format-time.ts
|
|
704
|
-
var TIME_KEY_RE = /(?:Time|Date|At)$/;
|
|
705
|
-
var ISO_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/;
|
|
706
|
-
function formatDateTime(value) {
|
|
707
|
-
const d = value instanceof Date ? value : new Date(value);
|
|
708
|
-
if (Number.isNaN(d.getTime()))
|
|
709
|
-
return String(value);
|
|
710
|
-
return new Intl.DateTimeFormat("sv-SE", {
|
|
711
|
-
timeZone: "Asia/Shanghai",
|
|
712
|
-
year: "numeric",
|
|
713
|
-
month: "2-digit",
|
|
714
|
-
day: "2-digit",
|
|
715
|
-
hour: "2-digit",
|
|
716
|
-
minute: "2-digit",
|
|
717
|
-
second: "2-digit",
|
|
718
|
-
hour12: false
|
|
719
|
-
}).format(d).replace("T", " ");
|
|
720
|
-
}
|
|
721
|
-
function isTimeKey(key) {
|
|
722
|
-
return TIME_KEY_RE.test(key);
|
|
723
|
-
}
|
|
724
|
-
function formatApiDates(data) {
|
|
725
|
-
return walk(data);
|
|
726
|
-
}
|
|
727
|
-
function walk(value, key) {
|
|
728
|
-
if (value == null)
|
|
729
|
-
return value;
|
|
730
|
-
if (value instanceof Date)
|
|
731
|
-
return formatDateTime(value);
|
|
732
|
-
if (typeof value === "string" && key && isTimeKey(key) && ISO_RE.test(value)) {
|
|
733
|
-
return formatDateTime(value);
|
|
734
|
-
}
|
|
735
|
-
if (Array.isArray(value))
|
|
736
|
-
return value.map((item) => walk(item));
|
|
737
|
-
if (typeof value === "object") {
|
|
738
|
-
if (Object.prototype.toString.call(value) !== "[object Object]")
|
|
739
|
-
return value;
|
|
740
|
-
const out = {};
|
|
741
|
-
for (const [k, v] of Object.entries(value)) {
|
|
742
|
-
out[k] = walk(v, k);
|
|
743
|
-
}
|
|
744
|
-
return out;
|
|
745
|
-
}
|
|
746
|
-
return value;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
// src/routing/base.ts
|
|
750
|
-
var RES_CODE = {
|
|
751
|
-
SUCCESS: 1000,
|
|
752
|
-
ERROR: 1001
|
|
753
|
-
};
|
|
754
|
-
|
|
755
|
-
class BaseController {
|
|
756
|
-
ok(data) {
|
|
757
|
-
const raw = data === undefined ? null : data;
|
|
758
|
-
return {
|
|
759
|
-
code: RES_CODE.SUCCESS,
|
|
760
|
-
message: "success",
|
|
761
|
-
data: raw == null ? raw : formatApiDates(raw)
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
fail(message = "error", code = RES_CODE.ERROR) {
|
|
765
|
-
return { code, message };
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
// src/ioc/decorators.ts
|
|
769
|
-
import"reflect-metadata";
|
|
770
|
-
function normalizeProvideArgs(idOrOptions) {
|
|
771
|
-
if (idOrOptions == null)
|
|
772
|
-
return {};
|
|
773
|
-
if (typeof idOrOptions === "string" || typeof idOrOptions === "symbol") {
|
|
774
|
-
return { id: idOrOptions };
|
|
775
|
-
}
|
|
776
|
-
return idOrOptions;
|
|
777
|
-
}
|
|
778
|
-
function Provide(idOrOptions) {
|
|
779
|
-
return (target) => {
|
|
780
|
-
const options = normalizeProvideArgs(idOrOptions);
|
|
781
|
-
const scope = options.scope ?? "singleton" /* Singleton */;
|
|
782
|
-
registerProvider({ token: target, useClass: target, scope });
|
|
783
|
-
if (options.id != null) {
|
|
784
|
-
registerProvider({ token: options.id, useClass: target, scope });
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
function Inject(token) {
|
|
789
|
-
return (target, propertyKey) => {
|
|
790
|
-
const designType = Reflect.getMetadata("design:type", target, propertyKey);
|
|
791
|
-
const injectToken = token ?? designType;
|
|
792
|
-
if (injectToken == null) {
|
|
793
|
-
throw new Error(`[Ioc] @Inject \u65E0\u6CD5\u63A8\u65AD ${String(propertyKey)} \u7684\u7C7B\u578B\uFF0C\u8BF7\u663E\u5F0F\u4F20\u5165 token`);
|
|
794
|
-
}
|
|
795
|
-
appendInjectMeta(target.constructor, {
|
|
796
|
-
propertyKey,
|
|
797
|
-
token: injectToken
|
|
798
|
-
});
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
// src/orm/query-op.ts
|
|
802
|
-
import {
|
|
803
|
-
and,
|
|
804
|
-
arrayContains,
|
|
805
|
-
arrayOverlaps,
|
|
806
|
-
asc,
|
|
807
|
-
desc,
|
|
808
|
-
eq,
|
|
809
|
-
gte,
|
|
810
|
-
inArray,
|
|
811
|
-
like,
|
|
812
|
-
lte,
|
|
813
|
-
or,
|
|
814
|
-
sql
|
|
815
|
-
} from "drizzle-orm";
|
|
816
|
-
function colName(ref) {
|
|
817
|
-
if (typeof ref === "string") {
|
|
818
|
-
const name = ref.includes(".") ? ref.split(".").pop() : ref;
|
|
819
|
-
return { column: name, param: name, none: false };
|
|
820
|
-
}
|
|
821
|
-
const column = ref.column.includes(".") ? ref.column.split(".").pop() : ref.column;
|
|
822
|
-
return {
|
|
823
|
-
column,
|
|
824
|
-
param: ref.requestParam ?? column,
|
|
825
|
-
none: Boolean(ref.none)
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
function rangeColumn(r) {
|
|
829
|
-
return r.column.includes(".") ? r.column.split(".").pop() : r.column;
|
|
830
|
-
}
|
|
831
|
-
function tableCol(table, name) {
|
|
832
|
-
const col = table[name];
|
|
833
|
-
if (col == null)
|
|
834
|
-
throw new Error(`[QueryOp] \u8868\u65E0\u5B57\u6BB5: ${name}`);
|
|
835
|
-
return col;
|
|
836
|
-
}
|
|
837
|
-
function isBlank(value) {
|
|
838
|
-
return value === undefined || value === null || value === "";
|
|
839
|
-
}
|
|
840
|
-
function compactWhere(result) {
|
|
841
|
-
if (result == null || result === false)
|
|
842
|
-
return [];
|
|
843
|
-
const list = Array.isArray(result) ? result : [result];
|
|
844
|
-
return list.filter((x) => x != null && x !== false);
|
|
845
|
-
}
|
|
846
|
-
var q = {
|
|
847
|
-
between(col, min, max) {
|
|
848
|
-
if (isBlank(min) || isBlank(max))
|
|
849
|
-
return;
|
|
850
|
-
return sql`${col} between ${min} and ${max}`;
|
|
851
|
-
},
|
|
852
|
-
range(col, start, end) {
|
|
853
|
-
const parts = [];
|
|
854
|
-
if (!isBlank(start))
|
|
855
|
-
parts.push(gte(col, start));
|
|
856
|
-
if (!isBlank(end))
|
|
857
|
-
parts.push(lte(col, end));
|
|
858
|
-
if (!parts.length)
|
|
859
|
-
return;
|
|
860
|
-
return parts.length === 1 ? parts[0] : and(...parts);
|
|
861
|
-
},
|
|
862
|
-
eqRest(params, table, map) {
|
|
863
|
-
const out = [];
|
|
864
|
-
for (const [key, value] of Object.entries(params)) {
|
|
865
|
-
if (isBlank(value))
|
|
866
|
-
continue;
|
|
867
|
-
const col = map?.[key] ?? table[key];
|
|
868
|
-
if (col == null)
|
|
869
|
-
continue;
|
|
870
|
-
out.push(eq(col, value));
|
|
871
|
-
}
|
|
872
|
-
return out;
|
|
873
|
-
},
|
|
874
|
-
contains(col, value) {
|
|
875
|
-
if (isBlank(value))
|
|
876
|
-
return;
|
|
877
|
-
const values = Array.isArray(value) ? value : [value];
|
|
878
|
-
if (!values.length)
|
|
879
|
-
return;
|
|
880
|
-
return values.length === 1 ? arrayContains(col, values) : arrayOverlaps(col, values);
|
|
881
|
-
}
|
|
882
|
-
};
|
|
883
|
-
function buildFieldClauses(table, body, op) {
|
|
884
|
-
const clauses = [];
|
|
885
|
-
if (op.keyWordLikeFields?.length && !isBlank(body.keyWord)) {
|
|
886
|
-
const kw = `%${String(body.keyWord)}%`;
|
|
887
|
-
const likes = op.keyWordLikeFields.map((f) => {
|
|
888
|
-
const name = f.includes(".") ? f.split(".").pop() : f;
|
|
889
|
-
return like(tableCol(table, name), kw);
|
|
890
|
-
});
|
|
891
|
-
if (likes.length === 1)
|
|
892
|
-
clauses.push(likes[0]);
|
|
893
|
-
else if (likes.length > 1)
|
|
894
|
-
clauses.push(or(...likes));
|
|
895
|
-
}
|
|
896
|
-
for (const ref of op.fieldEq ?? []) {
|
|
897
|
-
const { column, param } = colName(ref);
|
|
898
|
-
const value = body[param];
|
|
899
|
-
if (isBlank(value))
|
|
900
|
-
continue;
|
|
901
|
-
if (Array.isArray(value)) {
|
|
902
|
-
if (!value.length)
|
|
903
|
-
continue;
|
|
904
|
-
clauses.push(inArray(tableCol(table, column), value));
|
|
905
|
-
} else {
|
|
906
|
-
clauses.push(eq(tableCol(table, column), value));
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
for (const ref of op.fieldLike ?? []) {
|
|
910
|
-
const { column, param } = colName(ref);
|
|
911
|
-
const value = body[param];
|
|
912
|
-
if (isBlank(value))
|
|
913
|
-
continue;
|
|
914
|
-
clauses.push(like(tableCol(table, column), `%${String(value)}%`));
|
|
915
|
-
}
|
|
916
|
-
for (const ref of op.fieldArray ?? []) {
|
|
917
|
-
const { column, param } = colName(ref);
|
|
918
|
-
const clause = q.contains(tableCol(table, column), body[param]);
|
|
919
|
-
if (clause)
|
|
920
|
-
clauses.push(clause);
|
|
921
|
-
}
|
|
922
|
-
for (const r of op.fieldRange ?? []) {
|
|
923
|
-
const col = tableCol(table, rangeColumn(r));
|
|
924
|
-
const clause = q.range(col, body[r.min], body[r.max]);
|
|
925
|
-
if (clause)
|
|
926
|
-
clauses.push(clause);
|
|
927
|
-
}
|
|
928
|
-
return clauses;
|
|
929
|
-
}
|
|
930
|
-
function buildOrderBy(table, body, op) {
|
|
931
|
-
const orderBy = [];
|
|
932
|
-
const orderField = body.order != null ? String(body.order) : undefined;
|
|
933
|
-
const sortDir = body.sort === "asc" || body.sort === "desc" ? body.sort : undefined;
|
|
934
|
-
if (orderField) {
|
|
935
|
-
const col = tableCol(table, orderField);
|
|
936
|
-
orderBy.push(sortDir === "asc" ? asc(col) : desc(col));
|
|
937
|
-
} else if (op.addOrderBy) {
|
|
938
|
-
for (const [field, dir] of Object.entries(op.addOrderBy)) {
|
|
939
|
-
const name = field.includes(".") ? field.split(".").pop() : field;
|
|
940
|
-
const col = tableCol(table, name);
|
|
941
|
-
orderBy.push(dir === "asc" ? asc(col) : desc(col));
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
return orderBy;
|
|
945
|
-
}
|
|
946
|
-
function needsAdvancedQuery(op) {
|
|
947
|
-
return !!(op?.join?.length || op?.select);
|
|
948
|
-
}
|
|
949
|
-
async function buildQueryOp(table, body, op = {}, request) {
|
|
950
|
-
const clauses = buildFieldClauses(table, body, op);
|
|
951
|
-
const orderBySql = buildOrderBy(table, body, op);
|
|
952
|
-
const ctx = { body, request: request ?? new Request("http://local") };
|
|
953
|
-
if (op.where) {
|
|
954
|
-
clauses.push(...compactWhere(await op.where(ctx)));
|
|
955
|
-
}
|
|
956
|
-
if (op.extend) {
|
|
957
|
-
const qb = {
|
|
958
|
-
andWhere(condition) {
|
|
959
|
-
if (condition != null && condition !== false)
|
|
960
|
-
clauses.push(condition);
|
|
961
|
-
},
|
|
962
|
-
orderBy(...orders) {
|
|
963
|
-
for (const o of orders) {
|
|
964
|
-
if (o != null)
|
|
965
|
-
orderBySql.push(o);
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
await op.extend(qb, ctx);
|
|
970
|
-
}
|
|
971
|
-
const where = clauses.length === 0 ? undefined : clauses.length === 1 ? clauses[0] : and(...clauses);
|
|
972
|
-
return { where, orderBySql };
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
// src/orm/query-builder.ts
|
|
976
|
-
import {
|
|
977
|
-
and as and4,
|
|
978
|
-
count,
|
|
979
|
-
countDistinct,
|
|
980
|
-
getTableColumns,
|
|
981
|
-
isNotNull,
|
|
982
|
-
isNull,
|
|
983
|
-
sql as sql4
|
|
984
|
-
} from "drizzle-orm";
|
|
985
|
-
|
|
986
|
-
// src/orm/crud-config.ts
|
|
987
|
-
function readCrudConfig() {
|
|
988
|
-
return VomeConfig.vome?.crud ?? {};
|
|
989
|
-
}
|
|
990
|
-
function resolveUpsert(override) {
|
|
991
|
-
return override ?? readCrudConfig().upsert ?? "insert";
|
|
992
|
-
}
|
|
993
|
-
function resolveSoftDelete(override) {
|
|
994
|
-
if (override != null)
|
|
995
|
-
return override;
|
|
996
|
-
return readCrudConfig().softDelete === true;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
// src/orm/db-store.ts
|
|
1000
|
-
class DbStore {
|
|
1001
|
-
drizzle;
|
|
1002
|
-
client;
|
|
1003
|
-
schema;
|
|
1004
|
-
sql;
|
|
1005
|
-
constructor(drizzle, client, schema, sql2) {
|
|
1006
|
-
this.drizzle = drizzle;
|
|
1007
|
-
this.client = client;
|
|
1008
|
-
this.schema = schema;
|
|
1009
|
-
this.sql = sql2;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// src/orm/data-scope.ts
|
|
1014
|
-
import { and as and3, inArray as inArray2, sql as sql3 } from "drizzle-orm";
|
|
1015
|
-
|
|
1016
|
-
// src/orm/tenant.ts
|
|
1017
|
-
import { and as and2, eq as eq2, sql as sql2 } from "drizzle-orm";
|
|
1018
|
-
var SKIP_KEY = "__skipTenant";
|
|
1019
|
-
function isTenantEnabled() {
|
|
1020
|
-
return VomeConfig.vome?.tenant === true;
|
|
1021
|
-
}
|
|
1022
|
-
function tableHasTenantId(table) {
|
|
1023
|
-
return table.tenantId != null;
|
|
1024
|
-
}
|
|
1025
|
-
function resolveTenantScope() {
|
|
1026
|
-
if (!isTenantEnabled())
|
|
1027
|
-
return "off";
|
|
1028
|
-
const ctx = Context.get();
|
|
1029
|
-
if (ctx?.[SKIP_KEY])
|
|
1030
|
-
return "off";
|
|
1031
|
-
if (ctx?.isSuper)
|
|
1032
|
-
return "all";
|
|
1033
|
-
const raw = ctx?.tenantId;
|
|
1034
|
-
const id = typeof raw === "number" ? raw : Number(raw);
|
|
1035
|
-
if (!Number.isFinite(id) || id <= 0)
|
|
1036
|
-
return "none";
|
|
1037
|
-
return id;
|
|
1038
|
-
}
|
|
1039
|
-
function applyTenantWhere(table, where) {
|
|
1040
|
-
if (!tableHasTenantId(table))
|
|
1041
|
-
return where;
|
|
1042
|
-
const scope = resolveTenantScope();
|
|
1043
|
-
if (scope === "off" || scope === "all")
|
|
1044
|
-
return where;
|
|
1045
|
-
const col = table.tenantId;
|
|
1046
|
-
const tenantClause = scope === "none" ? sql2`false` : eq2(col, scope);
|
|
1047
|
-
if (where && tenantClause)
|
|
1048
|
-
return and2(where, tenantClause);
|
|
1049
|
-
return where ?? tenantClause;
|
|
1050
|
-
}
|
|
1051
|
-
function stampTenantId(table, data) {
|
|
1052
|
-
if (!tableHasTenantId(table))
|
|
1053
|
-
return data;
|
|
1054
|
-
const scope = resolveTenantScope();
|
|
1055
|
-
if (typeof scope !== "number")
|
|
1056
|
-
return data;
|
|
1057
|
-
if (data.tenantId != null)
|
|
1058
|
-
return data;
|
|
1059
|
-
return { ...data, tenantId: scope };
|
|
1060
|
-
}
|
|
1061
|
-
async function noTenant(fn) {
|
|
1062
|
-
const ctx = Context.get();
|
|
1063
|
-
if (!ctx)
|
|
1064
|
-
return fn();
|
|
1065
|
-
const prev = ctx[SKIP_KEY];
|
|
1066
|
-
ctx[SKIP_KEY] = true;
|
|
1067
|
-
try {
|
|
1068
|
-
return await fn();
|
|
1069
|
-
} finally {
|
|
1070
|
-
if (prev === undefined)
|
|
1071
|
-
delete ctx[SKIP_KEY];
|
|
1072
|
-
else
|
|
1073
|
-
ctx[SKIP_KEY] = prev;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
function normalizeHost(host) {
|
|
1077
|
-
if (!host)
|
|
1078
|
-
return "";
|
|
1079
|
-
return host.trim().toLowerCase().replace(/:\d+$/, "");
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
// src/orm/data-scope.ts
|
|
1083
|
-
var SKIP_KEY2 = "__skipDataScope";
|
|
1084
|
-
function tableHasDepartmentId(table) {
|
|
1085
|
-
return table.departmentId != null;
|
|
1086
|
-
}
|
|
1087
|
-
function resolveDataScope() {
|
|
1088
|
-
const ctx = Context.get();
|
|
1089
|
-
if (!ctx)
|
|
1090
|
-
return "off";
|
|
1091
|
-
if (ctx[SKIP_KEY2])
|
|
1092
|
-
return "off";
|
|
1093
|
-
if (ctx.isSuper)
|
|
1094
|
-
return "all";
|
|
1095
|
-
const mode = ctx.dataScope;
|
|
1096
|
-
if (mode == null || mode === "")
|
|
1097
|
-
return "off";
|
|
1098
|
-
if (mode === "all")
|
|
1099
|
-
return "all";
|
|
1100
|
-
if (mode === "none")
|
|
1101
|
-
return "none";
|
|
1102
|
-
const raw = ctx.dataScopeDeptIds;
|
|
1103
|
-
const ids = Array.isArray(raw) ? raw.map((id) => Number(id)).filter((id) => Number.isFinite(id) && id > 0) : [];
|
|
1104
|
-
if (!ids.length)
|
|
1105
|
-
return "none";
|
|
1106
|
-
return [...new Set(ids)];
|
|
1107
|
-
}
|
|
1108
|
-
function applyDataScopeWhere(table, where) {
|
|
1109
|
-
if (!tableHasDepartmentId(table))
|
|
1110
|
-
return where;
|
|
1111
|
-
const scope = resolveDataScope();
|
|
1112
|
-
if (scope === "off" || scope === "all")
|
|
1113
|
-
return where;
|
|
1114
|
-
const col = table.departmentId;
|
|
1115
|
-
const clause = scope === "none" ? sql3`false` : inArray2(col, scope);
|
|
1116
|
-
if (where)
|
|
1117
|
-
return and3(where, clause);
|
|
1118
|
-
return clause;
|
|
1119
|
-
}
|
|
1120
|
-
function applyRowScopes(table, where) {
|
|
1121
|
-
return applyDataScopeWhere(table, applyTenantWhere(table, where));
|
|
1122
|
-
}
|
|
1123
|
-
async function noDataScope(fn) {
|
|
1124
|
-
const ctx = Context.get();
|
|
1125
|
-
if (!ctx)
|
|
1126
|
-
return fn();
|
|
1127
|
-
const prev = ctx[SKIP_KEY2];
|
|
1128
|
-
ctx[SKIP_KEY2] = true;
|
|
1129
|
-
try {
|
|
1130
|
-
return await fn();
|
|
1131
|
-
} finally {
|
|
1132
|
-
if (prev === undefined)
|
|
1133
|
-
delete ctx[SKIP_KEY2];
|
|
1134
|
-
else
|
|
1135
|
-
ctx[SKIP_KEY2] = prev;
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
// src/orm/query-builder.ts
|
|
1140
|
-
function deletedAtColumn(table) {
|
|
1141
|
-
return table.deletedAt;
|
|
1142
|
-
}
|
|
1143
|
-
function trashClause(table, options) {
|
|
1144
|
-
if (!resolveSoftDelete(options?.softDelete))
|
|
1145
|
-
return;
|
|
1146
|
-
const col = deletedAtColumn(table);
|
|
1147
|
-
if (col == null)
|
|
1148
|
-
return;
|
|
1149
|
-
if (options?.onlyTrashed)
|
|
1150
|
-
return isNotNull(col);
|
|
1151
|
-
if (options?.withTrashed)
|
|
1152
|
-
return;
|
|
1153
|
-
return isNull(col);
|
|
1154
|
-
}
|
|
1155
|
-
function mergeWhere(where, trash) {
|
|
1156
|
-
if (where && trash)
|
|
1157
|
-
return and4(trash, where);
|
|
1158
|
-
return where ?? trash;
|
|
1159
|
-
}
|
|
1160
|
-
function applyJoins(query, main, op) {
|
|
1161
|
-
let next = query;
|
|
1162
|
-
for (const join2 of op.join ?? []) {
|
|
1163
|
-
const table = join2.table;
|
|
1164
|
-
const on = join2.on(main);
|
|
1165
|
-
const type = join2.type ?? "leftJoin";
|
|
1166
|
-
if (type === "innerJoin" || type === "join") {
|
|
1167
|
-
next = next.innerJoin(table, on);
|
|
1168
|
-
} else {
|
|
1169
|
-
next = next.leftJoin(table, on);
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
return next;
|
|
1173
|
-
}
|
|
1174
|
-
function resolveSelect(main, op) {
|
|
1175
|
-
if (op.select)
|
|
1176
|
-
return op.select;
|
|
1177
|
-
return getTableColumns(main);
|
|
1178
|
-
}
|
|
1179
|
-
function countExpr(main, hasJoin) {
|
|
1180
|
-
const idCol = main.id;
|
|
1181
|
-
if (idCol != null && hasJoin)
|
|
1182
|
-
return countDistinct(idCol);
|
|
1183
|
-
if (idCol != null)
|
|
1184
|
-
return count(idCol);
|
|
1185
|
-
return count(sql4`*`);
|
|
1186
|
-
}
|
|
1187
|
-
async function queryWithOp(main, body, op, options) {
|
|
1188
|
-
const built = await buildQueryOp(main, body, op, options.request);
|
|
1189
|
-
const trash = trashClause(main, options.trash);
|
|
1190
|
-
const where = applyRowScopes(main, mergeWhere(built.where, trash));
|
|
1191
|
-
const select = resolveSelect(main, op);
|
|
1192
|
-
const hasJoin = !!op.join?.length;
|
|
1193
|
-
const db = Ioc.get(DbStore).drizzle;
|
|
1194
|
-
let listQuery = applyJoins(db.select(select).from(main), main, op);
|
|
1195
|
-
if (where)
|
|
1196
|
-
listQuery = listQuery.where(where);
|
|
1197
|
-
if (built.orderBySql.length)
|
|
1198
|
-
listQuery = listQuery.orderBy(...built.orderBySql);
|
|
1199
|
-
if (options.mode === "list") {
|
|
1200
|
-
return await listQuery;
|
|
1201
|
-
}
|
|
1202
|
-
const page = Math.max(1, Number(body.page ?? 1));
|
|
1203
|
-
const size = Math.min(100, Math.max(1, Number(body.size ?? 20)));
|
|
1204
|
-
const offset = (page - 1) * size;
|
|
1205
|
-
const list = await listQuery.limit(size).offset(offset);
|
|
1206
|
-
let countQuery = applyJoins(db.select({ value: countExpr(main, hasJoin) }).from(main), main, op);
|
|
1207
|
-
if (where)
|
|
1208
|
-
countQuery = countQuery.where(where);
|
|
1209
|
-
const rows = await countQuery;
|
|
1210
|
-
const total = Number(rows[0]?.value ?? 0);
|
|
1211
|
-
return { list, pagination: { page, size, total } };
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
// src/orm/repository.ts
|
|
1215
|
-
import { and as and5, count as count2, eq as eq3, inArray as inArray3, isNotNull as isNotNull2, isNull as isNull2 } from "drizzle-orm";
|
|
1216
|
-
|
|
1217
|
-
// src/orm/entity-schema.ts
|
|
1218
|
-
import { createInsertSchema, createSelectSchema, createUpdateSchema } from "drizzle-zod";
|
|
1219
|
-
function entitySchemas(table) {
|
|
1220
|
-
return {
|
|
1221
|
-
select: createSelectSchema(table),
|
|
1222
|
-
insert: createInsertSchema(table),
|
|
1223
|
-
update: createUpdateSchema(table)
|
|
1224
|
-
};
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
// src/orm/repository.ts
|
|
1228
|
-
var WRITE_META_KEYS = ["createTime", "updateTime", "deletedAt"];
|
|
1229
|
-
function sanitizeWritePayload(data) {
|
|
1230
|
-
const raw = data && typeof data === "object" && !Array.isArray(data) ? { ...data } : {};
|
|
1231
|
-
for (const k of WRITE_META_KEYS)
|
|
1232
|
-
delete raw[k];
|
|
1233
|
-
for (const [k, v] of Object.entries(raw)) {
|
|
1234
|
-
if (typeof v !== "string")
|
|
1235
|
-
continue;
|
|
1236
|
-
if (!/^\d{4}-\d{2}-\d{2}/.test(v))
|
|
1237
|
-
continue;
|
|
1238
|
-
const d = new Date(v);
|
|
1239
|
-
if (!Number.isNaN(d.getTime()))
|
|
1240
|
-
raw[k] = d;
|
|
1241
|
-
}
|
|
1242
|
-
return raw;
|
|
1243
|
-
}
|
|
1244
|
-
function isSqlLike(v) {
|
|
1245
|
-
return !!v && typeof v === "object" && v.getSQL != null;
|
|
1246
|
-
}
|
|
1247
|
-
function db() {
|
|
1248
|
-
return Ioc.get(DbStore).drizzle;
|
|
1249
|
-
}
|
|
1250
|
-
function tableId(table) {
|
|
1251
|
-
const id = table.id;
|
|
1252
|
-
if (!id) {
|
|
1253
|
-
throw new Error("[Repository] \u8868\u65E0 id \u5217\uFF0C\u8BF7\u6539\u7528 find(where) / findOne(where)");
|
|
1254
|
-
}
|
|
1255
|
-
return id;
|
|
1256
|
-
}
|
|
1257
|
-
function deletedAtColumn2(table) {
|
|
1258
|
-
return table.deletedAt;
|
|
1259
|
-
}
|
|
1260
|
-
function mergeWhere2(where, trash) {
|
|
1261
|
-
if (where && trash)
|
|
1262
|
-
return and5(trash, where);
|
|
1263
|
-
return where ?? trash;
|
|
1264
|
-
}
|
|
1265
|
-
function trashClause2(table, options) {
|
|
1266
|
-
if (!resolveSoftDelete(options?.softDelete))
|
|
1267
|
-
return;
|
|
1268
|
-
const col = deletedAtColumn2(table);
|
|
1269
|
-
if (col == null)
|
|
1270
|
-
return;
|
|
1271
|
-
if (options?.onlyTrashed)
|
|
1272
|
-
return isNotNull2(col);
|
|
1273
|
-
if (options?.withTrashed)
|
|
1274
|
-
return;
|
|
1275
|
-
return isNull2(col);
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
|
-
class Repository {
|
|
1279
|
-
table;
|
|
1280
|
-
schema;
|
|
1281
|
-
constructor(table, schema) {
|
|
1282
|
-
this.table = table;
|
|
1283
|
-
this.schema = schema ?? entitySchemas(table);
|
|
1284
|
-
}
|
|
1285
|
-
supportsSoftDelete() {
|
|
1286
|
-
return deletedAtColumn2(this.table) != null;
|
|
1287
|
-
}
|
|
1288
|
-
scopedWhere(where, options) {
|
|
1289
|
-
return applyRowScopes(this.table, mergeWhere2(where, trashClause2(this.table, options)));
|
|
1290
|
-
}
|
|
1291
|
-
async find(where, options) {
|
|
1292
|
-
const scoped = this.scopedWhere(where, options);
|
|
1293
|
-
let query = db().select().from(this.table);
|
|
1294
|
-
if (scoped)
|
|
1295
|
-
query = query.where(scoped);
|
|
1296
|
-
if (options?.orderBy?.length)
|
|
1297
|
-
query = query.orderBy(...options.orderBy);
|
|
1298
|
-
return await query;
|
|
1299
|
-
}
|
|
1300
|
-
async findOne(where, options) {
|
|
1301
|
-
const [row] = await this.find(where, options);
|
|
1302
|
-
return row;
|
|
1303
|
-
}
|
|
1304
|
-
async findById(id, options) {
|
|
1305
|
-
return this.findOne(eq3(tableId(this.table), id), options);
|
|
1306
|
-
}
|
|
1307
|
-
async count(where, options) {
|
|
1308
|
-
const scoped = this.scopedWhere(where, options);
|
|
1309
|
-
const query = db().select({ value: count2() }).from(this.table);
|
|
1310
|
-
const rows = scoped ? await query.where(scoped) : await query;
|
|
1311
|
-
return Number(rows[0]?.value ?? 0);
|
|
1312
|
-
}
|
|
1313
|
-
async findPage(options) {
|
|
1314
|
-
const { page, size, where, orderBy, withTrashed, onlyTrashed, softDelete } = options;
|
|
1315
|
-
const trashOpts = { withTrashed, onlyTrashed, softDelete };
|
|
1316
|
-
const scoped = this.scopedWhere(where, trashOpts);
|
|
1317
|
-
const offset = (page - 1) * size;
|
|
1318
|
-
let query = db().select().from(this.table);
|
|
1319
|
-
if (scoped)
|
|
1320
|
-
query = query.where(scoped);
|
|
1321
|
-
if (orderBy?.length)
|
|
1322
|
-
query = query.orderBy(...orderBy);
|
|
1323
|
-
const list = await query.limit(size).offset(offset);
|
|
1324
|
-
const total = await this.count(where, trashOpts);
|
|
1325
|
-
return { list, pagination: { page, size, total } };
|
|
1326
|
-
}
|
|
1327
|
-
parseInsert(item) {
|
|
1328
|
-
const stamped = stampTenantId(this.table, sanitizeWritePayload(item));
|
|
1329
|
-
return this.schema.insert.parse(stamped);
|
|
1330
|
-
}
|
|
1331
|
-
async create(data) {
|
|
1332
|
-
if (Array.isArray(data)) {
|
|
1333
|
-
if (!data.length)
|
|
1334
|
-
return [];
|
|
1335
|
-
const values = data.map((item) => this.parseInsert(item));
|
|
1336
|
-
return await db().insert(this.table).values(values).returning();
|
|
1337
|
-
}
|
|
1338
|
-
const [row] = await db().insert(this.table).values(this.parseInsert(data)).returning();
|
|
1339
|
-
return row;
|
|
1340
|
-
}
|
|
1341
|
-
async save(data) {
|
|
1342
|
-
if (Array.isArray(data)) {
|
|
1343
|
-
if (!data.length)
|
|
1344
|
-
return [];
|
|
1345
|
-
const rows = data;
|
|
1346
|
-
const idCol = tableId(this.table);
|
|
1347
|
-
const withId = rows.filter((r) => r?.id != null && r.id !== "");
|
|
1348
|
-
const withoutId = rows.filter((r) => r?.id == null || r.id === "");
|
|
1349
|
-
let existingIds = new Set;
|
|
1350
|
-
if (withId.length) {
|
|
1351
|
-
const found = await this.find(inArray3(idCol, withId.map((r) => r.id)));
|
|
1352
|
-
existingIds = new Set(found.map((r) => r.id));
|
|
1353
|
-
}
|
|
1354
|
-
const toUpdate = [];
|
|
1355
|
-
const toInsert = [...withoutId];
|
|
1356
|
-
for (const r of withId) {
|
|
1357
|
-
if (existingIds.has(r.id))
|
|
1358
|
-
toUpdate.push(r);
|
|
1359
|
-
else
|
|
1360
|
-
toInsert.push(r);
|
|
1361
|
-
}
|
|
1362
|
-
const updated = toUpdate.length ? await this.update(toUpdate) : [];
|
|
1363
|
-
const inserted = toInsert.length ? await this.create(toInsert) : [];
|
|
1364
|
-
return [
|
|
1365
|
-
...Array.isArray(updated) ? updated : updated ? [updated] : [],
|
|
1366
|
-
...Array.isArray(inserted) ? inserted : inserted ? [inserted] : []
|
|
1367
|
-
];
|
|
1368
|
-
}
|
|
1369
|
-
const record = data;
|
|
1370
|
-
const id = record?.id;
|
|
1371
|
-
if (id != null && id !== "") {
|
|
1372
|
-
const existing = await this.findById(id);
|
|
1373
|
-
if (existing) {
|
|
1374
|
-
const { id: _omit, ...patch } = record;
|
|
1375
|
-
const updated = await this.update(eq3(tableId(this.table), id), patch);
|
|
1376
|
-
return updated ?? existing;
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
return await this.create(data);
|
|
1380
|
-
}
|
|
1381
|
-
async update(whereOrRows, data) {
|
|
1382
|
-
if (Array.isArray(whereOrRows)) {
|
|
1383
|
-
return this.updateByRows(whereOrRows);
|
|
1384
|
-
}
|
|
1385
|
-
const patch = this.schema.update.parse(sanitizeWritePayload(data));
|
|
1386
|
-
const scoped = applyRowScopes(this.table, whereOrRows);
|
|
1387
|
-
if (!scoped)
|
|
1388
|
-
return;
|
|
1389
|
-
const [row] = await db().update(this.table).set(patch).where(scoped).returning();
|
|
1390
|
-
return row;
|
|
1391
|
-
}
|
|
1392
|
-
async updateByRows(rows) {
|
|
1393
|
-
if (!rows.length)
|
|
1394
|
-
return [];
|
|
1395
|
-
const idCol = tableId(this.table);
|
|
1396
|
-
const groups = new Map;
|
|
1397
|
-
for (const row of rows) {
|
|
1398
|
-
const id = row.id;
|
|
1399
|
-
if (id == null || id === "") {
|
|
1400
|
-
throw new Error("[Repository] \u6279\u91CF\u66F4\u65B0\u6BCF\u6761\u9700\u5E26 id");
|
|
1401
|
-
}
|
|
1402
|
-
const { id: _omit, ...rest } = row;
|
|
1403
|
-
const patch = this.schema.update.parse(sanitizeWritePayload(rest));
|
|
1404
|
-
const key = JSON.stringify(patch);
|
|
1405
|
-
const g = groups.get(key);
|
|
1406
|
-
if (g)
|
|
1407
|
-
g.ids.push(id);
|
|
1408
|
-
else
|
|
1409
|
-
groups.set(key, { ids: [id], patch });
|
|
1410
|
-
}
|
|
1411
|
-
const out = [];
|
|
1412
|
-
for (const { ids, patch } of groups.values()) {
|
|
1413
|
-
const scoped = applyRowScopes(this.table, inArray3(idCol, ids));
|
|
1414
|
-
if (!scoped)
|
|
1415
|
-
continue;
|
|
1416
|
-
const updated = await db().update(this.table).set(patch).where(scoped).returning();
|
|
1417
|
-
out.push(...updated);
|
|
1418
|
-
}
|
|
1419
|
-
return out;
|
|
1420
|
-
}
|
|
1421
|
-
resolveIdWhere(whereOrIds) {
|
|
1422
|
-
if (isSqlLike(whereOrIds)) {
|
|
1423
|
-
return applyRowScopes(this.table, whereOrIds);
|
|
1424
|
-
}
|
|
1425
|
-
const ids = Array.isArray(whereOrIds) ? whereOrIds : [whereOrIds];
|
|
1426
|
-
if (!ids.length)
|
|
1427
|
-
return;
|
|
1428
|
-
return applyRowScopes(this.table, inArray3(tableId(this.table), ids));
|
|
1429
|
-
}
|
|
1430
|
-
async softDelete(whereOrIds) {
|
|
1431
|
-
if (!this.supportsSoftDelete()) {
|
|
1432
|
-
throw new Error("[Repository] \u8868\u65E0 deletedAt\uFF0C\u65E0\u6CD5\u8F6F\u5220\u9664");
|
|
1433
|
-
}
|
|
1434
|
-
const scoped = this.resolveIdWhere(whereOrIds);
|
|
1435
|
-
if (!scoped)
|
|
1436
|
-
return;
|
|
1437
|
-
await db().update(this.table).set({ deletedAt: new Date }).where(scoped);
|
|
1438
|
-
}
|
|
1439
|
-
async restore(whereOrIds) {
|
|
1440
|
-
if (!this.supportsSoftDelete()) {
|
|
1441
|
-
throw new Error("[Repository] \u8868\u65E0 deletedAt\uFF0C\u65E0\u6CD5\u6062\u590D");
|
|
1442
|
-
}
|
|
1443
|
-
const scoped = this.resolveIdWhere(whereOrIds);
|
|
1444
|
-
if (!scoped)
|
|
1445
|
-
return;
|
|
1446
|
-
await db().update(this.table).set({ deletedAt: null }).where(scoped);
|
|
1447
|
-
}
|
|
1448
|
-
async forceDelete(whereOrIds) {
|
|
1449
|
-
const scoped = this.resolveIdWhere(whereOrIds);
|
|
1450
|
-
if (!scoped)
|
|
1451
|
-
return;
|
|
1452
|
-
await db().delete(this.table).where(scoped);
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
var repoCache = new WeakMap;
|
|
1456
|
-
function getRepository(table) {
|
|
1457
|
-
const cached = repoCache.get(table);
|
|
1458
|
-
if (cached)
|
|
1459
|
-
return cached;
|
|
1460
|
-
const repo = new Repository(table);
|
|
1461
|
-
repoCache.set(table, repo);
|
|
1462
|
-
return repo;
|
|
1463
|
-
}
|
|
1464
|
-
function InjectRepository(table) {
|
|
1465
|
-
return (target, propertyKey) => {
|
|
1466
|
-
appendInjectMeta(target.constructor, {
|
|
1467
|
-
propertyKey,
|
|
1468
|
-
resolve: () => getRepository(table)
|
|
1469
|
-
});
|
|
1470
|
-
};
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
// src/orm/service.ts
|
|
1474
|
-
function isSql(v) {
|
|
1475
|
-
return !!v && typeof v === "object" && v.getSQL != null;
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
class BaseService {
|
|
1479
|
-
entity;
|
|
1480
|
-
bindEntity(repo) {
|
|
1481
|
-
if (!this.entity)
|
|
1482
|
-
this.entity = repo;
|
|
1483
|
-
}
|
|
1484
|
-
setEntity(repo) {
|
|
1485
|
-
this.entity = repo;
|
|
1486
|
-
}
|
|
1487
|
-
hasEntity() {
|
|
1488
|
-
return !!this.entity;
|
|
1489
|
-
}
|
|
1490
|
-
getRepo() {
|
|
1491
|
-
return this.requireEntity();
|
|
1492
|
-
}
|
|
1493
|
-
requireEntity() {
|
|
1494
|
-
if (!this.entity) {
|
|
1495
|
-
throw new Error("[BaseService] \u672A\u7ED1\u5B9A\u5B9E\u4F53\uFF0C\u8BF7\u4F7F\u7528 @InjectRepository \u6216 setEntity");
|
|
1496
|
-
}
|
|
1497
|
-
return this.entity;
|
|
1498
|
-
}
|
|
1499
|
-
async modifyBefore(_data, _type) {}
|
|
1500
|
-
async modifyAfter(_data, _type) {}
|
|
1501
|
-
async add(data, options) {
|
|
1502
|
-
const mode = resolveUpsert(options?.upsert);
|
|
1503
|
-
const payload = Array.isArray(data) ? data.map((item) => item != null && typeof item === "object" ? { ...item } : item) : data != null && typeof data === "object" ? { ...data } : data;
|
|
1504
|
-
await this.modifyBefore(payload, "add");
|
|
1505
|
-
const result = mode === "save" ? await this.requireEntity().save(payload) : await this.requireEntity().create(payload);
|
|
1506
|
-
await this.modifyAfter(result ?? payload, "add");
|
|
1507
|
-
return result;
|
|
1508
|
-
}
|
|
1509
|
-
async update(whereOrData, data) {
|
|
1510
|
-
if (Array.isArray(whereOrData)) {
|
|
1511
|
-
const payloads = whereOrData.map((item) => ({ ...item }));
|
|
1512
|
-
await this.modifyBefore(payloads, "update");
|
|
1513
|
-
const result2 = await this.requireEntity().update(payloads);
|
|
1514
|
-
await this.modifyAfter(result2 ?? payloads, "update");
|
|
1515
|
-
return result2;
|
|
1516
|
-
}
|
|
1517
|
-
if (isSql(whereOrData)) {
|
|
1518
|
-
const payload = data != null && typeof data === "object" ? { ...data } : data;
|
|
1519
|
-
await this.modifyBefore(payload, "update");
|
|
1520
|
-
const result2 = await this.requireEntity().update(whereOrData, payload);
|
|
1521
|
-
await this.modifyAfter(result2 ?? payload, "update");
|
|
1522
|
-
return result2;
|
|
1523
|
-
}
|
|
1524
|
-
const row = { ...whereOrData };
|
|
1525
|
-
await this.modifyBefore(row, "update");
|
|
1526
|
-
const result = await this.requireEntity().update([row]);
|
|
1527
|
-
await this.modifyAfter(result ?? row, "update");
|
|
1528
|
-
return Array.isArray(result) ? result[0] : result;
|
|
1529
|
-
}
|
|
1530
|
-
async delete(whereOrIds, options) {
|
|
1531
|
-
const entity = this.requireEntity();
|
|
1532
|
-
await this.modifyBefore(whereOrIds, "delete");
|
|
1533
|
-
const soft = resolveSoftDelete(options?.softDelete);
|
|
1534
|
-
if (options?.force || !soft || !entity.supportsSoftDelete()) {
|
|
1535
|
-
await entity.forceDelete(whereOrIds);
|
|
1536
|
-
} else {
|
|
1537
|
-
await entity.softDelete(whereOrIds);
|
|
1538
|
-
}
|
|
1539
|
-
await this.modifyAfter(whereOrIds, "delete");
|
|
1540
|
-
}
|
|
1541
|
-
restore(whereOrIds) {
|
|
1542
|
-
return this.requireEntity().restore(whereOrIds);
|
|
1543
|
-
}
|
|
1544
|
-
list(where, options) {
|
|
1545
|
-
return this.requireEntity().find(where, options);
|
|
1546
|
-
}
|
|
1547
|
-
info(idOrWhere, options) {
|
|
1548
|
-
const entity = this.requireEntity();
|
|
1549
|
-
if (typeof idOrWhere === "object")
|
|
1550
|
-
return entity.findOne(idOrWhere, options);
|
|
1551
|
-
return entity.findById(idOrWhere, options);
|
|
1552
|
-
}
|
|
1553
|
-
page(query = {}) {
|
|
1554
|
-
const page = Math.max(1, query.page ?? 1);
|
|
1555
|
-
const size = Math.min(100, Math.max(1, query.size ?? 20));
|
|
1556
|
-
return this.requireEntity().findPage({
|
|
1557
|
-
page,
|
|
1558
|
-
size,
|
|
1559
|
-
where: query.where,
|
|
1560
|
-
orderBy: query.orderBy,
|
|
1561
|
-
withTrashed: query.withTrashed,
|
|
1562
|
-
onlyTrashed: query.onlyTrashed,
|
|
1563
|
-
softDelete: query.softDelete
|
|
1564
|
-
});
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
// src/routing/crud-summary.ts
|
|
1569
|
-
var CRUD_SUMMARY = {
|
|
1570
|
-
add: "\u65B0\u589E",
|
|
1571
|
-
delete: "\u5220\u9664",
|
|
1572
|
-
update: "\u4FEE\u6539",
|
|
1573
|
-
info: "\u5355\u4E2A\u4FE1\u606F",
|
|
1574
|
-
list: "\u5217\u8868\u67E5\u8BE2",
|
|
1575
|
-
page: "\u5206\u9875\u67E5\u8BE2",
|
|
1576
|
-
restore: "\u6062\u590D"
|
|
1577
|
-
};
|
|
1578
|
-
|
|
1579
|
-
// src/orm/crud-register.ts
|
|
1580
|
-
var CRUD_APIS = [
|
|
1581
|
-
"add",
|
|
1582
|
-
"delete",
|
|
1583
|
-
"update",
|
|
1584
|
-
"info",
|
|
1585
|
-
"list",
|
|
1586
|
-
"page",
|
|
1587
|
-
"restore"
|
|
1588
|
-
];
|
|
1589
|
-
var BEFORE_APIS = new Set(["add", "update", "delete", "restore"]);
|
|
1590
|
-
function omitProps(row, keys) {
|
|
1591
|
-
if (!row || !keys?.length)
|
|
1592
|
-
return row;
|
|
1593
|
-
const next = { ...row };
|
|
1594
|
-
for (const key of keys)
|
|
1595
|
-
delete next[key];
|
|
1596
|
-
return next;
|
|
1597
|
-
}
|
|
1598
|
-
function resolveIds(body) {
|
|
1599
|
-
if (Array.isArray(body)) {
|
|
1600
|
-
return body.map((item) => {
|
|
1601
|
-
if (item != null && typeof item === "object" && "id" in item) {
|
|
1602
|
-
return item.id;
|
|
1603
|
-
}
|
|
1604
|
-
return item;
|
|
1605
|
-
});
|
|
1606
|
-
}
|
|
1607
|
-
if (body && typeof body === "object") {
|
|
1608
|
-
const o = body;
|
|
1609
|
-
if (Array.isArray(o.ids))
|
|
1610
|
-
return o.ids;
|
|
1611
|
-
if (o.id != null)
|
|
1612
|
-
return [o.id];
|
|
1613
|
-
}
|
|
1614
|
-
return [];
|
|
1615
|
-
}
|
|
1616
|
-
function resolveService(meta) {
|
|
1617
|
-
const crud = meta.crud;
|
|
1618
|
-
const table = crud.entity;
|
|
1619
|
-
if (crud.service) {
|
|
1620
|
-
const svc2 = Ioc.get(crud.service);
|
|
1621
|
-
if (table && !svc2.hasEntity())
|
|
1622
|
-
svc2.setEntity(getRepository(table));
|
|
1623
|
-
return svc2;
|
|
1624
|
-
}
|
|
1625
|
-
if (!table) {
|
|
1626
|
-
throw new Error(`[CRUD] ${meta.token.name} \u9700\u914D\u7F6E entity \u6216 service`);
|
|
1627
|
-
}
|
|
1628
|
-
const svc = new class extends BaseService {
|
|
1629
|
-
};
|
|
1630
|
-
svc.setEntity(getRepository(table));
|
|
1631
|
-
return svc;
|
|
1632
|
-
}
|
|
1633
|
-
function tableOf(svc, meta) {
|
|
1634
|
-
const fromCrud = meta.crud?.entity;
|
|
1635
|
-
if (fromCrud)
|
|
1636
|
-
return fromCrud;
|
|
1637
|
-
return svc.getRepo().table;
|
|
1638
|
-
}
|
|
1639
|
-
var attachCrudRoutes = (plugin, meta, ctx) => {
|
|
1640
|
-
const crud = meta.crud;
|
|
1641
|
-
if (!crud)
|
|
1642
|
-
return plugin;
|
|
1643
|
-
const apis = (crud.api ?? []).filter((a) => CRUD_APIS.includes(a));
|
|
1644
|
-
const serviceApis = crud.serviceApis ?? [];
|
|
1645
|
-
if (!apis.length && !serviceApis.length)
|
|
1646
|
-
return plugin;
|
|
1647
|
-
const responder = ctx.controller instanceof BaseController ? ctx.controller : new BaseController;
|
|
1648
|
-
const needsEntity = apis.length > 0;
|
|
1649
|
-
const svc = needsEntity || crud.service ? resolveService(meta) : undefined;
|
|
1650
|
-
const table = needsEntity && svc ? tableOf(svc, meta) : undefined;
|
|
1651
|
-
const idCol = table ? table.id : undefined;
|
|
1652
|
-
if (needsEntity && idCol == null) {
|
|
1653
|
-
throw new Error(`[CRUD] ${meta.token.name} \u8868\u65E0 id \u5217`);
|
|
1654
|
-
}
|
|
1655
|
-
let next = plugin;
|
|
1656
|
-
const mount = (method, path, action, handler) => {
|
|
1657
|
-
next = next[method](path, handler, ctx.routeOptions({ action, summary: CRUD_SUMMARY[action] }));
|
|
1658
|
-
};
|
|
1659
|
-
const runBefore = async (api, body, request) => {
|
|
1660
|
-
if (!crud.before || !BEFORE_APIS.has(api))
|
|
1661
|
-
return body;
|
|
1662
|
-
await crud.before({ body, request, api });
|
|
1663
|
-
return body;
|
|
1664
|
-
};
|
|
1665
|
-
if (apis.includes("add") && svc) {
|
|
1666
|
-
mount("post", "/add", "add", async ({ body, request }) => {
|
|
1667
|
-
try {
|
|
1668
|
-
const raw = body;
|
|
1669
|
-
if (Array.isArray(raw)) {
|
|
1670
|
-
let list = raw;
|
|
1671
|
-
if (crud.before && BEFORE_APIS.has("add")) {
|
|
1672
|
-
for (let i = 0;i < list.length; i++) {
|
|
1673
|
-
list[i] = await runBefore("add", { ...list[i] ?? {} }, request);
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
if (crud.insertParam) {
|
|
1677
|
-
const extra = await crud.insertParam({ body: list[0] ?? {}, request });
|
|
1678
|
-
list = list.map((row2) => ({ ...row2, ...extra }));
|
|
1679
|
-
}
|
|
1680
|
-
const rows = await svc.add(list);
|
|
1681
|
-
return responder.ok(rows);
|
|
1682
|
-
}
|
|
1683
|
-
let data = { ...raw ?? {} };
|
|
1684
|
-
data = await runBefore("add", data, request);
|
|
1685
|
-
if (crud.insertParam) {
|
|
1686
|
-
Object.assign(data, await crud.insertParam({ body: data, request }));
|
|
1687
|
-
}
|
|
1688
|
-
const row = await svc.add(data);
|
|
1689
|
-
return responder.ok(row);
|
|
1690
|
-
} catch (e) {
|
|
1691
|
-
return responder.fail(e instanceof Error ? e.message : "add failed");
|
|
1692
|
-
}
|
|
1693
|
-
});
|
|
1694
|
-
}
|
|
1695
|
-
if (apis.includes("delete") && svc && idCol) {
|
|
1696
|
-
mount("post", "/delete", "delete", async ({ body, request }) => {
|
|
1697
|
-
try {
|
|
1698
|
-
const raw = body;
|
|
1699
|
-
const data = Array.isArray(raw) ? raw : await runBefore("delete", { ...raw ?? {} }, request);
|
|
1700
|
-
const ids = resolveIds(data);
|
|
1701
|
-
if (!ids.length)
|
|
1702
|
-
return responder.fail("ids required");
|
|
1703
|
-
const force = !Array.isArray(data) && !!data.force;
|
|
1704
|
-
await svc.delete(ids, { force });
|
|
1705
|
-
return responder.ok();
|
|
1706
|
-
} catch (e) {
|
|
1707
|
-
return responder.fail(e instanceof Error ? e.message : "delete failed");
|
|
1708
|
-
}
|
|
1709
|
-
});
|
|
1710
|
-
}
|
|
1711
|
-
if (apis.includes("update") && svc && idCol) {
|
|
1712
|
-
mount("post", "/update", "update", async ({ body, request }) => {
|
|
1713
|
-
try {
|
|
1714
|
-
const raw = body;
|
|
1715
|
-
if (Array.isArray(raw)) {
|
|
1716
|
-
let list = raw;
|
|
1717
|
-
if (crud.before && BEFORE_APIS.has("update")) {
|
|
1718
|
-
for (let i = 0;i < list.length; i++) {
|
|
1719
|
-
list[i] = await runBefore("update", { ...list[i] ?? {} }, request);
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
const rows = await svc.update(list);
|
|
1723
|
-
return responder.ok(rows);
|
|
1724
|
-
}
|
|
1725
|
-
const data = await runBefore("update", { ...raw ?? {} }, request);
|
|
1726
|
-
const id = data.id;
|
|
1727
|
-
if (id == null)
|
|
1728
|
-
return responder.fail("id required");
|
|
1729
|
-
const row = await svc.update(data);
|
|
1730
|
-
return responder.ok(row);
|
|
1731
|
-
} catch (e) {
|
|
1732
|
-
return responder.fail(e instanceof Error ? e.message : "update failed");
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
}
|
|
1736
|
-
if (apis.includes("info") && svc) {
|
|
1737
|
-
mount("get", "/info", "info", async ({ query }) => {
|
|
1738
|
-
try {
|
|
1739
|
-
const id = query?.id;
|
|
1740
|
-
if (id == null || id === "")
|
|
1741
|
-
return responder.fail("id required");
|
|
1742
|
-
const row = await svc.info(id);
|
|
1743
|
-
return responder.ok(omitProps(row, crud.infoIgnoreProperty));
|
|
1744
|
-
} catch (e) {
|
|
1745
|
-
return responder.fail(e instanceof Error ? e.message : "info failed");
|
|
1746
|
-
}
|
|
1747
|
-
});
|
|
1748
|
-
}
|
|
1749
|
-
if (apis.includes("list") && svc && table) {
|
|
1750
|
-
mount("post", "/list", "list", async ({ body, request }) => {
|
|
1751
|
-
try {
|
|
1752
|
-
const payload = body ?? {};
|
|
1753
|
-
const op = crud.listQueryOp ?? {};
|
|
1754
|
-
const trash = {
|
|
1755
|
-
onlyTrashed: payload.onlyTrashed === true,
|
|
1756
|
-
withTrashed: payload.withTrashed === true
|
|
1757
|
-
};
|
|
1758
|
-
if (needsAdvancedQuery(op)) {
|
|
1759
|
-
const list2 = await queryWithOp(table, payload, op, {
|
|
1760
|
-
request,
|
|
1761
|
-
mode: "list",
|
|
1762
|
-
trash
|
|
1763
|
-
});
|
|
1764
|
-
return responder.ok(list2);
|
|
1765
|
-
}
|
|
1766
|
-
const { where, orderBySql } = await buildQueryOp(table, payload, op, request);
|
|
1767
|
-
const list = await svc.list(where, { orderBy: orderBySql, ...trash });
|
|
1768
|
-
return responder.ok(list);
|
|
1769
|
-
} catch (e) {
|
|
1770
|
-
return responder.fail(e instanceof Error ? e.message : "list failed");
|
|
1771
|
-
}
|
|
1772
|
-
});
|
|
1773
|
-
}
|
|
1774
|
-
if (apis.includes("page") && svc && table) {
|
|
1775
|
-
mount("post", "/page", "page", async ({ body, request }) => {
|
|
1776
|
-
try {
|
|
1777
|
-
const payload = body ?? {};
|
|
1778
|
-
const op = crud.pageQueryOp ?? {};
|
|
1779
|
-
const trash = {
|
|
1780
|
-
onlyTrashed: payload.onlyTrashed === true,
|
|
1781
|
-
withTrashed: payload.withTrashed === true
|
|
1782
|
-
};
|
|
1783
|
-
if (needsAdvancedQuery(op)) {
|
|
1784
|
-
const result2 = await queryWithOp(table, payload, op, {
|
|
1785
|
-
request,
|
|
1786
|
-
mode: "page",
|
|
1787
|
-
trash
|
|
1788
|
-
});
|
|
1789
|
-
return responder.ok(result2);
|
|
1790
|
-
}
|
|
1791
|
-
const { where, orderBySql } = await buildQueryOp(table, payload, op, request);
|
|
1792
|
-
const result = await svc.page({
|
|
1793
|
-
page: Number(payload.page ?? 1),
|
|
1794
|
-
size: Number(payload.size ?? 20),
|
|
1795
|
-
where,
|
|
1796
|
-
orderBy: orderBySql,
|
|
1797
|
-
...trash
|
|
1798
|
-
});
|
|
1799
|
-
return responder.ok(result);
|
|
1800
|
-
} catch (e) {
|
|
1801
|
-
return responder.fail(e instanceof Error ? e.message : "page failed");
|
|
1802
|
-
}
|
|
1803
|
-
});
|
|
1804
|
-
}
|
|
1805
|
-
if (apis.includes("restore") && svc && idCol) {
|
|
1806
|
-
mount("post", "/restore", "restore", async ({ body, request }) => {
|
|
1807
|
-
try {
|
|
1808
|
-
const raw = body;
|
|
1809
|
-
const data = Array.isArray(raw) ? raw : await runBefore("restore", { ...raw ?? {} }, request);
|
|
1810
|
-
const ids = resolveIds(data);
|
|
1811
|
-
if (!ids.length)
|
|
1812
|
-
return responder.fail("ids required");
|
|
1813
|
-
await svc.restore(ids);
|
|
1814
|
-
return responder.ok();
|
|
1815
|
-
} catch (e) {
|
|
1816
|
-
return responder.fail(e instanceof Error ? e.message : "restore failed");
|
|
1817
|
-
}
|
|
1818
|
-
});
|
|
1819
|
-
}
|
|
1820
|
-
if (serviceApis.length) {
|
|
1821
|
-
if (!crud.service) {
|
|
1822
|
-
throw new Error(`[CRUD] ${meta.token.name} \u914D\u7F6E\u4E86 serviceApis\uFF0C\u9700\u540C\u65F6\u914D\u7F6E service`);
|
|
1823
|
-
}
|
|
1824
|
-
const biz = Ioc.get(crud.service);
|
|
1825
|
-
for (const name of serviceApis) {
|
|
1826
|
-
const method = biz[name];
|
|
1827
|
-
if (typeof method !== "function") {
|
|
1828
|
-
throw new Error(`[CRUD] ${crud.service.name}.${name} \u4E0D\u662F\u6709\u6548\u65B9\u6CD5`);
|
|
1829
|
-
}
|
|
1830
|
-
const bound = method.bind(biz);
|
|
1831
|
-
mount("post", `/${name}`, name, async ({ body }) => {
|
|
1832
|
-
try {
|
|
1833
|
-
const result = await bound(body);
|
|
1834
|
-
return responder.ok(result);
|
|
1835
|
-
} catch (e) {
|
|
1836
|
-
return responder.fail(e instanceof Error ? e.message : `${name} failed`);
|
|
1837
|
-
}
|
|
1838
|
-
});
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
return next;
|
|
1842
|
-
};
|
|
1843
|
-
|
|
1844
|
-
// src/ioc/host.ts
|
|
1845
|
-
import { join as join2 } from "path";
|
|
1846
|
-
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
1847
|
-
var SERVICE_PATTERN = "**/modules/*/service/**/*.ts";
|
|
1848
|
-
var CONTROLLER_SCANS = [
|
|
1849
|
-
{ pattern: "**/modules/*/controller/admin/**/*.ts", side: "admin" },
|
|
1850
|
-
{ pattern: "**/modules/*/controller/app/**/*.ts", side: "app" }
|
|
1851
|
-
];
|
|
1852
|
-
async function importWithContext(cwd, file, side) {
|
|
1853
|
-
setControllerScanContext({
|
|
1854
|
-
module: parseModuleFromPath(file),
|
|
1855
|
-
side,
|
|
1856
|
-
file
|
|
1857
|
-
});
|
|
1858
|
-
try {
|
|
1859
|
-
const href = pathToFileURL2(join2(cwd, file)).href;
|
|
1860
|
-
await import(href);
|
|
1861
|
-
} finally {
|
|
1862
|
-
setControllerScanContext(null);
|
|
1863
|
-
}
|
|
1864
|
-
}
|
|
1865
|
-
async function scanHost() {
|
|
1866
|
-
const cwd = process.cwd();
|
|
1867
|
-
const serviceFiles = await scanFiles(SERVICE_PATTERN, { cwd });
|
|
1868
|
-
for (const file of serviceFiles) {
|
|
1869
|
-
const href = pathToFileURL2(join2(cwd, file)).href;
|
|
1870
|
-
await import(href);
|
|
1871
|
-
}
|
|
1872
|
-
let controllerCount = 0;
|
|
1873
|
-
for (const { pattern, side } of CONTROLLER_SCANS) {
|
|
1874
|
-
const files = await scanFiles(pattern, { cwd });
|
|
1875
|
-
controllerCount += files.length;
|
|
1876
|
-
for (const file of files) {
|
|
1877
|
-
await importWithContext(cwd, file, side);
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
setCrudRegistrar(attachCrudRoutes);
|
|
1881
|
-
console.log(`[Host] crud \u2190 @vome-core/orm`);
|
|
1882
|
-
console.log(`[Host] scan \u2190 ${serviceFiles.length} service, ${controllerCount} controller file(s)`);
|
|
1883
|
-
}
|
|
1884
|
-
|
|
1885
|
-
// src/logger/pino.ts
|
|
1886
|
-
import { join as join4 } from "path";
|
|
1887
|
-
import { createPinoLogger } from "@bogeychan/elysia-logger";
|
|
1888
|
-
import pinoPretty from "pino-pretty";
|
|
1889
|
-
|
|
1890
|
-
// src/comm/daily-log.ts
|
|
1891
|
-
import {
|
|
1892
|
-
createWriteStream,
|
|
1893
|
-
mkdirSync,
|
|
1894
|
-
readdirSync,
|
|
1895
|
-
unlinkSync
|
|
1896
|
-
} from "fs";
|
|
1897
|
-
import { join as join3 } from "path";
|
|
1898
|
-
import { Writable } from "stream";
|
|
1899
|
-
var FILE_PATTERN = /^(\d{4}-\d{2}-\d{2})\.log$/;
|
|
1900
|
-
function formatLocalDate(date = new Date) {
|
|
1901
|
-
const y = date.getFullYear();
|
|
1902
|
-
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
1903
|
-
const d = String(date.getDate()).padStart(2, "0");
|
|
1904
|
-
return `${y}-${m}-${d}`;
|
|
1905
|
-
}
|
|
1906
|
-
function purgeOldLogs(dir, maxDays) {
|
|
1907
|
-
const cutoff = new Date;
|
|
1908
|
-
cutoff.setDate(cutoff.getDate() - maxDays);
|
|
1909
|
-
const cutoffStr = formatLocalDate(cutoff);
|
|
1910
|
-
for (const name of readdirSync(dir)) {
|
|
1911
|
-
const matched = name.match(FILE_PATTERN);
|
|
1912
|
-
if (!matched || matched[1] >= cutoffStr)
|
|
1913
|
-
continue;
|
|
1914
|
-
unlinkSync(join3(dir, name));
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
function openDailyStream(dir, date) {
|
|
1918
|
-
return createWriteStream(join3(dir, `${date}.log`), { flags: "a" });
|
|
1919
|
-
}
|
|
1920
|
-
function createDailyLogStream(dir, maxDays = 30) {
|
|
1921
|
-
mkdirSync(dir, { recursive: true });
|
|
1922
|
-
purgeOldLogs(dir, maxDays);
|
|
1923
|
-
let currentDate = formatLocalDate();
|
|
1924
|
-
let fileStream = openDailyStream(dir, currentDate);
|
|
1925
|
-
return new Writable({
|
|
1926
|
-
write(chunk, _encoding, callback) {
|
|
1927
|
-
const today = formatLocalDate();
|
|
1928
|
-
if (today !== currentDate) {
|
|
1929
|
-
fileStream.end();
|
|
1930
|
-
currentDate = today;
|
|
1931
|
-
fileStream = openDailyStream(dir, currentDate);
|
|
1932
|
-
purgeOldLogs(dir, maxDays);
|
|
1933
|
-
}
|
|
1934
|
-
fileStream.write(chunk, callback);
|
|
1935
|
-
},
|
|
1936
|
-
final(callback) {
|
|
1937
|
-
fileStream.end(callback);
|
|
1938
|
-
}
|
|
1939
|
-
});
|
|
1940
|
-
}
|
|
1941
|
-
|
|
1942
|
-
// src/logger/pino.ts
|
|
1943
|
-
var pinoInstance;
|
|
1944
|
-
function buildPino() {
|
|
1945
|
-
const logging = VomeConfig.logging ?? {};
|
|
1946
|
-
const level = logging.level ?? "info";
|
|
1947
|
-
if (logging.transport === "file") {
|
|
1948
|
-
const dir = join4(process.cwd(), logging.dir ?? "logging");
|
|
1949
|
-
const maxDays = logging.maxDays ?? 30;
|
|
1950
|
-
return createPinoLogger({
|
|
1951
|
-
level,
|
|
1952
|
-
stream: createDailyLogStream(dir, maxDays)
|
|
1953
|
-
});
|
|
1954
|
-
}
|
|
1955
|
-
return createPinoLogger({
|
|
1956
|
-
level,
|
|
1957
|
-
stream: pinoPretty({
|
|
1958
|
-
colorize: true,
|
|
1959
|
-
translateTime: "SYS:standard",
|
|
1960
|
-
ignore: "pid,hostname"
|
|
1961
|
-
})
|
|
1962
|
-
});
|
|
1963
|
-
}
|
|
1964
|
-
function getPinoLogger() {
|
|
1965
|
-
if (!pinoInstance)
|
|
1966
|
-
pinoInstance = buildPino();
|
|
1967
|
-
return pinoInstance;
|
|
1968
|
-
}
|
|
1969
|
-
function resetPinoLogger() {
|
|
1970
|
-
pinoInstance = undefined;
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
// src/logger/logger.ts
|
|
1974
|
-
class Logger {
|
|
1975
|
-
info(msg, ...args) {
|
|
1976
|
-
const log = getPinoLogger();
|
|
1977
|
-
if (args.length)
|
|
1978
|
-
log.info({ args }, msg);
|
|
1979
|
-
else
|
|
1980
|
-
log.info(msg);
|
|
1981
|
-
}
|
|
1982
|
-
warn(msg, ...args) {
|
|
1983
|
-
const log = getPinoLogger();
|
|
1984
|
-
if (args.length)
|
|
1985
|
-
log.warn({ args }, msg);
|
|
1986
|
-
else
|
|
1987
|
-
log.warn(msg);
|
|
1988
|
-
}
|
|
1989
|
-
debug(msg, ...args) {
|
|
1990
|
-
const log = getPinoLogger();
|
|
1991
|
-
if (args.length)
|
|
1992
|
-
log.debug({ args }, msg);
|
|
1993
|
-
else
|
|
1994
|
-
log.debug(msg);
|
|
1995
|
-
}
|
|
1996
|
-
error(msg, ...args) {
|
|
1997
|
-
const log = getPinoLogger();
|
|
1998
|
-
if (msg instanceof Error) {
|
|
1999
|
-
log.error(msg);
|
|
2000
|
-
return;
|
|
2001
|
-
}
|
|
2002
|
-
if (args[0] instanceof Error) {
|
|
2003
|
-
log.error(args[0], msg);
|
|
2004
|
-
return;
|
|
2005
|
-
}
|
|
2006
|
-
if (args.length)
|
|
2007
|
-
log.error({ args }, msg);
|
|
2008
|
-
else
|
|
2009
|
-
log.error(msg);
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
|
-
// src/logger/exception.ts
|
|
2013
|
-
class CommException extends Error {
|
|
2014
|
-
statusCode;
|
|
2015
|
-
code;
|
|
2016
|
-
constructor(message, options) {
|
|
2017
|
-
super(message);
|
|
2018
|
-
this.name = "CommException";
|
|
2019
|
-
this.statusCode = options?.statusCode ?? 200;
|
|
2020
|
-
this.code = options?.code ?? RES_CODE.ERROR;
|
|
2021
|
-
}
|
|
2022
|
-
}
|
|
2023
|
-
function isCommException(error) {
|
|
2024
|
-
return error instanceof CommException;
|
|
2025
|
-
}
|
|
2026
|
-
// src/logger/bootstrap.ts
|
|
2027
|
-
function bootstrapLogger() {
|
|
2028
|
-
getPinoLogger();
|
|
2029
|
-
Ioc.set(Logger, new Logger);
|
|
2030
|
-
}
|
|
2031
|
-
// src/comm/startBanner.ts
|
|
2032
|
-
var VOME_BANNER = `
|
|
2033
|
-
\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
2034
|
-
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|
|
2035
|
-
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557
|
|
2036
|
-
\u2588\u2588\u2557 \u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D
|
|
2037
|
-
\u255A\u2588\u2588\u2588\u2554\u255D \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
2038
|
-
\u255A\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
2039
|
-
`;
|
|
2040
|
-
function resetViewport() {
|
|
2041
|
-
if (!process.stdout.isTTY)
|
|
2042
|
-
return;
|
|
2043
|
-
process.stdout.write("\x1B[2J\x1B[H");
|
|
2044
|
-
}
|
|
2045
|
-
function printStartupBanner() {
|
|
2046
|
-
resetViewport();
|
|
2047
|
-
const env = getEnv();
|
|
2048
|
-
const port = VomeConfig.system?.port ?? 3001;
|
|
2049
|
-
const docsPath = VomeConfig.openapi?.path ?? "/docs";
|
|
2050
|
-
const baseUrl = `http://localhost:${port}`;
|
|
2051
|
-
console.log(VOME_BANNER);
|
|
2052
|
-
console.log(`\uD83C\uDF0D \u8FD0\u884C\u73AF\u5883: ${env}`);
|
|
2053
|
-
if (env === "dev") {
|
|
2054
|
-
console.log(`\uD83D\uDCE1 \u670D\u52A1\u5730\u5740: ${baseUrl}`);
|
|
2055
|
-
console.log(`\uD83D\uDCDA API\u6587\u6863: ${baseUrl}${docsPath.startsWith("/") ? docsPath : `/${docsPath}`}`);
|
|
2056
|
-
}
|
|
2057
|
-
}
|
|
2058
|
-
|
|
2059
|
-
// src/core/host-infra.ts
|
|
2060
|
-
import { access } from "fs/promises";
|
|
2061
|
-
import { join as join5 } from "path";
|
|
2062
|
-
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
2063
|
-
async function exists(abs) {
|
|
2064
|
-
try {
|
|
2065
|
-
await access(abs);
|
|
2066
|
-
return true;
|
|
2067
|
-
} catch {
|
|
2068
|
-
return false;
|
|
2069
|
-
}
|
|
2070
|
-
}
|
|
2071
|
-
async function importHostModule(relPath) {
|
|
2072
|
-
const abs = join5(process.cwd(), relPath);
|
|
2073
|
-
if (!await exists(abs)) {
|
|
2074
|
-
console.warn(`[Host] skip \u2190 missing ${relPath}`);
|
|
2075
|
-
return;
|
|
2076
|
-
}
|
|
2077
|
-
return await import(pathToFileURL3(abs).href);
|
|
2078
|
-
}
|
|
2079
|
-
async function bootstrapHostInfra() {
|
|
2080
|
-
const dbMod = await importHostModule("src/lib/db/index.ts");
|
|
2081
|
-
if (dbMod?.Db?.bootstrap)
|
|
2082
|
-
await dbMod.Db.bootstrap();
|
|
2083
|
-
const cacheMod = await importHostModule("src/lib/cache/index.ts");
|
|
2084
|
-
if (cacheMod?.Cache?.bootstrap)
|
|
2085
|
-
await cacheMod.Cache.bootstrap();
|
|
2086
|
-
const authMod = await importHostModule("src/lib/auth/index.ts");
|
|
2087
|
-
if (authMod?.Auth?.bootstrap)
|
|
2088
|
-
await authMod.Auth.bootstrap();
|
|
2089
|
-
}
|
|
2090
|
-
async function bootstrapHostTasks() {
|
|
2091
|
-
const mod = await importHostModule("src/lib/task/index.ts");
|
|
2092
|
-
if (mod?.Task?.bootstrap)
|
|
2093
|
-
await mod.Task.bootstrap();
|
|
2094
|
-
}
|
|
2095
|
-
async function bootstrapHostPlugins() {
|
|
2096
|
-
const mod = await importHostModule("src/lib/plugin/index.ts");
|
|
2097
|
-
if (mod?.Plugin?.bootstrap)
|
|
2098
|
-
await mod.Plugin.bootstrap();
|
|
2099
|
-
}
|
|
2100
|
-
async function bootstrapHostModules() {
|
|
2101
|
-
const mod = await importHostModule("src/lib/module/index.ts");
|
|
2102
|
-
if (mod?.Module?.bootstrap)
|
|
2103
|
-
await mod.Module.bootstrap();
|
|
2104
|
-
}
|
|
2105
|
-
async function shutdownHostTasks() {
|
|
2106
|
-
const mod = await importHostModule("src/lib/task/index.ts");
|
|
2107
|
-
if (mod?.Task?.close)
|
|
2108
|
-
await mod.Task.close();
|
|
2109
|
-
}
|
|
2110
|
-
async function shutdownHostInfra() {
|
|
2111
|
-
const cacheMod = await importHostModule("src/lib/cache/index.ts");
|
|
2112
|
-
if (cacheMod?.Cache?.close)
|
|
2113
|
-
await cacheMod.Cache.close();
|
|
2114
|
-
const dbMod = await importHostModule("src/lib/db/index.ts");
|
|
2115
|
-
if (dbMod?.Db?.close)
|
|
2116
|
-
await dbMod.Db.close();
|
|
2117
|
-
}
|
|
2118
|
-
async function applyHostAuthMiddleware(app) {
|
|
2119
|
-
const mod = await importHostModule("src/middleware/index.ts");
|
|
2120
|
-
if (!mod)
|
|
2121
|
-
return app;
|
|
2122
|
-
let next = app;
|
|
2123
|
-
if (mod.webAuth)
|
|
2124
|
-
next = next.use(mod.webAuth);
|
|
2125
|
-
if (mod.adminAuth)
|
|
2126
|
-
next = next.use(mod.adminAuth);
|
|
2127
|
-
if (mod.requestLog)
|
|
2128
|
-
next = next.use(mod.requestLog);
|
|
2129
|
-
if (mod.microApps)
|
|
2130
|
-
next = next.use(mod.microApps);
|
|
2131
|
-
if (mod.moduleGateway)
|
|
2132
|
-
next = next.use(mod.moduleGateway);
|
|
2133
|
-
return next;
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
// src/core/plugins/async-context.ts
|
|
2137
|
-
function applyAsyncContext(app) {
|
|
2138
|
-
const cfg = VomeConfig.asyncContextManager ?? {};
|
|
2139
|
-
if (!cfg.enable)
|
|
2140
|
-
return app;
|
|
2141
|
-
return app.onRequest(({ request }) => {
|
|
2142
|
-
enterContextWith(initContextFromRequest(request));
|
|
2143
|
-
});
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
// src/core/plugins/error.ts
|
|
2147
|
-
function applyErrorHandler(app) {
|
|
2148
|
-
return app.onError(({ error, set: set2, code }) => {
|
|
2149
|
-
const log = getPinoLogger();
|
|
2150
|
-
if (isCommException(error)) {
|
|
2151
|
-
log.error({ code: error.code }, error.message);
|
|
2152
|
-
set2.status = error.statusCode;
|
|
2153
|
-
return { code: error.code, message: error.message };
|
|
2154
|
-
}
|
|
2155
|
-
if (code === "VALIDATION") {
|
|
2156
|
-
const message = error instanceof Error ? error.message : "validation failed";
|
|
2157
|
-
log.error({ code }, message);
|
|
2158
|
-
set2.status = 422;
|
|
2159
|
-
return { code: RES_CODE.ERROR, message };
|
|
2160
|
-
}
|
|
2161
|
-
if (code === "NOT_FOUND") {
|
|
2162
|
-
set2.status = 404;
|
|
2163
|
-
return { code: RES_CODE.ERROR, message: "not found" };
|
|
2164
|
-
}
|
|
2165
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
2166
|
-
log.error(err);
|
|
2167
|
-
set2.status = 500;
|
|
2168
|
-
return {
|
|
2169
|
-
code: RES_CODE.ERROR,
|
|
2170
|
-
message: getEnv() === "dev" ? err.message : "internal server error"
|
|
2171
|
-
};
|
|
2172
|
-
});
|
|
2173
|
-
}
|
|
2174
|
-
|
|
2175
|
-
// src/core/plugins/logging.ts
|
|
2176
|
-
function applyLogging(app) {
|
|
2177
|
-
const log = getPinoLogger();
|
|
2178
|
-
return app.use(log.into({
|
|
2179
|
-
autoLogging: {
|
|
2180
|
-
ignore: (ctx) => Boolean(ctx.isError)
|
|
2181
|
-
}
|
|
2182
|
-
}));
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
// src/core/plugins/openapi.ts
|
|
2186
|
-
import { openapi } from "@elysiajs/openapi";
|
|
2187
|
-
function applyOpenapi(app) {
|
|
2188
|
-
const config = VomeConfig.openapi ?? { enable: false };
|
|
2189
|
-
if (config.enable === false)
|
|
2190
|
-
return app;
|
|
2191
|
-
const path = config.path ?? "/docs";
|
|
2192
|
-
const { tags, tagGroups } = buildOpenApiTagDocs();
|
|
2193
|
-
const userDoc = config.documentation ?? {};
|
|
2194
|
-
const userScalar = config.scalar ?? {};
|
|
2195
|
-
return app.use(openapi({
|
|
2196
|
-
path,
|
|
2197
|
-
documentation: {
|
|
2198
|
-
...userDoc,
|
|
2199
|
-
tags: [...userDoc.tags ?? [], ...tags],
|
|
2200
|
-
"x-tagGroups": tagGroups
|
|
2201
|
-
},
|
|
2202
|
-
scalar: {
|
|
2203
|
-
...userScalar,
|
|
2204
|
-
layout: userScalar.layout ?? "classic",
|
|
2205
|
-
operationTitleSource: userScalar.operationTitleSource ?? "summary"
|
|
2206
|
-
}
|
|
2207
|
-
}));
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
// src/core/app.ts
|
|
2211
|
-
var app;
|
|
2212
|
-
var started = false;
|
|
2213
|
-
var signalsRegistered = false;
|
|
2214
|
-
var hostScanned = false;
|
|
2215
|
-
var bootstrapHooks = [];
|
|
2216
|
-
var shutdownHooks = [];
|
|
2217
|
-
var usePlugins = [];
|
|
2218
|
-
async function ensureHostScanned() {
|
|
2219
|
-
if (hostScanned)
|
|
2220
|
-
return;
|
|
2221
|
-
hostScanned = true;
|
|
2222
|
-
await scanHost();
|
|
2223
|
-
}
|
|
2224
|
-
function createApp() {
|
|
2225
|
-
return applyAsyncContext(applyErrorHandler(applyLogging(new Elysia2)));
|
|
2226
|
-
}
|
|
2227
|
-
function bootstrap(hook) {
|
|
2228
|
-
bootstrapHooks.push(hook);
|
|
2229
|
-
}
|
|
2230
|
-
function shutdown(hook) {
|
|
2231
|
-
shutdownHooks.push(hook);
|
|
2232
|
-
}
|
|
2233
|
-
function use(setup) {
|
|
2234
|
-
usePlugins.push(setup);
|
|
2235
|
-
}
|
|
2236
|
-
async function start() {
|
|
2237
|
-
if (started) {
|
|
2238
|
-
throw new Error("[App] \u5DF2\u542F\u52A8\uFF0C\u8BF7\u5148 App.stop() \u518D start");
|
|
2239
|
-
}
|
|
2240
|
-
let next = createApp();
|
|
2241
|
-
next = await applyHostAuthMiddleware(next);
|
|
2242
|
-
for (const setup of usePlugins) {
|
|
2243
|
-
next = setup(next);
|
|
2244
|
-
}
|
|
2245
|
-
await ensureHostScanned();
|
|
2246
|
-
next = applyOpenapi(next);
|
|
2247
|
-
await bootstrapHostInfra();
|
|
2248
|
-
for (const hook of bootstrapHooks)
|
|
2249
|
-
await hook();
|
|
2250
|
-
bootstrapLogger();
|
|
2251
|
-
bootstrapIoc();
|
|
2252
|
-
await bootstrapHostPlugins();
|
|
2253
|
-
await bootstrapHostModules();
|
|
2254
|
-
await bootstrapHostTasks();
|
|
2255
|
-
next = registerControllers(next, VomeConfig);
|
|
2256
|
-
const port = VomeConfig.system?.port ?? 3001;
|
|
2257
|
-
next.listen(port);
|
|
2258
|
-
app = next;
|
|
2259
|
-
started = true;
|
|
2260
|
-
printStartupBanner();
|
|
2261
|
-
registerShutdownSignals();
|
|
2262
|
-
return app;
|
|
2263
|
-
}
|
|
2264
|
-
async function stop() {
|
|
2265
|
-
if (!app)
|
|
2266
|
-
return;
|
|
2267
|
-
for (const hook of shutdownHooks)
|
|
2268
|
-
await hook();
|
|
2269
|
-
await shutdownHostTasks();
|
|
2270
|
-
await shutdownHostInfra();
|
|
2271
|
-
await app.stop();
|
|
2272
|
-
app = undefined;
|
|
2273
|
-
started = false;
|
|
2274
|
-
hostScanned = false;
|
|
2275
|
-
resetIoc();
|
|
2276
|
-
resetPinoLogger();
|
|
2277
|
-
setCrudRegistrar(undefined);
|
|
2278
|
-
signalsRegistered = false;
|
|
2279
|
-
}
|
|
2280
|
-
function registerShutdownSignals() {
|
|
2281
|
-
if (signalsRegistered)
|
|
2282
|
-
return;
|
|
2283
|
-
signalsRegistered = true;
|
|
2284
|
-
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
2285
|
-
process.once(signal, async () => {
|
|
2286
|
-
await stop();
|
|
2287
|
-
process.exit(0);
|
|
2288
|
-
});
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
var App = {
|
|
2292
|
-
bootstrap,
|
|
2293
|
-
shutdown,
|
|
2294
|
-
use,
|
|
2295
|
-
start,
|
|
2296
|
-
stop
|
|
2297
|
-
};
|
|
2298
|
-
async function vome(setup) {
|
|
2299
|
-
if (setup)
|
|
2300
|
-
await setup({ App });
|
|
2301
|
-
return App.start();
|
|
2302
|
-
}
|
|
2303
|
-
// src/routing/eps.ts
|
|
2304
|
-
import { getTableColumns as getTableColumns3, getTableName as getTableName2 } from "drizzle-orm";
|
|
2305
|
-
|
|
2306
|
-
// src/orm/column-comments.ts
|
|
2307
|
-
import { getTableColumns as getTableColumns2, getTableName } from "drizzle-orm";
|
|
2308
|
-
|
|
2309
|
-
// src/orm/base-columns.ts
|
|
2310
|
-
import { integer, serial, timestamp } from "drizzle-orm/pg-core";
|
|
2311
|
-
var baseColumns = {
|
|
2312
|
-
id: serial("id").primaryKey(),
|
|
2313
|
-
createTime: timestamp("createTime", { withTimezone: true }).notNull().defaultNow(),
|
|
2314
|
-
updateTime: timestamp("updateTime", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => new Date),
|
|
2315
|
-
deletedAt: timestamp("deletedAt", { withTimezone: true }),
|
|
2316
|
-
tenantId: integer("tenantId")
|
|
2317
|
-
};
|
|
2318
|
-
var BASE_COLUMN_COMMENTS = {
|
|
2319
|
-
id: "ID",
|
|
2320
|
-
createTime: "\u521B\u5EFA\u65F6\u95F4",
|
|
2321
|
-
updateTime: "\u66F4\u65B0\u65F6\u95F4",
|
|
2322
|
-
deletedAt: "\u5220\u9664\u65F6\u95F4",
|
|
2323
|
-
tenantId: "\u79DF\u6237"
|
|
2324
|
-
};
|
|
2325
|
-
|
|
2326
|
-
// src/orm/column-comments.ts
|
|
2327
|
-
var registry = new WeakMap;
|
|
2328
|
-
var tables = new Set;
|
|
2329
|
-
function columnComments(table, comments = {}) {
|
|
2330
|
-
tables.add(table);
|
|
2331
|
-
registry.set(table, {
|
|
2332
|
-
...BASE_COLUMN_COMMENTS,
|
|
2333
|
-
...registry.get(table) || {},
|
|
2334
|
-
...comments
|
|
2335
|
-
});
|
|
2336
|
-
return table;
|
|
2337
|
-
}
|
|
2338
|
-
function getColumnComments(table) {
|
|
2339
|
-
return registry.get(table) || {};
|
|
2340
|
-
}
|
|
2341
|
-
function listColumnCommentTables() {
|
|
2342
|
-
return [...tables];
|
|
2343
|
-
}
|
|
2344
|
-
function quoteIdent(name) {
|
|
2345
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
2346
|
-
throw new Error(`[columnComments] \u975E\u6CD5\u6807\u8BC6\u7B26: ${name}`);
|
|
2347
|
-
}
|
|
2348
|
-
return `"${name}"`;
|
|
2349
|
-
}
|
|
2350
|
-
function escapeLiteral(value) {
|
|
2351
|
-
return value.replace(/'/g, "''");
|
|
2352
|
-
}
|
|
2353
|
-
async function syncColumnCommentsToPg(sql5) {
|
|
2354
|
-
const registered = listColumnCommentTables();
|
|
2355
|
-
if (!registered.length)
|
|
2356
|
-
return 0;
|
|
2357
|
-
const desired = new Map;
|
|
2358
|
-
const tableNames = [];
|
|
2359
|
-
for (const table of registered) {
|
|
2360
|
-
let name;
|
|
2361
|
-
try {
|
|
2362
|
-
name = getTableName(table);
|
|
2363
|
-
} catch {
|
|
2364
|
-
continue;
|
|
2365
|
-
}
|
|
2366
|
-
const cols = getTableColumns2(table);
|
|
2367
|
-
const comments = getColumnComments(table);
|
|
2368
|
-
const colMap = new Map;
|
|
2369
|
-
for (const [prop, text] of Object.entries(comments)) {
|
|
2370
|
-
if (!text || !(prop in cols))
|
|
2371
|
-
continue;
|
|
2372
|
-
colMap.set(prop, text);
|
|
2373
|
-
}
|
|
2374
|
-
if (!colMap.size)
|
|
2375
|
-
continue;
|
|
2376
|
-
desired.set(name, colMap);
|
|
2377
|
-
tableNames.push(name);
|
|
2378
|
-
}
|
|
2379
|
-
if (!tableNames.length)
|
|
2380
|
-
return 0;
|
|
2381
|
-
const inList = tableNames.map((t) => `'${escapeLiteral(t)}'`).join(",");
|
|
2382
|
-
const rows = await sql5.unsafe(`
|
|
2383
|
-
SELECT
|
|
2384
|
-
c.relname AS table_name,
|
|
2385
|
-
a.attname AS column_name,
|
|
2386
|
-
col_description(a.attrelid, a.attnum) AS comment
|
|
2387
|
-
FROM pg_catalog.pg_class c
|
|
2388
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
2389
|
-
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
|
2390
|
-
WHERE c.relkind = 'r'
|
|
2391
|
-
AND n.nspname = current_schema()
|
|
2392
|
-
AND a.attnum > 0
|
|
2393
|
-
AND NOT a.attisdropped
|
|
2394
|
-
AND c.relname IN (${inList})
|
|
2395
|
-
`);
|
|
2396
|
-
const existing = new Map;
|
|
2397
|
-
for (const row of rows || []) {
|
|
2398
|
-
if (!row.table_name || !row.column_name)
|
|
2399
|
-
continue;
|
|
2400
|
-
existing.set(`${row.table_name}.${row.column_name}`, row.comment ?? null);
|
|
2401
|
-
}
|
|
2402
|
-
let updated = 0;
|
|
2403
|
-
for (const [tableName, cols] of desired) {
|
|
2404
|
-
for (const [colName2, text] of cols) {
|
|
2405
|
-
const key = `${tableName}.${colName2}`;
|
|
2406
|
-
const cur = existing.get(key);
|
|
2407
|
-
if (cur === text)
|
|
2408
|
-
continue;
|
|
2409
|
-
await sql5.unsafe(`COMMENT ON COLUMN ${quoteIdent(tableName)}.${quoteIdent(colName2)} IS '${escapeLiteral(text)}'`);
|
|
2410
|
-
updated++;
|
|
2411
|
-
}
|
|
2412
|
-
}
|
|
2413
|
-
return updated;
|
|
2414
|
-
}
|
|
2415
|
-
|
|
2416
|
-
// src/routing/eps.ts
|
|
2417
|
-
var SIDE_PREFIX2 = {
|
|
2418
|
-
admin: "/admin",
|
|
2419
|
-
app: "/app"
|
|
2420
|
-
};
|
|
2421
|
-
function getSidePrefix2(side) {
|
|
2422
|
-
return normalizePrefix(SIDE_PREFIX2[side]);
|
|
2423
|
-
}
|
|
2424
|
-
function lastSegment(prefix) {
|
|
2425
|
-
const parts = prefix.replace(/^\/+|\/+$/g, "").split("/");
|
|
2426
|
-
return parts[parts.length - 1] || prefix || "index";
|
|
2427
|
-
}
|
|
2428
|
-
function toPascalEntityName(tableName) {
|
|
2429
|
-
return tableName.split("_").filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Entity";
|
|
2430
|
-
}
|
|
2431
|
-
function withAlias(fields) {
|
|
2432
|
-
if (!fields?.length)
|
|
2433
|
-
return [];
|
|
2434
|
-
return fields.map((f) => {
|
|
2435
|
-
if (typeof f !== "string") {
|
|
2436
|
-
const col = f.column;
|
|
2437
|
-
return {
|
|
2438
|
-
...f,
|
|
2439
|
-
column: col.includes(".") ? col : `a.${col}`
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
return f.includes(".") ? f : `a.${f}`;
|
|
2443
|
-
});
|
|
2444
|
-
}
|
|
2445
|
-
function normalizePageQueryOp(op) {
|
|
2446
|
-
return {
|
|
2447
|
-
keyWordLikeFields: withAlias(op?.keyWordLikeFields),
|
|
2448
|
-
fieldEq: withAlias(op?.fieldEq),
|
|
2449
|
-
fieldLike: withAlias(op?.fieldLike),
|
|
2450
|
-
fieldArray: withAlias(op?.fieldArray),
|
|
2451
|
-
fieldRange: (op?.fieldRange ?? []).map((r) => ({
|
|
2452
|
-
...r,
|
|
2453
|
-
column: r.column.includes(".") ? r.column : `a.${r.column}`
|
|
2454
|
-
}))
|
|
2455
|
-
};
|
|
2456
|
-
}
|
|
2457
|
-
function applyFieldDictToColumns(columns, fieldEq) {
|
|
2458
|
-
for (const ref of fieldEq) {
|
|
2459
|
-
if (typeof ref === "string" || !ref.dict)
|
|
2460
|
-
continue;
|
|
2461
|
-
const name = ref.column.includes(".") ? ref.column.split(".").pop() : ref.column;
|
|
2462
|
-
const col = columns.find((c) => c.propertyName === name);
|
|
2463
|
-
if (col)
|
|
2464
|
-
col.dict = ref.dict;
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
function columnsFromEntity(entity) {
|
|
2468
|
-
if (!entity || typeof entity !== "object")
|
|
2469
|
-
return [];
|
|
2470
|
-
try {
|
|
2471
|
-
const cols = getTableColumns3(entity);
|
|
2472
|
-
const comments = getColumnComments(entity);
|
|
2473
|
-
const list = [];
|
|
2474
|
-
for (const [propertyName, col] of Object.entries(cols)) {
|
|
2475
|
-
if (propertyName === "tenantId")
|
|
2476
|
-
continue;
|
|
2477
|
-
const c = col;
|
|
2478
|
-
list.push({
|
|
2479
|
-
propertyName,
|
|
2480
|
-
type: String(c.dataType ?? c.columnType ?? "string"),
|
|
2481
|
-
length: c.length != null ? String(c.length) : undefined,
|
|
2482
|
-
nullable: c.notNull !== true,
|
|
2483
|
-
source: `a.${propertyName}`,
|
|
2484
|
-
comment: comments[propertyName]
|
|
2485
|
-
});
|
|
2486
|
-
}
|
|
2487
|
-
const tail = new Set(["createTime", "updateTime", "deletedAt"]);
|
|
2488
|
-
const head = list.filter((c) => !tail.has(c.propertyName));
|
|
2489
|
-
const end = list.filter((c) => tail.has(c.propertyName));
|
|
2490
|
-
return [...head, ...end];
|
|
2491
|
-
} catch {
|
|
2492
|
-
return [];
|
|
2493
|
-
}
|
|
2494
|
-
}
|
|
2495
|
-
function entityNameOf(entity) {
|
|
2496
|
-
if (!entity || typeof entity !== "object")
|
|
2497
|
-
return;
|
|
2498
|
-
try {
|
|
2499
|
-
return toPascalEntityName(getTableName2(entity));
|
|
2500
|
-
} catch {
|
|
2501
|
-
return;
|
|
2502
|
-
}
|
|
2503
|
-
}
|
|
2504
|
-
function buildApis(meta, fullPrefix) {
|
|
2505
|
-
const apis = [];
|
|
2506
|
-
const seen = new Set;
|
|
2507
|
-
const push = (item) => {
|
|
2508
|
-
const key = `${item.method}:${item.path}`;
|
|
2509
|
-
if (seen.has(key))
|
|
2510
|
-
return;
|
|
2511
|
-
seen.add(key);
|
|
2512
|
-
apis.push(item);
|
|
2513
|
-
};
|
|
2514
|
-
for (const route of meta.routes) {
|
|
2515
|
-
const subPath = getRouteSubPath(route.path, meta.prefix);
|
|
2516
|
-
const path = subPath.startsWith("/") ? subPath : `/${subPath}`;
|
|
2517
|
-
const action = actionFromSubPath(path);
|
|
2518
|
-
push({
|
|
2519
|
-
method: route.method.toLowerCase(),
|
|
2520
|
-
path,
|
|
2521
|
-
summary: route.summary ?? "",
|
|
2522
|
-
dts: {},
|
|
2523
|
-
tag: "",
|
|
2524
|
-
prefix: fullPrefix,
|
|
2525
|
-
ignoreToken: Boolean(route.public),
|
|
2526
|
-
ignorePerms: Boolean(route.ignorePerms),
|
|
2527
|
-
perms: effectivePerms(route, meta, action) ?? []
|
|
2528
|
-
});
|
|
2529
|
-
}
|
|
2530
|
-
for (const name of meta.crud?.api ?? []) {
|
|
2531
|
-
const path = `/${name}`;
|
|
2532
|
-
push({
|
|
2533
|
-
method: name === "info" ? "get" : "post",
|
|
2534
|
-
path,
|
|
2535
|
-
summary: CRUD_SUMMARY[name] ?? name,
|
|
2536
|
-
dts: {},
|
|
2537
|
-
tag: "",
|
|
2538
|
-
prefix: fullPrefix,
|
|
2539
|
-
ignoreToken: false,
|
|
2540
|
-
ignorePerms: false,
|
|
2541
|
-
perms: effectivePerms({}, meta, name) ?? []
|
|
2542
|
-
});
|
|
2543
|
-
}
|
|
2544
|
-
for (const name of meta.crud?.serviceApis ?? []) {
|
|
2545
|
-
const path = `/${name}`;
|
|
2546
|
-
push({
|
|
2547
|
-
method: "post",
|
|
2548
|
-
path,
|
|
2549
|
-
summary: name,
|
|
2550
|
-
dts: {},
|
|
2551
|
-
tag: "",
|
|
2552
|
-
prefix: fullPrefix,
|
|
2553
|
-
ignoreToken: false,
|
|
2554
|
-
ignorePerms: false,
|
|
2555
|
-
perms: effectivePerms({}, meta, name) ?? []
|
|
2556
|
-
});
|
|
2557
|
-
}
|
|
2558
|
-
return apis;
|
|
2559
|
-
}
|
|
2560
|
-
function buildEntity(meta) {
|
|
2561
|
-
const fullPrefix = joinPrefix(getSidePrefix2(meta.side), meta.prefix);
|
|
2562
|
-
const typeName = lastSegment(meta.prefix);
|
|
2563
|
-
const entity = meta.crud?.entity;
|
|
2564
|
-
const columns = columnsFromEntity(entity);
|
|
2565
|
-
const pageQueryOp = normalizePageQueryOp(meta.crud?.pageQueryOp);
|
|
2566
|
-
applyFieldDictToColumns(columns, pageQueryOp.fieldEq);
|
|
2567
|
-
return {
|
|
2568
|
-
module: meta.module,
|
|
2569
|
-
side: meta.side,
|
|
2570
|
-
prefix: fullPrefix,
|
|
2571
|
-
name: entityNameOf(entity),
|
|
2572
|
-
info: {
|
|
2573
|
-
type: {
|
|
2574
|
-
name: typeName,
|
|
2575
|
-
description: meta.description ?? typeName
|
|
2576
|
-
}
|
|
2577
|
-
},
|
|
2578
|
-
api: buildApis(meta, fullPrefix),
|
|
2579
|
-
columns,
|
|
2580
|
-
pageQueryOp,
|
|
2581
|
-
pageColumns: columns
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
function groupByModule(list) {
|
|
2585
|
-
const map = {};
|
|
2586
|
-
for (const item of list) {
|
|
2587
|
-
const arr = map[item.module] ?? [];
|
|
2588
|
-
arr.push(item);
|
|
2589
|
-
map[item.module] = arr;
|
|
2590
|
-
}
|
|
2591
|
-
return map;
|
|
2592
|
-
}
|
|
2593
|
-
function isEpsEnabled() {
|
|
2594
|
-
return Boolean(VomeConfig.vome?.eps);
|
|
2595
|
-
}
|
|
2596
|
-
function buildEps(side) {
|
|
2597
|
-
if (!isEpsEnabled())
|
|
2598
|
-
return {};
|
|
2599
|
-
return groupByModule(listControllers(side).map(buildEntity));
|
|
2600
|
-
}
|
|
2601
|
-
var Eps = {
|
|
2602
|
-
controllers: listControllers,
|
|
2603
|
-
admin: () => buildEps("admin"),
|
|
2604
|
-
app: () => buildEps("app"),
|
|
2605
|
-
enabled: isEpsEnabled
|
|
2606
|
-
};
|
|
2607
|
-
// src/routing/decorators.ts
|
|
2608
|
-
import"reflect-metadata";
|
|
2609
|
-
var ROUTES_PENDING_KEY = "vome:controller:routes-pending";
|
|
2610
|
-
function joinRoute(prefix, path) {
|
|
2611
|
-
return joinPrefix(prefix, path === "/" ? "" : path);
|
|
2612
|
-
}
|
|
2613
|
-
function asMiddlewareList(mw) {
|
|
2614
|
-
if (mw == null)
|
|
2615
|
-
return;
|
|
2616
|
-
return Array.isArray(mw) ? mw : [mw];
|
|
2617
|
-
}
|
|
2618
|
-
function appendPendingRoute(ctor, route) {
|
|
2619
|
-
const list = Reflect.getMetadata(ROUTES_PENDING_KEY, ctor) ?? [];
|
|
2620
|
-
list.push(route);
|
|
2621
|
-
Reflect.defineMetadata(ROUTES_PENDING_KEY, list, ctor);
|
|
2622
|
-
}
|
|
2623
|
-
function createParamDecorator(source) {
|
|
2624
|
-
const label = source === "params" ? "Param" : source === "body" ? "Body" : "Query";
|
|
2625
|
-
return (schema) => (target, propertyKey, parameterIndex) => {
|
|
2626
|
-
if (propertyKey === undefined) {
|
|
2627
|
-
throw new Error(`[Controller] @${label} \u53EA\u80FD\u7528\u4E8E\u65B9\u6CD5\u53C2\u6570`);
|
|
2628
|
-
}
|
|
2629
|
-
const ctor = target.constructor;
|
|
2630
|
-
appendRouteParam(ctor, String(propertyKey), {
|
|
2631
|
-
index: parameterIndex,
|
|
2632
|
-
source,
|
|
2633
|
-
schema
|
|
2634
|
-
});
|
|
2635
|
-
};
|
|
2636
|
-
}
|
|
2637
|
-
function pickCrudOptions(options) {
|
|
2638
|
-
const {
|
|
2639
|
-
api,
|
|
2640
|
-
entity,
|
|
2641
|
-
service,
|
|
2642
|
-
serviceApis,
|
|
2643
|
-
before,
|
|
2644
|
-
pageQueryOp,
|
|
2645
|
-
listQueryOp,
|
|
2646
|
-
insertParam,
|
|
2647
|
-
infoIgnoreProperty
|
|
2648
|
-
} = options;
|
|
2649
|
-
if (api == null && entity == null && service == null && serviceApis == null && before == null && pageQueryOp == null && listQueryOp == null && insertParam == null && infoIgnoreProperty == null) {
|
|
2650
|
-
return;
|
|
2651
|
-
}
|
|
2652
|
-
return {
|
|
2653
|
-
api,
|
|
2654
|
-
entity,
|
|
2655
|
-
service,
|
|
2656
|
-
serviceApis,
|
|
2657
|
-
before,
|
|
2658
|
-
pageQueryOp,
|
|
2659
|
-
listQueryOp,
|
|
2660
|
-
insertParam,
|
|
2661
|
-
infoIgnoreProperty
|
|
2662
|
-
};
|
|
2663
|
-
}
|
|
2664
|
-
function Controller(prefixOrOptions = "") {
|
|
2665
|
-
const fromString = typeof prefixOrOptions === "string";
|
|
2666
|
-
const options = fromString ? { prefix: prefixOrOptions } : prefixOrOptions;
|
|
2667
|
-
return (target) => {
|
|
2668
|
-
registerProvider({
|
|
2669
|
-
token: target,
|
|
2670
|
-
useClass: target,
|
|
2671
|
-
scope: "singleton" /* Singleton */
|
|
2672
|
-
});
|
|
2673
|
-
const ctx = getControllerScanContext();
|
|
2674
|
-
const useAuto = fromString && prefixOrOptions === "" || !fromString && (options.prefix == null || options.prefix === "");
|
|
2675
|
-
const prefix = normalizePrefix(useAuto && ctx?.file ? parseControllerAutoPrefix(ctx.file) : options.prefix ?? "");
|
|
2676
|
-
const pending = Reflect.getMetadata(ROUTES_PENDING_KEY, target) ?? [];
|
|
2677
|
-
const crud = pickCrudOptions(options);
|
|
2678
|
-
registerController({
|
|
2679
|
-
token: target,
|
|
2680
|
-
prefix,
|
|
2681
|
-
module: options.module ?? ctx?.module ?? "unknown",
|
|
2682
|
-
side: options.side ?? ctx?.side ?? "admin",
|
|
2683
|
-
description: options.description,
|
|
2684
|
-
file: ctx?.file,
|
|
2685
|
-
middleware: asMiddlewareList(options.middleware),
|
|
2686
|
-
crud,
|
|
2687
|
-
routes: pending.map((route) => {
|
|
2688
|
-
const params = getRouteParams(target, route.handler);
|
|
2689
|
-
const schema = schemaFromParams(params);
|
|
2690
|
-
const routeMw = [
|
|
2691
|
-
...route.middleware ?? [],
|
|
2692
|
-
...getRouteMiddleware(target, route.handler)
|
|
2693
|
-
];
|
|
2694
|
-
return {
|
|
2695
|
-
...route,
|
|
2696
|
-
path: joinRoute(prefix, route.path.startsWith("/") ? route.path.slice(1) : route.path),
|
|
2697
|
-
params,
|
|
2698
|
-
body: schema?.body,
|
|
2699
|
-
query: schema?.query,
|
|
2700
|
-
routeParams: schema?.params,
|
|
2701
|
-
public: isRoutePublic(target, route.handler),
|
|
2702
|
-
ignorePerms: isRouteIgnorePerms(target, route.handler),
|
|
2703
|
-
perms: getRoutePerms(target, route.handler),
|
|
2704
|
-
middleware: routeMw.length ? routeMw : undefined
|
|
2705
|
-
};
|
|
2706
|
-
})
|
|
2707
|
-
});
|
|
2708
|
-
Reflect.deleteMetadata(ROUTES_PENDING_KEY, target);
|
|
2709
|
-
clearRouteParams(target);
|
|
2710
|
-
clearRoutePublic(target);
|
|
2711
|
-
clearRouteMiddleware(target);
|
|
2712
|
-
clearRoutePerms(target);
|
|
2713
|
-
clearRouteIgnorePerms(target);
|
|
2714
|
-
};
|
|
2715
|
-
}
|
|
2716
|
-
function Use(...middleware) {
|
|
2717
|
-
return (target, propertyKey) => {
|
|
2718
|
-
const ctor = target.constructor;
|
|
2719
|
-
appendRouteMiddleware(ctor, String(propertyKey), middleware);
|
|
2720
|
-
};
|
|
2721
|
-
}
|
|
2722
|
-
function createMethodDecorator(method) {
|
|
2723
|
-
return (path = "", options) => (target, propertyKey) => {
|
|
2724
|
-
const ctor = target.constructor;
|
|
2725
|
-
appendPendingRoute(ctor, {
|
|
2726
|
-
method,
|
|
2727
|
-
path,
|
|
2728
|
-
handler: String(propertyKey),
|
|
2729
|
-
summary: options?.summary
|
|
2730
|
-
});
|
|
2731
|
-
};
|
|
2732
|
-
}
|
|
2733
|
-
function Public() {
|
|
2734
|
-
return (target, propertyKey) => {
|
|
2735
|
-
const ctor = target.constructor;
|
|
2736
|
-
markRoutePublic(ctor, String(propertyKey));
|
|
2737
|
-
};
|
|
2738
|
-
}
|
|
2739
|
-
function Perms(...codes) {
|
|
2740
|
-
return (target, propertyKey) => {
|
|
2741
|
-
const ctor = target.constructor;
|
|
2742
|
-
setRoutePerms(ctor, String(propertyKey), codes);
|
|
2743
|
-
};
|
|
2744
|
-
}
|
|
2745
|
-
function IgnorePerms() {
|
|
2746
|
-
return (target, propertyKey) => {
|
|
2747
|
-
const ctor = target.constructor;
|
|
2748
|
-
markRouteIgnorePerms(ctor, String(propertyKey));
|
|
2749
|
-
};
|
|
2750
|
-
}
|
|
2751
|
-
var Body = createParamDecorator("body");
|
|
2752
|
-
var Query = createParamDecorator("query");
|
|
2753
|
-
var Param = createParamDecorator("params");
|
|
2754
|
-
var Get = createMethodDecorator("GET");
|
|
2755
|
-
var Post = createMethodDecorator("POST");
|
|
2756
|
-
var Put = createMethodDecorator("PUT");
|
|
2757
|
-
var Delete = createMethodDecorator("DELETE");
|
|
2758
|
-
var Patch = createMethodDecorator("PATCH");
|
|
2759
|
-
// src/ext/base-plugin.ts
|
|
2760
|
-
class BasePlugin {
|
|
2761
|
-
pluginInfo;
|
|
2762
|
-
ctx;
|
|
2763
|
-
cache;
|
|
2764
|
-
pluginService;
|
|
2765
|
-
async init(pluginInfo, ctx, _app, services) {
|
|
2766
|
-
this.pluginInfo = pluginInfo;
|
|
2767
|
-
this.ctx = ctx;
|
|
2768
|
-
this.cache = services?.cache;
|
|
2769
|
-
this.pluginService = services?.pluginService;
|
|
2770
|
-
await this.ready();
|
|
2771
|
-
}
|
|
2772
|
-
async ready() {}
|
|
2773
|
-
}
|
|
2774
|
-
// src/ext/load-plugin.ts
|
|
2775
|
-
import { existsSync, readFileSync } from "fs";
|
|
2776
|
-
import { createRequire } from "module";
|
|
2777
|
-
import { join as join7 } from "path";
|
|
2778
|
-
|
|
2779
|
-
// src/ext/path.ts
|
|
2780
|
-
import { createHash } from "crypto";
|
|
2781
|
-
import { homedir } from "os";
|
|
2782
|
-
import { join as join6 } from "path";
|
|
2783
|
-
function pDataPath() {
|
|
2784
|
-
const hash = createHash("md5").update(String(VomeConfig.keys ?? "vome")).digest("hex");
|
|
2785
|
-
return join6(homedir(), ".vome", hash);
|
|
2786
|
-
}
|
|
2787
|
-
function pPluginPath() {
|
|
2788
|
-
return join6(pDataPath(), "plugin");
|
|
2789
|
-
}
|
|
2790
|
-
function pModulesPath() {
|
|
2791
|
-
return join6(pDataPath(), "modules");
|
|
2792
|
-
}
|
|
2793
|
-
function pModulePath(key) {
|
|
2794
|
-
return join6(pModulesPath(), key);
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
// src/ext/load-plugin.ts
|
|
2798
|
-
var hostRequire = createRequire(import.meta.url);
|
|
2799
|
-
function pluginRequire(id) {
|
|
2800
|
-
if (id === "vome-plugin-runtime")
|
|
2801
|
-
return { BasePlugin };
|
|
2802
|
-
return hostRequire(id);
|
|
2803
|
-
}
|
|
2804
|
-
function loadPluginClass(content) {
|
|
2805
|
-
try {
|
|
2806
|
-
const normalized = content.replace(/export\s+const\s+Plugin\s*=/g, "var Plugin =").replace(/export\s+\{[^}]*\bPlugin\b[^}]*\};?/g, "").replace(/export\s+const\s+handlers\s*=/g, "var handlers =").replace(/export\s+\{[^}]*\bhandlers\b[^}]*\};?/g, "").replace(/export\s+class\s+(\w+)/g, "class $1").replace(/export\s+default\s+/g, "").replace(/import\s+\{?\s*BasePlugin\s*\}?\s*from\s*['"][^'"]+['"];?/g, "").replace(/import\s+BasePlugin\s+from\s*['"][^'"]+['"];?/g, "").replace(/require\(\s*['"]vome-plugin-runtime['"]\s*\)/g, "({ BasePlugin })");
|
|
2807
|
-
const fn = new Function("BasePlugin", "require", "module", "exports", `${normalized}
|
|
2808
|
-
var __Plugin = (typeof Plugin !== 'undefined')
|
|
2809
|
-
? Plugin
|
|
2810
|
-
: (module.exports && (module.exports.Plugin || module.exports.default || module.exports));
|
|
2811
|
-
if (typeof __Plugin === 'undefined' || __Plugin === null) {
|
|
2812
|
-
throw new Error('missing export Plugin');
|
|
2813
|
-
}
|
|
2814
|
-
return __Plugin;`);
|
|
2815
|
-
const mod = { exports: {} };
|
|
2816
|
-
return fn(BasePlugin, pluginRequire, mod, mod.exports);
|
|
2817
|
-
} catch (e) {
|
|
2818
|
-
throw new Error(`[Plugin] \u52A0\u8F7D\u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`);
|
|
2819
|
-
}
|
|
2820
|
-
}
|
|
2821
|
-
function readPluginScript(keyName) {
|
|
2822
|
-
const moduleServer = join7(pModulePath(keyName), "server", "index.js");
|
|
2823
|
-
if (existsSync(moduleServer)) {
|
|
2824
|
-
return readFileSync(moduleServer, "utf8");
|
|
2825
|
-
}
|
|
2826
|
-
const legacy = join7(pPluginPath(), keyName);
|
|
2827
|
-
if (!existsSync(legacy))
|
|
2828
|
-
return;
|
|
2829
|
-
try {
|
|
2830
|
-
const payload = JSON.parse(readFileSync(legacy, "utf8"));
|
|
2831
|
-
return payload.content?.data;
|
|
2832
|
-
} catch {
|
|
2833
|
-
return;
|
|
2834
|
-
}
|
|
2835
|
-
}
|
|
2836
|
-
// src/ext/module-registry.ts
|
|
2837
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync } from "fs";
|
|
2838
|
-
import { createRequire as createRequire2 } from "module";
|
|
2839
|
-
import { join as join8 } from "path";
|
|
2840
|
-
var registry2 = new Map;
|
|
2841
|
-
var hostRequire2 = createRequire2(import.meta.url);
|
|
2842
|
-
function pluginRequire2(id) {
|
|
2843
|
-
if (id === "vome-plugin-runtime")
|
|
2844
|
-
return { BasePlugin };
|
|
2845
|
-
return hostRequire2(id);
|
|
2846
|
-
}
|
|
2847
|
-
function normalizePath(path) {
|
|
2848
|
-
const p = path.startsWith("/") ? path : `/${path}`;
|
|
2849
|
-
return p.replace(/\/+$/, "") || "/";
|
|
2850
|
-
}
|
|
2851
|
-
function normalizeMethod(method) {
|
|
2852
|
-
return method.toUpperCase();
|
|
2853
|
-
}
|
|
2854
|
-
function normalizeModuleScript(content) {
|
|
2855
|
-
return content.replace(/export\s+const\s+handlers\s*=/g, "var handlers =").replace(/export\s+\{[^}]*\bhandlers\b[^}]*\};?/g, "").replace(/export\s+default\s+\{/g, "var handlers = {").replace(/export\s+const\s+Plugin\s*=/g, "var Plugin =").replace(/export\s+\{[^}]*\bPlugin\b[^}]*\};?/g, "").replace(/export\s+class\s+(\w+)/g, "class $1").replace(/import\s+\{?\s*BasePlugin\s*\}?\s*from\s*['"][^'"]+['"];?/g, "").replace(/import\s+BasePlugin\s+from\s*['"][^'"]+['"];?/g, "").replace(/require\(\s*['"]vome-plugin-runtime['"]\s*\)/g, "({ BasePlugin })");
|
|
2856
|
-
}
|
|
2857
|
-
function loadModuleHandlers(content, required = true) {
|
|
2858
|
-
const normalized = normalizeModuleScript(content);
|
|
2859
|
-
const fn = new Function("BasePlugin", "require", "module", "exports", `${normalized}
|
|
2860
|
-
if (typeof handlers === 'undefined') return null;
|
|
2861
|
-
return handlers;`);
|
|
2862
|
-
const mod = { exports: {} };
|
|
2863
|
-
const handlers = fn(BasePlugin, pluginRequire2, mod, mod.exports);
|
|
2864
|
-
if (!handlers || typeof handlers !== "object") {
|
|
2865
|
-
if (required)
|
|
2866
|
-
throw new Error("missing export handlers");
|
|
2867
|
-
return {};
|
|
2868
|
-
}
|
|
2869
|
-
return handlers;
|
|
2870
|
-
}
|
|
2871
|
-
var ModuleRegistry = {
|
|
2872
|
-
get(key) {
|
|
2873
|
-
return registry2.get(key);
|
|
2874
|
-
},
|
|
2875
|
-
list() {
|
|
2876
|
-
return [...registry2.entries()].map(([key, mod]) => ({
|
|
2877
|
-
key,
|
|
2878
|
-
manifest: mod.manifest,
|
|
2879
|
-
routes: mod.routes
|
|
2880
|
-
}));
|
|
2881
|
-
},
|
|
2882
|
-
load(key) {
|
|
2883
|
-
if (!key || !/^[a-zA-Z0-9_-]+$/.test(key)) {
|
|
2884
|
-
throw new Error(`\u975E\u6CD5\u6A21\u5757 key: ${key}`);
|
|
2885
|
-
}
|
|
2886
|
-
const dir = pModulePath(key);
|
|
2887
|
-
const metaPath = join8(dir, "module.json");
|
|
2888
|
-
if (!existsSync2(metaPath)) {
|
|
2889
|
-
throw new Error(`\u7F3A\u5C11 module.json: ${key}`);
|
|
2890
|
-
}
|
|
2891
|
-
const manifest = JSON.parse(readFileSync2(metaPath, "utf8"));
|
|
2892
|
-
const routes = (manifest.routes ?? []).map((r) => ({
|
|
2893
|
-
...r,
|
|
2894
|
-
method: normalizeMethod(r.method),
|
|
2895
|
-
path: normalizePath(r.path)
|
|
2896
|
-
}));
|
|
2897
|
-
let handlers = {};
|
|
2898
|
-
const serverEntry = join8(dir, "server", "index.js");
|
|
2899
|
-
if (existsSync2(serverEntry)) {
|
|
2900
|
-
const content = readFileSync2(serverEntry, "utf8");
|
|
2901
|
-
handlers = loadModuleHandlers(content, routes.length > 0);
|
|
2902
|
-
for (const route of routes) {
|
|
2903
|
-
if (typeof handlers[route.handler] !== "function") {
|
|
2904
|
-
throw new Error(`\u6A21\u5757 ${key} \u7F3A\u5C11 handler: ${route.handler}`);
|
|
2905
|
-
}
|
|
2906
|
-
}
|
|
2907
|
-
} else if (routes.length) {
|
|
2908
|
-
throw new Error(`\u6A21\u5757 ${key} \u58F0\u660E\u4E86 routes \u4F46\u7F3A\u5C11 server/index.js`);
|
|
2909
|
-
}
|
|
2910
|
-
registry2.set(key, { manifest, handlers, routes });
|
|
2911
|
-
return registry2.get(key);
|
|
2912
|
-
},
|
|
2913
|
-
unload(key) {
|
|
2914
|
-
registry2.delete(key);
|
|
2915
|
-
},
|
|
2916
|
-
async dispatch(key, method, subPath, ctx) {
|
|
2917
|
-
const mod = registry2.get(key);
|
|
2918
|
-
if (!mod) {
|
|
2919
|
-
return { ok: false, status: 404, message: "\u6A21\u5757\u672A\u52A0\u8F7D" };
|
|
2920
|
-
}
|
|
2921
|
-
const m = normalizeMethod(method);
|
|
2922
|
-
const path = normalizePath(subPath);
|
|
2923
|
-
const route = mod.routes.find((r) => r.method === m && r.path === path);
|
|
2924
|
-
if (!route) {
|
|
2925
|
-
return { ok: false, status: 404, message: "\u8DEF\u7531\u4E0D\u5B58\u5728" };
|
|
2926
|
-
}
|
|
2927
|
-
const handler = mod.handlers[route.handler];
|
|
2928
|
-
if (typeof handler !== "function") {
|
|
2929
|
-
return { ok: false, status: 500, message: `handler \u7F3A\u5931: ${route.handler}` };
|
|
2930
|
-
}
|
|
2931
|
-
try {
|
|
2932
|
-
const data = await handler(ctx);
|
|
2933
|
-
return { ok: true, data, route };
|
|
2934
|
-
} catch (e) {
|
|
2935
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
2936
|
-
return { ok: false, status: 500, message, route };
|
|
2937
|
-
}
|
|
2938
|
-
},
|
|
2939
|
-
bootstrap() {
|
|
2940
|
-
const root = pModulesPath();
|
|
2941
|
-
if (!existsSync2(root))
|
|
2942
|
-
return;
|
|
2943
|
-
for (const name of readdirSync2(root)) {
|
|
2944
|
-
const dir = join8(root, name);
|
|
2945
|
-
if (!statSync(dir).isDirectory())
|
|
2946
|
-
continue;
|
|
2947
|
-
if (!existsSync2(join8(dir, "module.json")))
|
|
2948
|
-
continue;
|
|
2949
|
-
try {
|
|
2950
|
-
this.load(name);
|
|
2951
|
-
console.log(`[Module] loaded ${name}`);
|
|
2952
|
-
} catch (e) {
|
|
2953
|
-
console.warn(`[Module] load failed ${name}:`, e instanceof Error ? e.message : e);
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
|
-
}
|
|
2957
|
-
};
|
|
2958
|
-
// src/ext/micro-apps.ts
|
|
2959
|
-
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
2960
|
-
import { join as join9, normalize, sep } from "path";
|
|
2961
|
-
import { Elysia as Elysia3 } from "elysia";
|
|
2962
|
-
var PREFIX = "/vome/apps";
|
|
2963
|
-
function contentType(filePath) {
|
|
2964
|
-
const lower = filePath.toLowerCase();
|
|
2965
|
-
if (lower.endsWith(".html"))
|
|
2966
|
-
return "text/html; charset=utf-8";
|
|
2967
|
-
if (lower.endsWith(".js") || lower.endsWith(".mjs"))
|
|
2968
|
-
return "application/javascript; charset=utf-8";
|
|
2969
|
-
if (lower.endsWith(".css"))
|
|
2970
|
-
return "text/css; charset=utf-8";
|
|
2971
|
-
if (lower.endsWith(".json"))
|
|
2972
|
-
return "application/json; charset=utf-8";
|
|
2973
|
-
if (lower.endsWith(".svg"))
|
|
2974
|
-
return "image/svg+xml";
|
|
2975
|
-
if (lower.endsWith(".png"))
|
|
2976
|
-
return "image/png";
|
|
2977
|
-
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg"))
|
|
2978
|
-
return "image/jpeg";
|
|
2979
|
-
if (lower.endsWith(".woff2"))
|
|
2980
|
-
return "font/woff2";
|
|
2981
|
-
if (lower.endsWith(".woff"))
|
|
2982
|
-
return "font/woff";
|
|
2983
|
-
if (lower.endsWith(".map"))
|
|
2984
|
-
return "application/json";
|
|
2985
|
-
return "application/octet-stream";
|
|
2986
|
-
}
|
|
2987
|
-
var microApps = new Elysia3({ name: "micro-apps-static" }).get(`${PREFIX}/*`, ({ params, set: set2 }) => {
|
|
2988
|
-
const star = String(params["*"] || "");
|
|
2989
|
-
const parts = star.split("/").filter(Boolean);
|
|
2990
|
-
if (!parts.length) {
|
|
2991
|
-
set2.status = 404;
|
|
2992
|
-
return "Not Found";
|
|
2993
|
-
}
|
|
2994
|
-
const key = parts[0];
|
|
2995
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(key)) {
|
|
2996
|
-
set2.status = 400;
|
|
2997
|
-
return "Invalid app key";
|
|
2998
|
-
}
|
|
2999
|
-
const root = join9(pModulePath(key), "web");
|
|
3000
|
-
if (!existsSync3(root) || !statSync2(root).isDirectory()) {
|
|
3001
|
-
set2.status = 404;
|
|
3002
|
-
return "App not found";
|
|
3003
|
-
}
|
|
3004
|
-
let sub = parts.slice(1).join("/") || "index.html";
|
|
3005
|
-
if (sub.endsWith("/"))
|
|
3006
|
-
sub += "index.html";
|
|
3007
|
-
const resolved = normalize(join9(root, sub));
|
|
3008
|
-
if (!resolved.startsWith(root + sep) && resolved !== root) {
|
|
3009
|
-
set2.status = 403;
|
|
3010
|
-
return "Forbidden";
|
|
3011
|
-
}
|
|
3012
|
-
let filePath = resolved;
|
|
3013
|
-
if (existsSync3(filePath) && statSync2(filePath).isDirectory()) {
|
|
3014
|
-
filePath = join9(filePath, "index.html");
|
|
3015
|
-
}
|
|
3016
|
-
if (!existsSync3(filePath) || !statSync2(filePath).isFile()) {
|
|
3017
|
-
set2.status = 404;
|
|
3018
|
-
return "Not Found";
|
|
3019
|
-
}
|
|
3020
|
-
set2.headers["content-type"] = contentType(filePath);
|
|
3021
|
-
set2.headers["cache-control"] = "no-cache";
|
|
3022
|
-
set2.headers["access-control-allow-origin"] = "*";
|
|
3023
|
-
return Bun.file(filePath);
|
|
3024
|
-
});
|
|
3025
|
-
// src/ext/module-gateway.ts
|
|
3026
|
-
import { Elysia as Elysia4 } from "elysia";
|
|
3027
|
-
function ok(data) {
|
|
3028
|
-
return { code: RES_CODE.SUCCESS, message: "success", data: data ?? null };
|
|
3029
|
-
}
|
|
3030
|
-
function fail(message, code = RES_CODE.ERROR) {
|
|
3031
|
-
return { code, message };
|
|
3032
|
-
}
|
|
3033
|
-
async function handleExt(ctx) {
|
|
3034
|
-
const key = ctx.params.key;
|
|
3035
|
-
if (!key || !/^[a-zA-Z0-9_-]+$/.test(key)) {
|
|
3036
|
-
ctx.set.status = 400;
|
|
3037
|
-
return fail("\u975E\u6CD5\u6A21\u5757 key");
|
|
3038
|
-
}
|
|
3039
|
-
const star = String(ctx.params["*"] || "");
|
|
3040
|
-
const subPath = `/${star}`.replace(/\/+/g, "/");
|
|
3041
|
-
const store = Context.get();
|
|
3042
|
-
const mod = ModuleRegistry.get(key);
|
|
3043
|
-
if (!mod) {
|
|
3044
|
-
ctx.set.status = 404;
|
|
3045
|
-
return fail("\u6A21\u5757\u672A\u5B89\u88C5\u6216\u672A\u52A0\u8F7D");
|
|
3046
|
-
}
|
|
3047
|
-
const method = ctx.request.method.toUpperCase();
|
|
3048
|
-
const pathNorm = subPath.replace(/\/+$/, "") || "/";
|
|
3049
|
-
const route = mod.routes.find((r) => r.method === method && r.path === pathNorm);
|
|
3050
|
-
if (!route) {
|
|
3051
|
-
ctx.set.status = 404;
|
|
3052
|
-
return fail("\u8DEF\u7531\u4E0D\u5B58\u5728");
|
|
3053
|
-
}
|
|
3054
|
-
if (route.perms && !store?.isSuper) {
|
|
3055
|
-
const held = store?.perms ?? [];
|
|
3056
|
-
if (!held.includes(route.perms)) {
|
|
3057
|
-
return ctx.status(403);
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
const result = await ModuleRegistry.dispatch(key, method, subPath, {
|
|
3061
|
-
body: ctx.body,
|
|
3062
|
-
query: ctx.query ?? {},
|
|
3063
|
-
params: ctx.params,
|
|
3064
|
-
headers: ctx.request.headers,
|
|
3065
|
-
adminId: store?.adminId
|
|
3066
|
-
});
|
|
3067
|
-
if (!result.ok) {
|
|
3068
|
-
ctx.set.status = result.status;
|
|
3069
|
-
return fail(result.message);
|
|
3070
|
-
}
|
|
3071
|
-
return ok(result.data);
|
|
3072
|
-
}
|
|
3073
|
-
function createModuleGateway(options) {
|
|
3074
|
-
return new Elysia4({ name: "module-gateway" }).use(options.adminAuth).all("/admin/ext/:key/*", handleExt, { adminAuth: true }).all("/admin/ext/:key", handleExt, { adminAuth: true });
|
|
3075
|
-
}
|
|
3076
|
-
// src/auth/define-macro.ts
|
|
3077
|
-
import { Elysia as Elysia5 } from "elysia";
|
|
3078
|
-
function defineAuthMacro(name, resolve) {
|
|
3079
|
-
return new Elysia5({ name: `${name}-macro` }).macro({
|
|
3080
|
-
[name]: { resolve }
|
|
3081
|
-
}).as("scoped");
|
|
3082
|
-
}
|
|
3083
|
-
// package.json
|
|
3084
|
-
var package_default = {
|
|
3085
|
-
name: "vome-core",
|
|
3086
|
-
version: "0.0.9",
|
|
3087
|
-
description: "Vome framework \u2014 shared + Bun/Elysia server + Vue admin",
|
|
3088
|
-
license: "MIT",
|
|
3089
|
-
type: "module",
|
|
3090
|
-
files: [
|
|
3091
|
-
"dist",
|
|
3092
|
-
"src/admin",
|
|
3093
|
-
"src/shared",
|
|
3094
|
-
"typings/admin"
|
|
3095
|
-
],
|
|
3096
|
-
main: "./dist/index.js",
|
|
3097
|
-
types: "./dist/index.d.ts",
|
|
3098
|
-
exports: {
|
|
3099
|
-
".": {
|
|
3100
|
-
types: "./dist/index.d.ts",
|
|
3101
|
-
import: "./dist/index.js",
|
|
3102
|
-
default: "./dist/index.js"
|
|
3103
|
-
},
|
|
3104
|
-
"./server": {
|
|
3105
|
-
types: "./dist/server/index.d.ts",
|
|
3106
|
-
import: "./dist/server/index.js",
|
|
3107
|
-
default: "./dist/server/index.js"
|
|
3108
|
-
},
|
|
3109
|
-
"./admin": {
|
|
3110
|
-
types: "./src/admin/index.ts",
|
|
3111
|
-
import: "./src/admin/index.ts",
|
|
3112
|
-
default: "./src/admin/index.ts"
|
|
3113
|
-
},
|
|
3114
|
-
"./admin/*": "./src/admin/*",
|
|
3115
|
-
"./admin/styles/base.css": "./src/admin/styles/base.css",
|
|
3116
|
-
"./typings/*": "./typings/admin/*"
|
|
3117
|
-
},
|
|
3118
|
-
scripts: {
|
|
3119
|
-
build: `rm -rf dist && bun build ./src/index.ts ./src/server/index.ts --outdir ./dist --target bun --format esm --external elysia --external reflect-metadata --external drizzle-orm --external drizzle-zod --external @elysiajs/openapi --external @bogeychan/elysia-logger --external pino --external pino-pretty && tsc -p tsconfig.build.json && printf "%s\\n" "export * from '../src/index'" > dist/index.d.ts && mkdir -p dist/server && printf "%s\\n" "export * from '../../src/server/index'" > dist/server/index.d.ts`,
|
|
3120
|
-
"build:obfuscate": `rm -rf dist && bun build ./src/index.ts ./src/server/index.ts --outdir ./dist --target bun --format esm --minify --external elysia --external reflect-metadata --external drizzle-orm --external drizzle-zod --external @elysiajs/openapi --external @bogeychan/elysia-logger --external pino --external pino-pretty && tsc -p tsconfig.build.json && printf "%s\\n" "export * from '../src/index'" > dist/index.d.ts && mkdir -p dist/server && printf "%s\\n" "export * from '../../src/server/index'" > dist/server/index.d.ts && bun scripts/obfuscate.ts`,
|
|
3121
|
-
prepare: "bun run build"
|
|
3122
|
-
},
|
|
3123
|
-
peerDependencies: {
|
|
3124
|
-
elysia: ">=1.0.0",
|
|
3125
|
-
"reflect-metadata": ">=0.2.0",
|
|
3126
|
-
"drizzle-orm": ">=0.30.0",
|
|
3127
|
-
"drizzle-zod": ">=0.5.0",
|
|
3128
|
-
vue: ">=3.5.0",
|
|
3129
|
-
"vue-router": ">=4.0.0",
|
|
3130
|
-
pinia: ">=2.0.0",
|
|
3131
|
-
"vue-sonner": ">=2.0.0",
|
|
3132
|
-
"@vueuse/core": ">=10.0.0",
|
|
3133
|
-
clsx: ">=2.0.0",
|
|
3134
|
-
"tailwind-merge": ">=2.0.0",
|
|
3135
|
-
dompurify: ">=3.0.0",
|
|
3136
|
-
marked: ">=9.0.0"
|
|
3137
|
-
},
|
|
3138
|
-
peerDependenciesMeta: {
|
|
3139
|
-
"drizzle-orm": {
|
|
3140
|
-
optional: true
|
|
3141
|
-
},
|
|
3142
|
-
"drizzle-zod": {
|
|
3143
|
-
optional: true
|
|
3144
|
-
},
|
|
3145
|
-
vue: {
|
|
3146
|
-
optional: true
|
|
3147
|
-
},
|
|
3148
|
-
"vue-router": {
|
|
3149
|
-
optional: true
|
|
3150
|
-
},
|
|
3151
|
-
pinia: {
|
|
3152
|
-
optional: true
|
|
3153
|
-
},
|
|
3154
|
-
"vue-sonner": {
|
|
3155
|
-
optional: true
|
|
3156
|
-
},
|
|
3157
|
-
"@vueuse/core": {
|
|
3158
|
-
optional: true
|
|
3159
|
-
},
|
|
3160
|
-
clsx: {
|
|
3161
|
-
optional: true
|
|
3162
|
-
},
|
|
3163
|
-
"tailwind-merge": {
|
|
3164
|
-
optional: true
|
|
3165
|
-
},
|
|
3166
|
-
dompurify: {
|
|
3167
|
-
optional: true
|
|
3168
|
-
},
|
|
3169
|
-
marked: {
|
|
3170
|
-
optional: true
|
|
3171
|
-
}
|
|
3172
|
-
},
|
|
3173
|
-
devDependencies: {
|
|
3174
|
-
"bun-types": "latest",
|
|
3175
|
-
"drizzle-orm": "latest",
|
|
3176
|
-
"drizzle-zod": "^0.8.3",
|
|
3177
|
-
elysia: "latest",
|
|
3178
|
-
"javascript-obfuscator": "^5.4.7",
|
|
3179
|
-
"reflect-metadata": "^0.2.2",
|
|
3180
|
-
typescript: "latest"
|
|
3181
|
-
},
|
|
3182
|
-
dependencies: {
|
|
3183
|
-
"@bogeychan/elysia-logger": "^0.1.10",
|
|
3184
|
-
"@elysiajs/openapi": "^1.4.15",
|
|
3185
|
-
pino: "^10.3.1",
|
|
3186
|
-
"pino-pretty": "^13.1.3"
|
|
3187
|
-
}
|
|
3188
|
-
};
|
|
3189
|
-
|
|
3190
|
-
// src/server/index.ts
|
|
3191
|
-
var version = package_default.version;
|
|
3192
|
-
export {
|
|
3193
|
-
vome,
|
|
3194
|
-
version,
|
|
3195
|
-
tableHasDepartmentId,
|
|
3196
|
-
syncColumnCommentsToPg,
|
|
3197
|
-
scanFiles,
|
|
3198
|
-
resolveTenantScope,
|
|
3199
|
-
resolveDataScope,
|
|
3200
|
-
readPluginScript,
|
|
3201
|
-
q,
|
|
3202
|
-
pPluginPath,
|
|
3203
|
-
pModulesPath,
|
|
3204
|
-
pModulePath,
|
|
3205
|
-
pDataPath,
|
|
3206
|
-
normalizeHost,
|
|
3207
|
-
noTenant,
|
|
3208
|
-
noDataScope,
|
|
3209
|
-
microApps,
|
|
3210
|
-
loadPluginClass,
|
|
3211
|
-
loadModuleHandlers,
|
|
3212
|
-
listProviders,
|
|
3213
|
-
listControllers,
|
|
3214
|
-
isTenantEnabled,
|
|
3215
|
-
isEpsEnabled,
|
|
3216
|
-
isCommException,
|
|
3217
|
-
getRepository,
|
|
3218
|
-
getEnv,
|
|
3219
|
-
getColumnComments,
|
|
3220
|
-
entitySchemas,
|
|
3221
|
-
defineAuthMacro,
|
|
3222
|
-
createModuleGateway,
|
|
3223
|
-
columnComments,
|
|
3224
|
-
baseColumns,
|
|
3225
|
-
attachCrudRoutes,
|
|
3226
|
-
applyRowScopes,
|
|
3227
|
-
applyDataScopeWhere,
|
|
3228
|
-
appendInjectMeta,
|
|
3229
|
-
VomeConfig,
|
|
3230
|
-
Use,
|
|
3231
|
-
ScopeEnum,
|
|
3232
|
-
Repository,
|
|
3233
|
-
RES_CODE,
|
|
3234
|
-
Query,
|
|
3235
|
-
Put,
|
|
3236
|
-
Public,
|
|
3237
|
-
Provide,
|
|
3238
|
-
Post,
|
|
3239
|
-
Perms,
|
|
3240
|
-
Patch,
|
|
3241
|
-
Param,
|
|
3242
|
-
ModuleRegistry,
|
|
3243
|
-
Logger,
|
|
3244
|
-
Ioc,
|
|
3245
|
-
InjectRepository,
|
|
3246
|
-
Inject,
|
|
3247
|
-
IgnorePerms,
|
|
3248
|
-
Get,
|
|
3249
|
-
Eps,
|
|
3250
|
-
Delete,
|
|
3251
|
-
DbStore,
|
|
3252
|
-
Controller,
|
|
3253
|
-
Context,
|
|
3254
|
-
CommException,
|
|
3255
|
-
Body,
|
|
3256
|
-
BaseService,
|
|
3257
|
-
BasePlugin,
|
|
3258
|
-
BaseController,
|
|
3259
|
-
BASE_COLUMN_COMMENTS,
|
|
3260
|
-
App
|
|
3261
|
-
};
|
|
1
|
+
const _0x558e8f=_0x16aa;(function(_0x4ad17c,_0x4dac29){const _0x490ceb=_0x16aa,_0x30bf34=_0x4ad17c();while(!![]){try{const _0x15ec2c=-parseInt(_0x490ceb(0x1de))/0x1*(-parseInt(_0x490ceb(0x166))/0x2)+-parseInt(_0x490ceb(0x288))/0x3*(-parseInt(_0x490ceb(0x265))/0x4)+parseInt(_0x490ceb(0x1e7))/0x5+parseInt(_0x490ceb(0x2e3))/0x6*(parseInt(_0x490ceb(0x23b))/0x7)+-parseInt(_0x490ceb(0x2ea))/0x8+parseInt(_0x490ceb(0x26a))/0x9+parseInt(_0x490ceb(0x17a))/0xa*(-parseInt(_0x490ceb(0x232))/0xb);if(_0x15ec2c===_0x4dac29)break;else _0x30bf34['push'](_0x30bf34['shift']());}catch(_0x4ee111){_0x30bf34['push'](_0x30bf34['shift']());}}}(_0x10f3,0x3f6f1));import{join}from'path';import{pathToFileURL}from'url';function getEnv(){const _0x2d8953=_0x16aa;return Bun[_0x2d8953(0x2a1)][_0x2d8953(0x263)]===_0x2d8953(0x31a)?_0x2d8953(0x31a):_0x2d8953(0x16d);}function merge(_0x4d805a,_0x92515b){const _0x3d70a7=_0x16aa,_0x14b6b4={..._0x4d805a};for(const _0x4a87fc of Object[_0x3d70a7(0x28b)](_0x92515b)){const _0x265725=_0x14b6b4[_0x4a87fc],_0x4c4532=_0x92515b[_0x4a87fc];if(_0x265725&&_0x4c4532&&typeof _0x265725==='object'&&typeof _0x4c4532===_0x3d70a7(0x1b1)&&!Array[_0x3d70a7(0x2dc)](_0x265725)&&!Array['isArray'](_0x4c4532)){_0x14b6b4[_0x4a87fc]=merge(_0x265725,_0x4c4532);continue;}_0x14b6b4[_0x4a87fc]=_0x4c4532;}return _0x14b6b4;}async function loadConfig(_0x268634=join(process[_0x558e8f(0x1cc)](),_0x558e8f(0x310))){const _0x2a4a60=_0x558e8f,_0xe52c7=getEnv()==='dev'?_0x2a4a60(0x307):_0x2a4a60(0x1df),_0x5dc2fe=await import(pathToFileURL(join(_0x268634,'default.ts'))[_0x2a4a60(0x194)]),_0x5e1fb9=await import(pathToFileURL(join(_0x268634,_0xe52c7))['href']);return merge(_0x5dc2fe[_0x2a4a60(0x300)],_0x5e1fb9[_0x2a4a60(0x300)]);}var VomeConfig=await loadConfig();import{Elysia as _0x19be4e}from'elysia';import{Elysia}from'elysia';import{AsyncLocalStorage}from'async_hooks';var storage=new AsyncLocalStorage(),warnedOutsideRequest=![];function resolveClientIp(_0x1fd446){const _0x1d94f7=_0x558e8f,_0x178d88=_0x1fd446[_0x1d94f7(0x292)][_0x1d94f7(0x248)](_0x1d94f7(0x2cd));if(_0x178d88){const _0x379711=_0x178d88['split'](',')[0x0]?.[_0x1d94f7(0x257)]();if(_0x379711)return _0x379711;}return _0x1fd446['headers'][_0x1d94f7(0x248)](_0x1d94f7(0x247))?.[_0x1d94f7(0x257)]()||_0x1fd446['headers'][_0x1d94f7(0x248)](_0x1d94f7(0x2ce))?.['trim']()||'';}function initContextFromRequest(_0x21c8e6){const _0x5de4e4=_0x558e8f,_0x1cc5ef=new URL(_0x21c8e6[_0x5de4e4(0x33a)]),_0x101602=_0x21c8e6[_0x5de4e4(0x292)][_0x5de4e4(0x248)](_0x5de4e4(0x197))?.[_0x5de4e4(0x2fa)](',')[0x0]?.[_0x5de4e4(0x257)](),_0x27117e=_0x21c8e6[_0x5de4e4(0x292)]['get']('host')?.['trim']();return{'requestId':crypto[_0x5de4e4(0x1e9)](),'method':_0x21c8e6[_0x5de4e4(0x31b)],'path':_0x1cc5ef[_0x5de4e4(0x188)],'ip':resolveClientIp(_0x21c8e6),'host':_0x101602||_0x27117e||_0x1cc5ef['host'],'startTime':Date[_0x5de4e4(0x1f5)]()};}function enterContextWith(_0x71242d){storage['enterWith'](_0x71242d);}function getContext(){const _0x584817=_0x558e8f;return storage[_0x584817(0x223)]();}function assignContext(_0x510d64){const _0x2f54b3=_0x558e8f,_0x1d79d9=storage['getStore']();if(!_0x1d79d9){getEnv()===_0x2f54b3(0x31a)&&!warnedOutsideRequest&&(warnedOutsideRequest=!![],console['warn']('[Context]\x20\u5F53\u524D\u65E0\u8BF7\u6C42\u4E0A\u4E0B\u6587\uFF0C\u5199\u5165\u88AB\u5FFD\u7565\uFF08\u8BF7\u786E\u8BA4\x20asyncContextManager\x20\u5DF2\u542F\u7528\uFF09'));return;}Object[_0x2f54b3(0x2b7)](_0x1d79d9,_0x510d64);}function runContext(_0x23fe86,_0x49beb8){const _0x36cf84=_0x558e8f;return storage[_0x36cf84(0x1d3)](_0x23fe86,_0x49beb8);}var Context=Object[_0x558e8f(0x2b7)](assignContext,{'get':getContext,'run':runContext});import'reflect-metadata';var INJECT_METADATA_KEY='vome:inject',providers=new Map();function registerProvider(_0x34e1b8){const _0x285367=_0x558e8f;providers[_0x285367(0x2f7)](_0x34e1b8['token'],_0x34e1b8);}function getProvider(_0x3c1d6d){const _0x5cd6bb=_0x558e8f;return providers[_0x5cd6bb(0x248)](_0x3c1d6d);}function listProviders(){const _0x153590=_0x558e8f,_0x1f7a73=new Set(),_0x1babf6=[];for(const _0x22be8c of providers['values']()){if(_0x1f7a73[_0x153590(0x2fc)](_0x22be8c['useClass']))continue;_0x1f7a73[_0x153590(0x29f)](_0x22be8c['useClass']),_0x1babf6[_0x153590(0x2d0)](_0x22be8c);}return _0x1babf6;}function tokenLabel(_0x3d3e13){const _0x427131=_0x558e8f;if(typeof _0x3d3e13===_0x427131(0x222)||typeof _0x3d3e13===_0x427131(0x28e))return String(_0x3d3e13);return _0x3d3e13[_0x427131(0x321)]||_0x427131(0x255);}function appendInjectMeta(_0x3bee07,_0x492997){const _0x5b2fc6=_0x558e8f,_0x42b7e7=Reflect[_0x5b2fc6(0x2db)](INJECT_METADATA_KEY,_0x3bee07)??[];_0x42b7e7['push'](_0x492997),Reflect[_0x5b2fc6(0x266)](INJECT_METADATA_KEY,_0x42b7e7,_0x3bee07);}function getInjectMetas(_0x3ebe36){return Reflect['getMetadata'](INJECT_METADATA_KEY,_0x3ebe36)??[];}function resetProviders(){const _0x41c2a8=_0x558e8f;providers[_0x41c2a8(0x173)]();}var ScopeEnum;(_0x45b4dd=>{const _0x28af73=_0x558e8f;_0x45b4dd[_0x28af73(0x2b2)]='singleton',_0x45b4dd[_0x28af73(0x1ba)]='request',_0x45b4dd[_0x28af73(0x260)]=_0x28af73(0x29a);})(ScopeEnum||={});var singletons=new Map(),creating=new Set(),requestCaches=new WeakMap();function injectProperties(_0x37513b,_0x326379){const _0x5ee556=_0x558e8f;for(const _0x584516 of getInjectMetas(_0x326379)){const {propertyKey:_0x2d67f1,token:_0x2de3b6,resolve:_0x1d56c9}=_0x584516;if(!_0x1d56c9&&_0x2de3b6==null)throw new Error(_0x5ee556(0x1e8)+String(_0x2d67f1)+_0x5ee556(0x1ff));const _0x52cbf2=_0x1d56c9?_0x1d56c9():Ioc[_0x5ee556(0x248)](_0x2de3b6);_0x37513b[_0x2d67f1]=_0x52cbf2;const _0x515786=_0x37513b['bindEntity'];_0x1d56c9&&typeof _0x515786===_0x5ee556(0x20b)&&_0x515786[_0x5ee556(0x2b0)](_0x37513b,_0x52cbf2);}}function createInstance(_0x3d8da8){const _0x21536e=_0x558e8f;if(creating['has'](_0x3d8da8))throw new Error('[Ioc]\x20检测到循环依赖:\x20'+_0x3d8da8['name']);creating[_0x21536e(0x29f)](_0x3d8da8);try{const _0x176676=new _0x3d8da8();return injectProperties(_0x176676,_0x3d8da8),_0x176676;}finally{creating[_0x21536e(0x296)](_0x3d8da8);}}function getSingleton(_0x52f7e1){const _0x28009d=singletons['get'](_0x52f7e1);if(_0x28009d)return _0x28009d;const _0x2367a5=createInstance(_0x52f7e1);return singletons['set'](_0x52f7e1,_0x2367a5),_0x2367a5;}function getRequestCache(){const _0x7d7c76=_0x558e8f,_0x3aa71e=Context[_0x7d7c76(0x248)]();if(!_0x3aa71e)throw new Error(_0x7d7c76(0x21e));let _0x229854=requestCaches['get'](_0x3aa71e);return!_0x229854&&(_0x229854=new Map(),requestCaches['set'](_0x3aa71e,_0x229854)),_0x229854;}function getRequestScoped(_0x4f0adf){const _0x15c57e=_0x558e8f,_0x37daf7=getRequestCache(),_0x51aed9=_0x37daf7[_0x15c57e(0x248)](_0x4f0adf);if(_0x51aed9)return _0x51aed9;const _0x2cb2f2=createInstance(_0x4f0adf);return _0x37daf7[_0x15c57e(0x2f7)](_0x4f0adf,_0x2cb2f2),_0x2cb2f2;}function resolveByScope(_0x1a3838,_0x15cdd5){const _0x2c1909=_0x558e8f;switch(_0x15cdd5){case _0x2c1909(0x1bf):return getSingleton(_0x1a3838);case _0x2c1909(0x29a):return createInstance(_0x1a3838);case _0x2c1909(0x26b):return getRequestScoped(_0x1a3838);default:throw new Error(_0x2c1909(0x1d8)+_0x15cdd5);}}function resolveMeta(_0x3dc043){const _0x26032f=_0x558e8f,_0x5d7afd=getProvider(_0x3dc043);if(!_0x5d7afd)throw new Error(_0x26032f(0x1b4)+tokenLabel(_0x3dc043));return _0x5d7afd;}function bootstrapIoc(){const _0x465b7e=_0x558e8f;for(const {useClass:_0x625d29,scope:_0x58128a}of listProviders()){_0x58128a==='singleton'&&getSingleton(_0x625d29);}console[_0x465b7e(0x21a)](_0x465b7e(0x328)+singletons[_0x465b7e(0x1d5)]+_0x465b7e(0x2ad));}function get(_0x5c86d7){const _0x1d5e39=_0x558e8f,_0x52a2d3=resolveMeta(_0x5c86d7);return resolveByScope(_0x52a2d3[_0x1d5e39(0x267)],_0x52a2d3[_0x1d5e39(0x210)]);}function set(_0x12d2c9,_0x146af3){const _0x45246a=_0x558e8f;if(typeof _0x12d2c9===_0x45246a(0x20b)){registerProvider({'token':_0x12d2c9,'useClass':_0x12d2c9,'scope':_0x45246a(0x1bf)}),singletons[_0x45246a(0x2f7)](_0x12d2c9,_0x146af3);return;}const _0x5ec8b9=_0x146af3?.[_0x45246a(0x1f0)];if(!_0x5ec8b9||_0x5ec8b9===Object)throw new Error(_0x45246a(0x324)+tokenLabel(_0x12d2c9)+')\x20需要\x20class\x20实例,以便确定\x20useClass');registerProvider({'token':_0x12d2c9,'useClass':_0x5ec8b9,'scope':_0x45246a(0x1bf)}),registerProvider({'token':_0x5ec8b9,'useClass':_0x5ec8b9,'scope':'singleton'}),singletons[_0x45246a(0x2f7)](_0x5ec8b9,_0x146af3);}function resetIoc(){const _0x172f99=_0x558e8f;singletons[_0x172f99(0x173)](),creating[_0x172f99(0x173)](),resetProviders();}var Ioc={'get':get,'set':set};import'reflect-metadata';var controllers=new Map();function registerController(_0x3b1c12){const _0x1fda33=_0x558e8f;controllers[_0x1fda33(0x2f7)](_0x3b1c12[_0x1fda33(0x2b5)],_0x3b1c12);}function listControllers(_0x1d986b){const _0x40bed6=_0x558e8f,_0x486ebf=[...controllers[_0x40bed6(0x2ca)]()];return _0x1d986b?_0x486ebf[_0x40bed6(0x1a7)](_0x3f8099=>_0x3f8099[_0x40bed6(0x261)]===_0x1d986b):_0x486ebf;}var ROUTE_PARAMS_KEY='vome:controller:route-params',ROUTE_PUBLIC_KEY=_0x558e8f(0x16f),ROUTE_MW_KEY=_0x558e8f(0x1b2),ROUTE_PERMS_KEY='vome:controller:route-perms',ROUTE_IGNORE_PERMS_KEY=_0x558e8f(0x19c);function appendRouteParam(_0x79218,_0x100960,_0x5cc5da){const _0x5514ea=_0x558e8f,_0x4cad45=Reflect['getMetadata'](ROUTE_PARAMS_KEY,_0x79218)??{},_0x39bddc=_0x4cad45[_0x100960]??[];_0x39bddc[_0x5514ea(0x2d0)](_0x5cc5da),_0x4cad45[_0x100960]=_0x39bddc,Reflect[_0x5514ea(0x266)](ROUTE_PARAMS_KEY,_0x4cad45,_0x79218);}function getRouteParams(_0x4107b6,_0x2b7460){const _0x2afaa8=Reflect['getMetadata'](ROUTE_PARAMS_KEY,_0x4107b6);return _0x2afaa8?.[_0x2b7460]??[];}function clearRouteParams(_0x2b9429){const _0x28a20c=_0x558e8f;Reflect[_0x28a20c(0x336)](ROUTE_PARAMS_KEY,_0x2b9429);}function markRoutePublic(_0x6b6076,_0x48f72e){const _0x283f68=_0x558e8f,_0x3b3d01=Reflect[_0x283f68(0x2db)](ROUTE_PUBLIC_KEY,_0x6b6076)??{};_0x3b3d01[_0x48f72e]=!![],Reflect['defineMetadata'](ROUTE_PUBLIC_KEY,_0x3b3d01,_0x6b6076);}function isRoutePublic(_0x3a7f5c,_0x516b74){const _0x304041=_0x558e8f,_0x5b6463=Reflect[_0x304041(0x2db)](ROUTE_PUBLIC_KEY,_0x3a7f5c);return!!_0x5b6463?.[_0x516b74];}function clearRoutePublic(_0x2d3a46){const _0x19fb86=_0x558e8f;Reflect[_0x19fb86(0x336)](ROUTE_PUBLIC_KEY,_0x2d3a46);}function appendRouteMiddleware(_0x3e0700,_0xe09cd4,_0x462926){const _0xe21681=_0x558e8f,_0x10a2d4=Reflect['getMetadata'](ROUTE_MW_KEY,_0x3e0700)??{};_0x10a2d4[_0xe09cd4]=[..._0x10a2d4[_0xe09cd4]??[],..._0x462926],Reflect[_0xe21681(0x266)](ROUTE_MW_KEY,_0x10a2d4,_0x3e0700);}function getRouteMiddleware(_0x5e8b2f,_0x5628f5){const _0x4feefa=_0x558e8f,_0x11d424=Reflect[_0x4feefa(0x2db)](ROUTE_MW_KEY,_0x5e8b2f);return _0x11d424?.[_0x5628f5]??[];}function clearRouteMiddleware(_0x88b483){const _0x333e9c=_0x558e8f;Reflect[_0x333e9c(0x336)](ROUTE_MW_KEY,_0x88b483);}function setRoutePerms(_0x38f869,_0x424488,_0x3b72c4){const _0x41f9f0=_0x558e8f,_0x3d9c32=Reflect[_0x41f9f0(0x2db)](ROUTE_PERMS_KEY,_0x38f869)??{};_0x3d9c32[_0x424488]=_0x3b72c4,Reflect[_0x41f9f0(0x266)](ROUTE_PERMS_KEY,_0x3d9c32,_0x38f869);}function getRoutePerms(_0x2a59db,_0x16129e){const _0x24f54d=Reflect['getMetadata'](ROUTE_PERMS_KEY,_0x2a59db);return _0x24f54d?.[_0x16129e];}function clearRoutePerms(_0x549a17){const _0x142475=_0x558e8f;Reflect[_0x142475(0x336)](ROUTE_PERMS_KEY,_0x549a17);}function markRouteIgnorePerms(_0x36dfb3,_0x370a9b){const _0x3fb344=_0x558e8f,_0x3af340=Reflect[_0x3fb344(0x2db)](ROUTE_IGNORE_PERMS_KEY,_0x36dfb3)??{};_0x3af340[_0x370a9b]=!![],Reflect[_0x3fb344(0x266)](ROUTE_IGNORE_PERMS_KEY,_0x3af340,_0x36dfb3);}function isRouteIgnorePerms(_0x3a1520,_0x2e55d6){const _0x410ffa=_0x558e8f,_0x1b8bae=Reflect[_0x410ffa(0x2db)](ROUTE_IGNORE_PERMS_KEY,_0x3a1520);return!!_0x1b8bae?.[_0x2e55d6];}function clearRouteIgnorePerms(_0x51374e){const _0x20e389=_0x558e8f;Reflect[_0x20e389(0x336)](ROUTE_IGNORE_PERMS_KEY,_0x51374e);}function schemaFromParams(_0x57a68c){const _0x243e14=_0x558e8f,_0x480150={};for(const _0x31bd7f of _0x57a68c){if(_0x31bd7f[_0x243e14(0x28a)]==='body'&&_0x31bd7f['schema']!==undefined)_0x480150['body']=_0x31bd7f['schema'];if(_0x31bd7f['source']===_0x243e14(0x192)&&_0x31bd7f[_0x243e14(0x231)]!==undefined)_0x480150[_0x243e14(0x192)]=_0x31bd7f['schema'];if(_0x31bd7f[_0x243e14(0x28a)]===_0x243e14(0x199)&&_0x31bd7f[_0x243e14(0x231)]!==undefined)_0x480150['params']=_0x31bd7f[_0x243e14(0x231)];}return Object[_0x243e14(0x28b)](_0x480150)['length']>0x0?_0x480150:undefined;}function openApiTag(_0x3e2319,_0x342fe8){return _0x3e2319+'.'+_0x342fe8;}function sideOrder(_0x114918){const _0x4ca688=_0x558e8f;if(_0x114918===_0x4ca688(0x2a7))return 0x0;if(_0x114918===_0x4ca688(0x1da))return 0x1;return 0x2;}function parseTag(_0x160b88){const _0x8d367a=_0x558e8f,_0x4f22c0=_0x160b88[_0x8d367a(0x314)]('.');if(_0x4f22c0<0x0)return{'module':_0x160b88,'side':''};return{'module':_0x160b88[_0x8d367a(0x331)](0x0,_0x4f22c0),'side':_0x160b88[_0x8d367a(0x331)](_0x4f22c0+0x1)};}function buildOpenApiTagDocs(){const _0x3a4f42=_0x558e8f,_0x164715=listControllers(),_0x52ce7b=new Map(),_0x14954b=new Map();for(const _0x5e9320 of _0x164715){const _0x48062a=openApiTag(_0x5e9320[_0x3a4f42(0x29d)],_0x5e9320[_0x3a4f42(0x261)]);!_0x52ce7b['has'](_0x48062a)&&_0x52ce7b[_0x3a4f42(0x2f7)](_0x48062a,{'name':_0x48062a,'description':_0x5e9320[_0x3a4f42(0x29d)]+'\x20'+_0x5e9320[_0x3a4f42(0x261)],'x-displayName':_0x5e9320['side']});let _0x4a2671=_0x14954b[_0x3a4f42(0x248)](_0x5e9320[_0x3a4f42(0x29d)]);!_0x4a2671&&(_0x4a2671=new Set(),_0x14954b[_0x3a4f42(0x2f7)](_0x5e9320[_0x3a4f42(0x29d)],_0x4a2671)),_0x4a2671[_0x3a4f42(0x29f)](_0x48062a);}const _0x6c1156=[..._0x52ce7b[_0x3a4f42(0x2ca)]()][_0x3a4f42(0x2af)]((_0xc89bc,_0x4bd661)=>{const _0x5509c8=_0x3a4f42,_0x22191c=parseTag(_0xc89bc[_0x5509c8(0x321)]),_0x52ad21=parseTag(_0x4bd661[_0x5509c8(0x321)]);return _0x22191c['module']['localeCompare'](_0x52ad21['module'])||sideOrder(_0x22191c[_0x5509c8(0x261)])-sideOrder(_0x52ad21['side']);}),_0x51caa8=[..._0x14954b[_0x3a4f42(0x2e7)]()][_0x3a4f42(0x2af)](([_0x51c2e5],[_0x31ec6c])=>_0x51c2e5[_0x3a4f42(0x1b7)](_0x31ec6c))['map'](([_0x4118bf,_0x1cf832])=>({'name':_0x4118bf,'tags':[..._0x1cf832][_0x3a4f42(0x2af)]((_0x154f84,_0x22103b)=>{const _0x13ab74=_0x3a4f42,_0x10f45f=parseTag(_0x154f84)[_0x13ab74(0x261)],_0x2ad9c5=parseTag(_0x22103b)['side'];return sideOrder(_0x10f45f)-sideOrder(_0x2ad9c5);})}));return{'tags':_0x6c1156,'tagGroups':_0x51caa8};}function normalizePrefix(_0xa9d37c){if(!_0xa9d37c)return'';return _0xa9d37c['startsWith']('/')?_0xa9d37c:'/'+_0xa9d37c;}function joinPrefix(..._0x1e9bd4){const _0x348c17=_0x558e8f,_0x204982=_0x1e9bd4['map'](_0x20794a=>normalizePrefix(_0x20794a)[_0x348c17(0x326)](/^\/+|\/+$/g,''))['filter'](Boolean);return _0x204982[_0x348c17(0x293)]?'/'+_0x204982['join']('/'):'/';}function getRouteSubPath(_0x3c00bb,_0x3455f1){const _0x17a1bc=_0x558e8f,_0x372116=normalizePrefix(_0x3455f1)[_0x17a1bc(0x326)](/\/$/,''),_0x4ece08=normalizePrefix(_0x3c00bb);if(!_0x372116)return _0x4ece08||'/';if(_0x4ece08===_0x372116)return'/';if(_0x4ece08[_0x17a1bc(0x2f2)](_0x372116+'/'))return _0x4ece08['slice'](_0x372116[_0x17a1bc(0x293)])||'/';const _0x16af12=_0x3c00bb[_0x17a1bc(0x2f2)]('/')?_0x3c00bb:'/'+_0x3c00bb;return _0x16af12||'/';}function resolveRoutePerm(_0x8a5135,_0x293894,_0x2a7c54){const _0x188d2b=_0x558e8f;let _0x192bc6=_0x293894[_0x188d2b(0x326)](/^\//,'')['replace'](/\/+/g,':');if(_0x192bc6===_0x8a5135)_0x192bc6=_0x8a5135;else _0x192bc6[_0x188d2b(0x2f2)](_0x8a5135+':')&&(_0x192bc6=_0x192bc6[_0x188d2b(0x331)](_0x8a5135[_0x188d2b(0x293)]+0x1));const _0xce5ba0=_0x8a5135+'-';_0x192bc6[_0x188d2b(0x2f2)](_0xce5ba0)&&(_0x192bc6=_0x192bc6[_0x188d2b(0x331)](_0xce5ba0['length']));_0x192bc6=_0x192bc6[_0x188d2b(0x326)](/-/g,':');if(!_0x192bc6)_0x192bc6=_0x8a5135;return _0x8a5135+':'+_0x192bc6+':'+_0x2a7c54;}function actionFromSubPath(_0x10d655){const _0x20c087=_0x558e8f,_0x49b345=_0x10d655[_0x20c087(0x326)](/^\/+|\/+$/g,'');if(!_0x49b345)return _0x20c087(0x2c6);const _0x1d6592=_0x49b345['split']('/');return _0x1d6592[_0x1d6592['length']-0x1]||_0x20c087(0x2c6);}function effectivePerms(_0x4863e1,_0x567c77,_0x6da9c4){const _0x863225=_0x558e8f;if(_0x567c77['side']!==_0x863225(0x2a7)||_0x4863e1[_0x863225(0x2bf)]||_0x4863e1[_0x863225(0x22b)])return;if(_0x4863e1[_0x863225(0x26c)]?.[_0x863225(0x293)])return _0x4863e1[_0x863225(0x26c)];const _0x5e8129=_0x6da9c4??actionFromSubPath(getRouteSubPath(_0x4863e1['path']??'/',_0x567c77[_0x863225(0x24d)]));return[resolveRoutePerm(_0x567c77[_0x863225(0x29d)],_0x567c77['prefix'],_0x5e8129)];}var crudRegistrar;function setCrudRegistrar(_0x26150c){crudRegistrar=_0x26150c;}var SIDE_PREFIX={'admin':'/admin','app':'/app'},ADMIN_GUARD=_0x558e8f(0x24c),APP_GUARD=_0x558e8f(0x219),ELYSIA_METHODS={'GET':_0x558e8f(0x248),'POST':_0x558e8f(0x1c8),'PUT':_0x558e8f(0x1ee),'DELETE':_0x558e8f(0x296),'PATCH':_0x558e8f(0x29b)};function getSidePrefix(_0x2d68e8){return normalizePrefix(SIDE_PREFIX[_0x2d68e8]);}function buildRouteSchema(_0x9a8222){const _0x4a294d=_0x558e8f;if(_0x9a8222[_0x4a294d(0x199)]?.['length'])return schemaFromParams(_0x9a8222['params']);const _0x2776d5={};if(_0x9a8222['body']!==undefined)_0x2776d5[_0x4a294d(0x30a)]=_0x9a8222[_0x4a294d(0x30a)];if(_0x9a8222[_0x4a294d(0x192)]!==undefined)_0x2776d5[_0x4a294d(0x192)]=_0x9a8222[_0x4a294d(0x192)];if(_0x9a8222[_0x4a294d(0x33b)]!==undefined)_0x2776d5['params']=_0x9a8222[_0x4a294d(0x33b)];return Object[_0x4a294d(0x28b)](_0x2776d5)[_0x4a294d(0x293)]>0x0?_0x2776d5:undefined;}function assertRouteParams(_0x550d69,_0x2242c1,_0x424596){const _0x369a04=_0x558e8f,_0x7cc74b=new Set();for(const _0x2b0360 of _0x550d69){if(_0x7cc74b[_0x369a04(0x2fc)](_0x2b0360[_0x369a04(0x28a)])){const _0x206049=_0x2b0360[_0x369a04(0x28a)]===_0x369a04(0x30a)?_0x369a04(0x25f):_0x2b0360[_0x369a04(0x28a)]===_0x369a04(0x192)?_0x369a04(0x17d):_0x369a04(0x202);throw new Error('[Router]\x20'+_0x424596+'.'+_0x2242c1+_0x369a04(0x31c)+_0x206049);}_0x7cc74b['add'](_0x2b0360[_0x369a04(0x28a)]);}}function createParamHandler(_0x12e0f3,_0x3aff22,_0x279ce4){const _0x411764=_0x558e8f,_0x4f7308=_0x12e0f3[_0x3aff22],_0x44e5bc=_0x4f7308[_0x411764(0x299)](_0x12e0f3);if(!_0x279ce4?.[_0x411764(0x293)])return _0x44e5bc;const _0x40f752=[..._0x279ce4][_0x411764(0x2af)]((_0x1b6a3e,_0x2406b4)=>_0x1b6a3e[_0x411764(0x2c6)]-_0x2406b4[_0x411764(0x2c6)]);return _0x5c3541=>{const _0xbedc8=_0x411764,_0x4361ae=_0x40f752[_0xbedc8(0x31e)](_0x5c0cf4=>{const _0x4dbbc5=_0xbedc8;if(_0x5c0cf4['source']==='body')return _0x5c3541[_0x4dbbc5(0x30a)];if(_0x5c0cf4['source']==='query')return _0x5c3541['query'];if(_0x5c0cf4['source']==='params')return _0x5c3541[_0x4dbbc5(0x199)];throw new Error(_0x4dbbc5(0x278)+_0x5c0cf4[_0x4dbbc5(0x28a)]);});return _0x44e5bc(..._0x4361ae,_0x5c3541);};}function createPermsGuard(_0x4e16dd){return _0x1ba9e9=>{const _0x1b4a7d=_0x16aa,_0x333a4f=_0x1ba9e9[_0x1b4a7d(0x21d)],_0x26dd5a=Context[_0x1b4a7d(0x248)]();if(_0x26dd5a?.[_0x1b4a7d(0x23c)])return;const _0x5d526c=_0x26dd5a?.[_0x1b4a7d(0x26c)]??[];if(_0x4e16dd[_0x1b4a7d(0x19a)](_0x1ed929=>_0x5d526c[_0x1b4a7d(0x339)](_0x1ed929)))return;return _0x333a4f(0x193);};}function openApiSummary(_0x23134e,_0x309ac9){const _0x4aefec=_0x558e8f,_0x448381=_0x23134e['replace'](/^\/+|\/+$/g,'')['split']('/')[_0x4aefec(0x2d9)]()||_0x23134e;return _0x309ac9?_0x448381+'\x20'+_0x309ac9:_0x448381;}function buildRouteOptions(_0x22c4bf,_0x2d2405){const _0x21ddb3=_0x558e8f,_0x525fe5=buildRouteSchema(_0x22c4bf)??{},_0x49675f={..._0x525fe5,'detail':{'tags':[openApiTag(_0x2d2405[_0x21ddb3(0x29d)],_0x2d2405[_0x21ddb3(0x261)])],'summary':openApiSummary(_0x22c4bf[_0x21ddb3(0x2aa)],_0x22c4bf[_0x21ddb3(0x311)])}};_0x2d2405[_0x21ddb3(0x261)]===_0x21ddb3(0x2a7)&&!_0x22c4bf[_0x21ddb3(0x2bf)]&&(_0x49675f[ADMIN_GUARD]=!![]);_0x2d2405['side']==='app'&&!_0x22c4bf['public']&&(_0x49675f[APP_GUARD]=!![]);const _0x11937c=[],_0x1407e3=effectivePerms(_0x22c4bf,_0x2d2405);if(_0x1407e3?.[_0x21ddb3(0x293)])_0x11937c[_0x21ddb3(0x2d0)](createPermsGuard(_0x1407e3));if(_0x22c4bf[_0x21ddb3(0x2e0)]?.['length'])_0x11937c[_0x21ddb3(0x2d0)](..._0x22c4bf[_0x21ddb3(0x2e0)]);if(_0x11937c[_0x21ddb3(0x293)])_0x49675f[_0x21ddb3(0x2e4)]=_0x11937c;return _0x49675f;}function normalizeCrudRouteOpts(_0x5d4248){const _0x2ee523=_0x558e8f;if(_0x5d4248==null)return{};if(typeof _0x5d4248===_0x2ee523(0x338))return{'public':_0x5d4248};return _0x5d4248;}function registerControllerPlugin(_0x55f87a,_0x2598da){const _0x4d5bcd=_0x558e8f,_0x354ecb=getSidePrefix(_0x55f87a[_0x4d5bcd(0x261)]),_0x3505d8=joinPrefix(_0x354ecb,_0x55f87a[_0x4d5bcd(0x24d)]),_0x2faeb1=Ioc[_0x4d5bcd(0x248)](_0x55f87a[_0x4d5bcd(0x2b5)]);let _0x413116=new Elysia({'prefix':_0x3505d8,'name':_0x55f87a[_0x4d5bcd(0x2b5)][_0x4d5bcd(0x321)],'tags':[openApiTag(_0x55f87a[_0x4d5bcd(0x29d)],_0x55f87a[_0x4d5bcd(0x261)])]});for(const _0xef8191 of _0x55f87a[_0x4d5bcd(0x2e0)]??[]){_0x413116=_0x413116[_0x4d5bcd(0x258)](_0xef8191);}const _0xb51964=[];for(const _0x19c669 of _0x55f87a[_0x4d5bcd(0x169)]){const _0x256ba9=_0x2faeb1[_0x19c669[_0x4d5bcd(0x2aa)]];if(typeof _0x256ba9!=='function')throw new Error(_0x4d5bcd(0x1dd)+_0x55f87a[_0x4d5bcd(0x2b5)]['name']+'.'+_0x19c669['handler']+_0x4d5bcd(0x196));assertRouteParams(_0x19c669[_0x4d5bcd(0x199)]??[],_0x19c669['handler'],_0x55f87a[_0x4d5bcd(0x2b5)][_0x4d5bcd(0x321)]);const _0x2a72b0=createParamHandler(_0x2faeb1,_0x19c669[_0x4d5bcd(0x2aa)],_0x19c669[_0x4d5bcd(0x199)]),_0x2b3dc5=getRouteSubPath(_0x19c669['path'],_0x55f87a[_0x4d5bcd(0x24d)]),_0x41debc=buildRouteOptions(_0x19c669,_0x55f87a),_0x1d6d67=ELYSIA_METHODS[_0x19c669[_0x4d5bcd(0x31b)]];_0x413116=_0x413116[_0x1d6d67](_0x2b3dc5,_0x2a72b0,_0x41debc);}if(_0x55f87a['crud']?.[_0x4d5bcd(0x2c1)]?.[_0x4d5bcd(0x293)]||_0x55f87a['crud']?.[_0x4d5bcd(0x209)]?.[_0x4d5bcd(0x293)]){if(!crudRegistrar)throw new Error(_0x4d5bcd(0x1dd)+_0x55f87a['token'][_0x4d5bcd(0x321)]+_0x4d5bcd(0x2a0));_0x413116=crudRegistrar(_0x413116,_0x55f87a,{'controller':_0x2faeb1,'routeOptions':_0x1f01f7=>{const _0x4e226e=_0x4d5bcd,{public:_0x432cf7,action:_0x394983,summary:_0x353eaf}=normalizeCrudRouteOpts(_0x1f01f7),_0x2b51c2={'detail':{'tags':[openApiTag(_0x55f87a['module'],_0x55f87a[_0x4e226e(0x261)])],'summary':openApiSummary(_0x394983??_0x4e226e(0x271),_0x353eaf)}};if(_0x55f87a['side']===_0x4e226e(0x2a7)&&!_0x432cf7){_0x2b51c2[ADMIN_GUARD]=!![];if(_0x394983){const _0x1942ad=resolveRoutePerm(_0x55f87a[_0x4e226e(0x29d)],_0x55f87a[_0x4e226e(0x24d)],_0x394983);_0x2b51c2[_0x4e226e(0x2e4)]=[createPermsGuard([_0x1942ad])];}}return _0x2b51c2;}});for(const _0x4090f2 of _0x55f87a[_0x4d5bcd(0x295)]?.[_0x4d5bcd(0x2c1)]??[]){const _0x1a81f2=_0x4090f2==='info'?_0x4d5bcd(0x2c2):'POST';_0xb51964[_0x4d5bcd(0x2d0)]({'method':_0x1a81f2,'path':joinPrefix(_0x55f87a[_0x4d5bcd(0x24d)],_0x4090f2),'handler':_0x4090f2,'autoCrud':!![]});}for(const _0x28364e of _0x55f87a[_0x4d5bcd(0x295)]?.['serviceApis']??[]){_0xb51964[_0x4d5bcd(0x2d0)]({'method':_0x4d5bcd(0x23e),'path':joinPrefix(_0x55f87a[_0x4d5bcd(0x24d)],_0x28364e),'handler':_0x28364e,'autoCrud':!![]});}}return{'plugin':_0x413116,'pluginPrefix':_0x3505d8,'autoRoutes':_0xb51964};}function registerControllers(_0xc46dde,_0x3abfd6){const _0x25a293=_0x558e8f;let _0x23745a=_0xc46dde,_0x28f496=0x0;const _0x40667d=[];for(const _0x303893 of listControllers()){const {plugin:_0x1c4b13,pluginPrefix:_0x438fa2,autoRoutes:_0x78c31c}=registerControllerPlugin(_0x303893,_0x3abfd6);_0x23745a=_0x23745a['use'](_0x1c4b13);for(const _0x1dd44c of[..._0x303893[_0x25a293(0x169)],..._0x78c31c]){_0x28f496+=0x1;const _0x7d419a=getRouteSubPath(_0x1dd44c['path'],_0x303893[_0x25a293(0x24d)]),_0x5729b5=_0x7d419a==='/'?_0x438fa2:joinPrefix(_0x438fa2,_0x7d419a[_0x25a293(0x326)](/^\//,'')),_0x33aee0=_0x1dd44c[_0x25a293(0x2bf)]?_0x25a293(0x191):_0x1dd44c[_0x25a293(0x297)]?'\x20(crud)':'';_0x40667d[_0x25a293(0x2d0)](_0x1dd44c[_0x25a293(0x31b)]+'\x20'+_0x5729b5+_0x33aee0);}}if(_0x28f496>0x0){console['log'](_0x25a293(0x1a5)+_0x28f496+_0x25a293(0x1c0));for(const _0x260dd5 of _0x40667d)console['log']('\x20\x20'+_0x260dd5);}return _0x23745a;}var {Glob}=globalThis[_0x558e8f(0x220)],DEFAULT_EXT=/\.tsx?$/;async function scanFiles(_0x10c3b3,_0x36e604={}){const _0x3278ce=_0x558e8f,{cwd:cwd=process[_0x3278ce(0x1cc)](),ext:ext=DEFAULT_EXT}=_0x36e604,_0x40f09e=Array[_0x3278ce(0x2dc)](_0x10c3b3)?_0x10c3b3:[_0x10c3b3],_0x151090=[];for(const _0x183754 of _0x40f09e){const _0x135154=new Glob(_0x183754);for await(const _0x49cb28 of _0x135154[_0x3278ce(0x1ac)]({'cwd':cwd,'onlyFiles':!![]})){if(ext[_0x3278ce(0x274)](_0x49cb28))_0x151090[_0x3278ce(0x2d0)](_0x49cb28);}}return[...new Set(_0x151090)][_0x3278ce(0x2af)]();}var context=null;function setControllerScanContext(_0x485535){context=_0x485535;}function getControllerScanContext(){return context;}function parseModuleFromPath(_0x258e5d){const _0x49154d=_0x558e8f,_0x2efbff=_0x258e5d[_0x49154d(0x1e1)](/modules\/([^/]+)\/controller\//);if(!_0x2efbff)return'unknown';return _0x2efbff[0x1];}function parseControllerAutoPrefix(_0x5caebe){const _0x13adbf=_0x558e8f,_0x415c05=_0x5caebe[_0x13adbf(0x326)](/\\/g,'/')['match'](/modules\/([^/]+)\/controller\/(?:admin|app)\/(.+)\.tsx?$/);if(!_0x415c05)return'';const _0x1fdc61=_0x415c05[0x1],_0x1cf9ee=_0x415c05[0x2][_0x13adbf(0x326)](/\/+/g,'/')['replace'](/^\/|\/$/g,'');if(!_0x1cf9ee)return'/'+_0x1fdc61;return'/'+_0x1fdc61+'/'+_0x1cf9ee;}var TIME_KEY_RE=/(?:Time|Date|At)$/,ISO_RE=/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/;function formatDateTime(_0x20c8ef){const _0x2e76c6=_0x558e8f,_0x2b3ceb=_0x20c8ef instanceof Date?_0x20c8ef:new Date(_0x20c8ef);if(Number[_0x2e76c6(0x21b)](_0x2b3ceb['getTime']()))return String(_0x20c8ef);return new Intl[(_0x2e76c6(0x1a2))](_0x2e76c6(0x2e1),{'timeZone':_0x2e76c6(0x1ed),'year':'numeric','month':'2-digit','day':_0x2e76c6(0x1c7),'hour':_0x2e76c6(0x1c7),'minute':_0x2e76c6(0x1c7),'second':_0x2e76c6(0x1c7),'hour12':![]})[_0x2e76c6(0x316)](_0x2b3ceb)[_0x2e76c6(0x326)]('T','\x20');}function isTimeKey(_0x5e15cf){return TIME_KEY_RE['test'](_0x5e15cf);}function formatApiDates(_0x563a3f){return walk(_0x563a3f);}function walk(_0x4e8dcf,_0x25c69a){const _0x462ceb=_0x558e8f;if(_0x4e8dcf==null)return _0x4e8dcf;if(_0x4e8dcf instanceof Date)return formatDateTime(_0x4e8dcf);if(typeof _0x4e8dcf===_0x462ceb(0x222)&&_0x25c69a&&isTimeKey(_0x25c69a)&&ISO_RE['test'](_0x4e8dcf))return formatDateTime(_0x4e8dcf);if(Array[_0x462ceb(0x2dc)](_0x4e8dcf))return _0x4e8dcf['map'](_0x47eb2b=>walk(_0x47eb2b));if(typeof _0x4e8dcf==='object'){if(Object['prototype'][_0x462ceb(0x22e)]['call'](_0x4e8dcf)!==_0x462ceb(0x1af))return _0x4e8dcf;const _0x4a6479={};for(const [_0x388d04,_0x5c4a73]of Object[_0x462ceb(0x2e7)](_0x4e8dcf)){_0x4a6479[_0x388d04]=walk(_0x5c4a73,_0x388d04);}return _0x4a6479;}return _0x4e8dcf;}var RES_CODE={'SUCCESS':0x3e8,'ERROR':0x3e9};class BaseController{['ok'](_0xbd00d8){const _0x2da2ed=_0x558e8f,_0x5be081=_0xbd00d8===undefined?null:_0xbd00d8;return{'code':RES_CODE['SUCCESS'],'message':_0x2da2ed(0x1ca),'data':_0x5be081==null?_0x5be081:formatApiDates(_0x5be081)};}[_0x558e8f(0x172)](_0x43805b=_0x558e8f(0x193),_0x3f78fb=RES_CODE[_0x558e8f(0x2cf)]){return{'code':_0x3f78fb,'message':_0x43805b};}}import'reflect-metadata';function normalizeProvideArgs(_0x36c9b2){const _0x32539c=_0x558e8f;if(_0x36c9b2==null)return{};if(typeof _0x36c9b2===_0x32539c(0x222)||typeof _0x36c9b2===_0x32539c(0x28e))return{'id':_0x36c9b2};return _0x36c9b2;}function Provide(_0x1ba45e){return _0x5185c7=>{const _0x281b1a=_0x16aa,_0x482f34=normalizeProvideArgs(_0x1ba45e),_0x334b28=_0x482f34[_0x281b1a(0x210)]??_0x281b1a(0x1bf);registerProvider({'token':_0x5185c7,'useClass':_0x5185c7,'scope':_0x334b28}),_0x482f34['id']!=null&®isterProvider({'token':_0x482f34['id'],'useClass':_0x5185c7,'scope':_0x334b28});};}function Inject(_0x5c59ad){return(_0x115171,_0x2fe029)=>{const _0xef79ec=_0x16aa,_0x43c60d=Reflect['getMetadata'](_0xef79ec(0x1fa),_0x115171,_0x2fe029),_0xba83f9=_0x5c59ad??_0x43c60d;if(_0xba83f9==null)throw new Error(_0xef79ec(0x1ab)+String(_0x2fe029)+_0xef79ec(0x2a2));appendInjectMeta(_0x115171[_0xef79ec(0x1f0)],{'propertyKey':_0x2fe029,'token':_0xba83f9});};}import{and,arrayContains,arrayOverlaps,asc,desc,eq,gte,inArray,like,lte,or,sql}from'drizzle-orm';function colName(_0x226f21){const _0x3a2692=_0x558e8f;if(typeof _0x226f21===_0x3a2692(0x222)){const _0x506f5e=_0x226f21[_0x3a2692(0x339)]('.')?_0x226f21[_0x3a2692(0x2fa)]('.')['pop']():_0x226f21;return{'column':_0x506f5e,'param':_0x506f5e,'none':![]};}const _0xf0fe6a=_0x226f21[_0x3a2692(0x1d1)][_0x3a2692(0x339)]('.')?_0x226f21[_0x3a2692(0x1d1)][_0x3a2692(0x2fa)]('.')[_0x3a2692(0x2d9)]():_0x226f21[_0x3a2692(0x1d1)];return{'column':_0xf0fe6a,'param':_0x226f21[_0x3a2692(0x33c)]??_0xf0fe6a,'none':Boolean(_0x226f21[_0x3a2692(0x270)])};}function rangeColumn(_0x4065a6){const _0x2a2759=_0x558e8f;return _0x4065a6[_0x2a2759(0x1d1)]['includes']('.')?_0x4065a6[_0x2a2759(0x1d1)][_0x2a2759(0x2fa)]('.')[_0x2a2759(0x2d9)]():_0x4065a6['column'];}function tableCol(_0xa8b57a,_0x39e096){const _0x2eadf7=_0x558e8f,_0x5d4124=_0xa8b57a[_0x39e096];if(_0x5d4124==null)throw new Error(_0x2eadf7(0x2a6)+_0x39e096);return _0x5d4124;}function isBlank(_0x19259c){return _0x19259c===undefined||_0x19259c===null||_0x19259c==='';}function compactWhere(_0x206a15){const _0xb6edfe=_0x558e8f;if(_0x206a15==null||_0x206a15===![])return[];const _0x1accc2=Array[_0xb6edfe(0x2dc)](_0x206a15)?_0x206a15:[_0x206a15];return _0x1accc2['filter'](_0x1f0924=>_0x1f0924!=null&&_0x1f0924!==![]);}var q={'between'(_0x23dd8d,_0x10f396,_0x557f21){if(isBlank(_0x10f396)||isBlank(_0x557f21))return;return sql`${_0x23dd8d} between ${_0x10f396} and ${_0x557f21}`;},'range'(_0x480c1f,_0x53658d,_0x4fc6ee){const _0x1c5476=_0x558e8f,_0x3c7cc0=[];if(!isBlank(_0x53658d))_0x3c7cc0[_0x1c5476(0x2d0)](gte(_0x480c1f,_0x53658d));if(!isBlank(_0x4fc6ee))_0x3c7cc0[_0x1c5476(0x2d0)](lte(_0x480c1f,_0x4fc6ee));if(!_0x3c7cc0['length'])return;return _0x3c7cc0['length']===0x1?_0x3c7cc0[0x0]:and(..._0x3c7cc0);},'eqRest'(_0x80e00f,_0x5e2e71,_0x227e54){const _0x230ec6=_0x558e8f,_0x1c9d48=[];for(const [_0x5d0bf8,_0x222243]of Object[_0x230ec6(0x2e7)](_0x80e00f)){if(isBlank(_0x222243))continue;const _0x54a8ac=_0x227e54?.[_0x5d0bf8]??_0x5e2e71[_0x5d0bf8];if(_0x54a8ac==null)continue;_0x1c9d48[_0x230ec6(0x2d0)](eq(_0x54a8ac,_0x222243));}return _0x1c9d48;},'contains'(_0x179263,_0x348ef5){const _0x3c607e=_0x558e8f;if(isBlank(_0x348ef5))return;const _0xeaba95=Array['isArray'](_0x348ef5)?_0x348ef5:[_0x348ef5];if(!_0xeaba95[_0x3c607e(0x293)])return;return _0xeaba95[_0x3c607e(0x293)]===0x1?arrayContains(_0x179263,_0xeaba95):arrayOverlaps(_0x179263,_0xeaba95);}};function buildFieldClauses(_0x3b51b3,_0x3523a1,_0x5768f3){const _0x200017=_0x558e8f,_0x47e1ca=[];if(_0x5768f3[_0x200017(0x329)]?.[_0x200017(0x293)]&&!isBlank(_0x3523a1['keyWord'])){const _0x3a8967='%'+String(_0x3523a1[_0x200017(0x32f)])+'%',_0x41c7ea=_0x5768f3[_0x200017(0x329)][_0x200017(0x31e)](_0x557cb2=>{const _0x41ee3f=_0x200017,_0x5087bf=_0x557cb2[_0x41ee3f(0x339)]('.')?_0x557cb2[_0x41ee3f(0x2fa)]('.')['pop']():_0x557cb2;return like(tableCol(_0x3b51b3,_0x5087bf),_0x3a8967);});if(_0x41c7ea[_0x200017(0x293)]===0x1)_0x47e1ca[_0x200017(0x2d0)](_0x41c7ea[0x0]);else{if(_0x41c7ea[_0x200017(0x293)]>0x1)_0x47e1ca[_0x200017(0x2d0)](or(..._0x41c7ea));}}for(const _0x1df5f6 of _0x5768f3['fieldEq']??[]){const {column:_0x2ca1e1,param:_0x2bbeaf}=colName(_0x1df5f6),_0x13f9c9=_0x3523a1[_0x2bbeaf];if(isBlank(_0x13f9c9))continue;if(Array[_0x200017(0x2dc)](_0x13f9c9)){if(!_0x13f9c9[_0x200017(0x293)])continue;_0x47e1ca[_0x200017(0x2d0)](inArray(tableCol(_0x3b51b3,_0x2ca1e1),_0x13f9c9));}else _0x47e1ca['push'](eq(tableCol(_0x3b51b3,_0x2ca1e1),_0x13f9c9));}for(const _0x5e99ce of _0x5768f3[_0x200017(0x225)]??[]){const {column:_0x3fe4f1,param:_0x2b3575}=colName(_0x5e99ce),_0x4946b3=_0x3523a1[_0x2b3575];if(isBlank(_0x4946b3))continue;_0x47e1ca['push'](like(tableCol(_0x3b51b3,_0x3fe4f1),'%'+String(_0x4946b3)+'%'));}for(const _0x553e69 of _0x5768f3[_0x200017(0x181)]??[]){const {column:_0xd7fb5c,param:_0x191874}=colName(_0x553e69),_0x47dca2=q['contains'](tableCol(_0x3b51b3,_0xd7fb5c),_0x3523a1[_0x191874]);if(_0x47dca2)_0x47e1ca[_0x200017(0x2d0)](_0x47dca2);}for(const _0x2e9950 of _0x5768f3[_0x200017(0x242)]??[]){const _0x4762d1=tableCol(_0x3b51b3,rangeColumn(_0x2e9950)),_0x36d5af=q[_0x200017(0x31f)](_0x4762d1,_0x3523a1[_0x2e9950[_0x200017(0x1fe)]],_0x3523a1[_0x2e9950[_0x200017(0x18b)]]);if(_0x36d5af)_0x47e1ca[_0x200017(0x2d0)](_0x36d5af);}return _0x47e1ca;}function buildOrderBy(_0x452da2,_0x423443,_0x22ccc1){const _0x86fc98=_0x558e8f,_0x1e1a08=[],_0x36b31d=_0x423443['order']!=null?String(_0x423443[_0x86fc98(0x2fd)]):undefined,_0x2ebcea=_0x423443[_0x86fc98(0x2af)]===_0x86fc98(0x1fc)||_0x423443[_0x86fc98(0x2af)]==='desc'?_0x423443[_0x86fc98(0x2af)]:undefined;if(_0x36b31d){const _0x48eca6=tableCol(_0x452da2,_0x36b31d);_0x1e1a08['push'](_0x2ebcea===_0x86fc98(0x1fc)?asc(_0x48eca6):desc(_0x48eca6));}else{if(_0x22ccc1['addOrderBy'])for(const [_0x63b5ca,_0x1ebdf4]of Object[_0x86fc98(0x2e7)](_0x22ccc1[_0x86fc98(0x1ad)])){const _0x3eb3be=_0x63b5ca[_0x86fc98(0x339)]('.')?_0x63b5ca['split']('.')[_0x86fc98(0x2d9)]():_0x63b5ca,_0x5a6719=tableCol(_0x452da2,_0x3eb3be);_0x1e1a08[_0x86fc98(0x2d0)](_0x1ebdf4===_0x86fc98(0x1fc)?asc(_0x5a6719):desc(_0x5a6719));}}return _0x1e1a08;}function needsAdvancedQuery(_0x11c43a){const _0x20c5a1=_0x558e8f;return!!(_0x11c43a?.[_0x20c5a1(0x245)]?.[_0x20c5a1(0x293)]||_0x11c43a?.[_0x20c5a1(0x230)]);}async function buildQueryOp(_0x59f91c,_0x4f9eec,_0x1d9ea1={},_0x5f41e9){const _0x43081b=_0x558e8f,_0x32c8ef=buildFieldClauses(_0x59f91c,_0x4f9eec,_0x1d9ea1),_0x2cd85e=buildOrderBy(_0x59f91c,_0x4f9eec,_0x1d9ea1),_0xc5cdee={'body':_0x4f9eec,'request':_0x5f41e9??new Request(_0x43081b(0x1fb))};_0x1d9ea1['where']&&_0x32c8ef[_0x43081b(0x2d0)](...compactWhere(await _0x1d9ea1[_0x43081b(0x327)](_0xc5cdee)));if(_0x1d9ea1[_0x43081b(0x16c)]){const _0x541fc2={'andWhere'(_0xae3bdb){if(_0xae3bdb!=null&&_0xae3bdb!==![])_0x32c8ef['push'](_0xae3bdb);},'orderBy'(..._0x5c3b37){for(const _0xb87abb of _0x5c3b37){if(_0xb87abb!=null)_0x2cd85e['push'](_0xb87abb);}}};await _0x1d9ea1[_0x43081b(0x16c)](_0x541fc2,_0xc5cdee);}const _0x12f3df=_0x32c8ef[_0x43081b(0x293)]===0x0?undefined:_0x32c8ef[_0x43081b(0x293)]===0x1?_0x32c8ef[0x0]:and(..._0x32c8ef);return{'where':_0x12f3df,'orderBySql':_0x2cd85e};}import{and as _0x4e7f47,count,countDistinct,getTableColumns,isNotNull,isNull,sql as _0x1f31d0}from'drizzle-orm';function readCrudConfig(){const _0xdcb7aa=_0x558e8f;return VomeConfig[_0xdcb7aa(0x189)]?.[_0xdcb7aa(0x295)]??{};}function resolveUpsert(_0x2b72d0){const _0x4cd7fd=_0x558e8f;return _0x2b72d0??readCrudConfig()[_0x4cd7fd(0x303)]??_0x4cd7fd(0x25b);}function resolveSoftDelete(_0x3b9a19){if(_0x3b9a19!=null)return _0x3b9a19;return readCrudConfig()['softDelete']===!![];}class DbStore{['drizzle'];[_0x558e8f(0x1a4)];[_0x558e8f(0x231)];['sql'];constructor(_0x420d28,_0x7ee046,_0x49b8e9,_0x3d256b){const _0x36ed93=_0x558e8f;this[_0x36ed93(0x1c9)]=_0x420d28,this['client']=_0x7ee046,this[_0x36ed93(0x231)]=_0x49b8e9,this[_0x36ed93(0x21f)]=_0x3d256b;}}import{and as _0x1cd4c,inArray as _0xda578d,sql as _0x44764e}from'drizzle-orm';import{and as _0x6892bb,eq as _0x3d534a,sql as _0x3d0e69}from'drizzle-orm';var SKIP_KEY='__skipTenant';function isTenantEnabled(){const _0x48056a=_0x558e8f;return VomeConfig[_0x48056a(0x189)]?.['tenant']===!![];}function tableHasTenantId(_0x18301f){const _0x4e5684=_0x558e8f;return _0x18301f[_0x4e5684(0x18a)]!=null;}function resolveTenantScope(){const _0x50d448=_0x558e8f;if(!isTenantEnabled())return _0x50d448(0x319);const _0x447353=Context['get']();if(_0x447353?.[SKIP_KEY])return _0x50d448(0x319);if(_0x447353?.[_0x50d448(0x23c)])return'all';const _0x3fa073=_0x447353?.[_0x50d448(0x18a)],_0x4ed621=typeof _0x3fa073==='number'?_0x3fa073:Number(_0x3fa073);if(!Number[_0x50d448(0x301)](_0x4ed621)||_0x4ed621<=0x0)return'none';return _0x4ed621;}function applyTenantWhere(_0x1958fb,_0x3181ab){const _0x54c913=_0x558e8f;if(!tableHasTenantId(_0x1958fb))return _0x3181ab;const _0x39e6ff=resolveTenantScope();if(_0x39e6ff===_0x54c913(0x319)||_0x39e6ff===_0x54c913(0x241))return _0x3181ab;const _0x2d2e79=_0x1958fb[_0x54c913(0x18a)],_0x2f7342=_0x39e6ff===_0x54c913(0x270)?_0x3d0e69`false`:_0x3d534a(_0x2d2e79,_0x39e6ff);if(_0x3181ab&&_0x2f7342)return _0x6892bb(_0x3181ab,_0x2f7342);return _0x3181ab??_0x2f7342;}function stampTenantId(_0x293aef,_0xd8af4c){const _0x42e5ab=_0x558e8f;if(!tableHasTenantId(_0x293aef))return _0xd8af4c;const _0x464ed7=resolveTenantScope();if(typeof _0x464ed7!==_0x42e5ab(0x163))return _0xd8af4c;if(_0xd8af4c['tenantId']!=null)return _0xd8af4c;return{..._0xd8af4c,'tenantId':_0x464ed7};}async function noTenant(_0x43b476){const _0x46da27=_0x558e8f,_0xfcc1b=Context[_0x46da27(0x248)]();if(!_0xfcc1b)return _0x43b476();const _0x7ce2a=_0xfcc1b[SKIP_KEY];_0xfcc1b[SKIP_KEY]=!![];try{return await _0x43b476();}finally{if(_0x7ce2a===undefined)delete _0xfcc1b[SKIP_KEY];else _0xfcc1b[SKIP_KEY]=_0x7ce2a;}}function normalizeHost(_0x2f7ae9){const _0x49b02a=_0x558e8f;if(!_0x2f7ae9)return'';return _0x2f7ae9['trim']()[_0x49b02a(0x1c3)]()[_0x49b02a(0x326)](/:\d+$/,'');}var SKIP_KEY2=_0x558e8f(0x171);function tableHasDepartmentId(_0x1ec066){const _0x1f4418=_0x558e8f;return _0x1ec066[_0x1f4418(0x280)]!=null;}function resolveDataScope(){const _0x271943=_0x558e8f,_0x1aefe8=Context[_0x271943(0x248)]();if(!_0x1aefe8)return _0x271943(0x319);if(_0x1aefe8[SKIP_KEY2])return _0x271943(0x319);if(_0x1aefe8[_0x271943(0x23c)])return'all';const _0xc6f0e=_0x1aefe8[_0x271943(0x27a)];if(_0xc6f0e==null||_0xc6f0e==='')return _0x271943(0x319);if(_0xc6f0e===_0x271943(0x241))return _0x271943(0x241);if(_0xc6f0e===_0x271943(0x270))return _0x271943(0x270);const _0x262bfd=_0x1aefe8[_0x271943(0x227)],_0x15c127=Array['isArray'](_0x262bfd)?_0x262bfd[_0x271943(0x31e)](_0x10a755=>Number(_0x10a755))[_0x271943(0x1a7)](_0x3b96e8=>Number[_0x271943(0x301)](_0x3b96e8)&&_0x3b96e8>0x0):[];if(!_0x15c127[_0x271943(0x293)])return _0x271943(0x270);return[...new Set(_0x15c127)];}function applyDataScopeWhere(_0x38a5ee,_0xb5c9cd){const _0x253403=_0x558e8f;if(!tableHasDepartmentId(_0x38a5ee))return _0xb5c9cd;const _0x4cbecf=resolveDataScope();if(_0x4cbecf===_0x253403(0x319)||_0x4cbecf===_0x253403(0x241))return _0xb5c9cd;const _0x138d9d=_0x38a5ee[_0x253403(0x280)],_0x4f9b46=_0x4cbecf==='none'?_0x44764e`false`:_0xda578d(_0x138d9d,_0x4cbecf);if(_0xb5c9cd)return _0x1cd4c(_0xb5c9cd,_0x4f9b46);return _0x4f9b46;}function applyRowScopes(_0x1b5f09,_0x5bfb78){return applyDataScopeWhere(_0x1b5f09,applyTenantWhere(_0x1b5f09,_0x5bfb78));}async function noDataScope(_0x242a35){const _0xd8ff0b=_0x558e8f,_0x477439=Context[_0xd8ff0b(0x248)]();if(!_0x477439)return _0x242a35();const _0x35d72d=_0x477439[SKIP_KEY2];_0x477439[SKIP_KEY2]=!![];try{return await _0x242a35();}finally{if(_0x35d72d===undefined)delete _0x477439[SKIP_KEY2];else _0x477439[SKIP_KEY2]=_0x35d72d;}}function deletedAtColumn(_0x1f5d3f){return _0x1f5d3f['deletedAt'];}function trashClause(_0xedb21a,_0x1094fb){const _0x4a3a5d=_0x558e8f;if(!resolveSoftDelete(_0x1094fb?.[_0x4a3a5d(0x2df)]))return;const _0x3fa371=deletedAtColumn(_0xedb21a);if(_0x3fa371==null)return;if(_0x1094fb?.['onlyTrashed'])return isNotNull(_0x3fa371);if(_0x1094fb?.[_0x4a3a5d(0x335)])return;return isNull(_0x3fa371);}function mergeWhere(_0x55ae06,_0x356a86){if(_0x55ae06&&_0x356a86)return _0x4e7f47(_0x356a86,_0x55ae06);return _0x55ae06??_0x356a86;}function applyJoins(_0xa6d98,_0x4195cc,_0x4fe087){const _0x2e5971=_0x558e8f;let _0x405f64=_0xa6d98;for(const _0x690a9b of _0x4fe087['join']??[]){const _0xacd5ab=_0x690a9b[_0x2e5971(0x31d)],_0x10a534=_0x690a9b['on'](_0x4195cc),_0x4cdffb=_0x690a9b['type']??_0x2e5971(0x2f6);_0x4cdffb===_0x2e5971(0x17c)||_0x4cdffb===_0x2e5971(0x245)?_0x405f64=_0x405f64[_0x2e5971(0x17c)](_0xacd5ab,_0x10a534):_0x405f64=_0x405f64[_0x2e5971(0x2f6)](_0xacd5ab,_0x10a534);}return _0x405f64;}function resolveSelect(_0x1517a8,_0x1b258e){const _0x371c57=_0x558e8f;if(_0x1b258e['select'])return _0x1b258e[_0x371c57(0x230)];return getTableColumns(_0x1517a8);}function countExpr(_0x2818b2,_0x13e760){const _0x95c34d=_0x2818b2['id'];if(_0x95c34d!=null&&_0x13e760)return countDistinct(_0x95c34d);if(_0x95c34d!=null)return count(_0x95c34d);return count(_0x1f31d0`*`);}async function queryWithOp(_0xf1fd4f,_0x23e9e8,_0x169612,_0x25498d){const _0x38f86b=_0x558e8f,_0x4704f7=await buildQueryOp(_0xf1fd4f,_0x23e9e8,_0x169612,_0x25498d[_0x38f86b(0x26b)]),_0x47fb03=trashClause(_0xf1fd4f,_0x25498d[_0x38f86b(0x244)]),_0x939abb=applyRowScopes(_0xf1fd4f,mergeWhere(_0x4704f7[_0x38f86b(0x327)],_0x47fb03)),_0x4706c2=resolveSelect(_0xf1fd4f,_0x169612),_0x2b768c=!!_0x169612['join']?.[_0x38f86b(0x293)],_0x37958e=Ioc[_0x38f86b(0x248)](DbStore)['drizzle'];let _0x27d366=applyJoins(_0x37958e[_0x38f86b(0x230)](_0x4706c2)[_0x38f86b(0x198)](_0xf1fd4f),_0xf1fd4f,_0x169612);if(_0x939abb)_0x27d366=_0x27d366[_0x38f86b(0x327)](_0x939abb);if(_0x4704f7[_0x38f86b(0x315)][_0x38f86b(0x293)])_0x27d366=_0x27d366[_0x38f86b(0x224)](..._0x4704f7[_0x38f86b(0x315)]);if(_0x25498d[_0x38f86b(0x1bb)]===_0x38f86b(0x320))return await _0x27d366;const _0x1ec3ed=Math[_0x38f86b(0x18b)](0x1,Number(_0x23e9e8['page']??0x1)),_0x206304=Math[_0x38f86b(0x1fe)](0x64,Math[_0x38f86b(0x18b)](0x1,Number(_0x23e9e8[_0x38f86b(0x1d5)]??0x14))),_0xe42790=(_0x1ec3ed-0x1)*_0x206304,_0x26d15f=await _0x27d366[_0x38f86b(0x269)](_0x206304)[_0x38f86b(0x262)](_0xe42790);let _0x5019b3=applyJoins(_0x37958e[_0x38f86b(0x230)]({'value':countExpr(_0xf1fd4f,_0x2b768c)})[_0x38f86b(0x198)](_0xf1fd4f),_0xf1fd4f,_0x169612);if(_0x939abb)_0x5019b3=_0x5019b3['where'](_0x939abb);const _0x47064a=await _0x5019b3,_0x5e1949=Number(_0x47064a[0x0]?.[_0x38f86b(0x1f8)]??0x0);return{'list':_0x26d15f,'pagination':{'page':_0x1ec3ed,'size':_0x206304,'total':_0x5e1949}};}import{and as _0x2776a2,count as _0x3bbf04,eq as _0x3314f7,inArray as _0x5095e3,isNotNull as _0x49cabc,isNull as _0x2b1170}from'drizzle-orm';import{createInsertSchema,createSelectSchema,createUpdateSchema}from'drizzle-zod';function entitySchemas(_0x521892){return{'select':createSelectSchema(_0x521892),'insert':createInsertSchema(_0x521892),'update':createUpdateSchema(_0x521892)};}var WRITE_META_KEYS=[_0x558e8f(0x259),_0x558e8f(0x2ba),_0x558e8f(0x254)];function sanitizeWritePayload(_0x50c1fd){const _0x4a8f21=_0x558e8f,_0x54c9b7=_0x50c1fd&&typeof _0x50c1fd==='object'&&!Array[_0x4a8f21(0x2dc)](_0x50c1fd)?{..._0x50c1fd}:{};for(const _0x186c8b of WRITE_META_KEYS)delete _0x54c9b7[_0x186c8b];for(const [_0x2837f2,_0x5a6e80]of Object[_0x4a8f21(0x2e7)](_0x54c9b7)){if(typeof _0x5a6e80!==_0x4a8f21(0x222))continue;if(!/^\d{4}-\d{2}-\d{2}/[_0x4a8f21(0x274)](_0x5a6e80))continue;const _0x5dcbff=new Date(_0x5a6e80);if(!Number['isNaN'](_0x5dcbff[_0x4a8f21(0x22f)]()))_0x54c9b7[_0x2837f2]=_0x5dcbff;}return _0x54c9b7;}function isSqlLike(_0x12a7b9){const _0x3eb0ce=_0x558e8f;return!!_0x12a7b9&&typeof _0x12a7b9===_0x3eb0ce(0x1b1)&&_0x12a7b9[_0x3eb0ce(0x2ee)]!=null;}function db(){const _0x38bf5f=_0x558e8f;return Ioc[_0x38bf5f(0x248)](DbStore)[_0x38bf5f(0x1c9)];}function tableId(_0xccf443){const _0x5e5dd7=_0x558e8f,_0x5e8037=_0xccf443['id'];if(!_0x5e8037)throw new Error(_0x5e5dd7(0x167));return _0x5e8037;}function _0x10f3(){const _0x4fae75=['CgX1z2LU','zgvZAwDUoNr5Cgu','Ahr0CdOVl2XVy2fS','yxnJ','lw1Hy3jV','BwLU','ioE8UUwWKsb0B2TLBIdMIjyGCMvZB2X2zq','z2v0rNvSBfLLyxi','lI90ExbPBMDZl2fKBwLUlYO','ugfYyw0','CgX1z2LUu2vYDMLJzq','qxv0Aa','zw5K','Dg9vChbLCKnHC2u','zgLY','w0fWCf0G5BEY5zcV5yQO77Ym6k+35ywiiefWCc5ZDg9WkcKG5yAnihn0yxj0','C2vYDMLJzufWAxm','z2v0rgf0zq','zNvUy3rPB24','DhLWAw5NCY9Hzg1PBG','pJ05lJaUma','B25SEvrYyxnOzwq','yxbWBgLJyxrPB24VB2n0zxqTC3rYzwfT','C2nVCgu','ioMCGoMfJEE9RIbLBNrPDhKG5OIwihnLCNzPy2u','y2fJAguTy29UDhjVBa','CgfNzq','w0nsvurDia','Cgf0Aa','DMfSAwrHDgLVBIbMywLSzwq','lI9KAxn0l2LUzgv4lMPZ','yMLUzevUDgL0Eq','yxv0Aa','Bg9N','Axnoyu4','D2vI','C3rHDhvZ','w0LVy10GuMvXDwvZDcdKVzZNLkJLN5/POBVLNkJOR7FMSylKUiRKUiVMLOFKUk3OP6pMNPdVViJOR7FNOA7ORQqGyxn5BMndB250zxH0twfUywDLCI5LBMfIBgxVViK','C3fS','qNvU','tK9ux0zpvu5e','C3rYAw5N','z2v0u3rVCMu','B3jKzxjcEq','zMLLBgrmAwTL','lI9KAxn0l2fKBwLUl2LUzgv4lMPZ','zgf0yvnJB3bLrgvWDeLKCW','y29UDgvUDc10ExbL','DMfYifbSDwDPBIa9','w1jLCg9ZAxrVCNLDioIHQoAxOcbKzwXLDgvKqxtVViZML6dMS5xMGAlLPi0','AwDUB3jLugvYBxm','y2fJAgu','zxHWB3j0CW','Dg9tDhjPBMC','z2v0vgLTzq','C2vSzwn0','C2nOzw1H','mtf0A1bnshG','C2f2zq','B3bLBMfWAq','C2v0rw50Axr5','CMvXDwLYzq','zMLUze9Uzq','ugX1z2LU','Aw5MBW','q2fJAgu','mti0ndeZmxPYB1PmBq','AxntDxbLCG','zM9Yy2u','ue9tva','BgLZDcbMywLSzwq','w2nVBhvTBKnVBw1LBNrZxsdPNz7MS5xMOiFOR4BNRky6ia','ywXS','zMLLBgrsyw5Nzq','B25szxf1zxn0','DhjHC2G','AM9PBG','Bw9KAwz5qMvMB3jL','Ec1YzwfSlwLW','z2v0','ywrKigzHAwXLza','AxneAxjLy3rVCNK','lI9KAxn0l2fKBwLUl3n0EwXLCY9IyxnLlMnZCW','ywrTAw5bDxrO','ChjLzML4','vM9TzsbMCMfTzxDVCMSG4OcuihnOyxjLzcaRiej1BI9fBhLZAweGC2vYDMvYicSGvNvLigfKBwLU','w0nVBNrYB2XSzxjDiea','BwvZC2fNzq','zgvMyxvSDe5VDW','Aw5KzxGUAhrTBa','C2v0rgf0zq','zgvSzxrLzef0','kgfUB255Bw91CYK','D2fYBG','DhjPBq','B25czwzVCMviyw5KBgu','y3jLyxrLvgLTzq','ChjVCgvYDhLoyw1L','Aw5Zzxj0','CgfYC2u','l2LUzM8','w01VzhvSzv0GBg9HzcbMywLSzwqG','qM9KEq','uhjVDg90ExbL','C2LKzq','B2zMC2v0','tK9erv9ftLy','C3rVCa','mta0mZzSywjXyLq','zgvMAw5Ltwv0ywrHDge','DxnLq2XHC3m','C3jJl2XPyI9WBhvNAw4VAw5KzxGUDhm','BgLTAxq','mtK4mti1mufWAhHPwa','CMvXDwvZDa','CgvYBxm','BwLJCM9bChbZ','mc4WlJeY','lI9KAxn0l2fKBwLUl2LUzgv4lMqUDhm','BM9Uzq','ywn0Aw9U','lMPZ','zgvSzxrLigzHAwXLza','DgvZDa','Bw9KDwXLCW','BgLZDff1zxj5t3a','C2vYDMLJzq','w1jVDxrLCL0G5PYQ55+L5y+c5PwW5P2L5RQqoIa','vKfmsurbveLptG','zgf0yvnJB3bL','u0Lhsu5u','DxbKyxrLigzHAwXLza','CgfNzsbMywLSzwq','zM9Yy2vezwXLDgu','Dgv4Dc9ODg1SoYbJAgfYC2v0pxv0zI04','zgvWyxj0BwvUDeLK','Bw9KAwz5qwz0zxi','q09ntuvovcbptIbdt0Xvtu4G','6z2E5Rov5QIH5z2xigTLEtOG','Bw9KDwXLlwDHDgv3yxK','tw9KDwXL','kIOVBw9KDwXLCY8Ql3nLCNzPy2uVkIOVkI50CW','w01VzhvSzv0GBg9HzgvKia','mZi3Cu1UveHi','D2vIqxv0Aa','C291CMnL','A2v5CW','C3jJl3nOyxjLza','pJ0ZlJuUma','C3LTyM9S','kqOGia','5QIH5z2xia','xJaUmI4Y','AgvHzgvYCW','BgvUz3rO','DgfNCW','y3j1za','zgvSzxrL','yxv0B0nYDwq','Aw5KzxGUANm','yMLUza','ChjVDg90ExbL','Cgf0y2G','lMXVzW','Bw9KDwXL','B3bLCMf0Aw9UvgL0BgvtB3vYy2u','ywrK','ioMfJEE9RUs6HIbHCgKVC2vYDMLJzufWAxpVViZKVyBMNkRMIB7LIlaGq1jvrcdLRP7NJRdVViHaDM9Tzs1JB3jLigf0DgfJAenYDwrsB3v0zxmG5PYQ5OYc6l2977Yj','zw52','ioEAHoEXU+wEI++8JoIVT+AyVUw8J+s8OowfPsb0B2TLBG','AwrZ','CgfNzvf1zxj5t3a','cUkwIokwIokvLYaGiokwIokwIokvLYaGiokwIokwIokwIokwIokwIokwIokvLYaGiokwIokwIokwIokvLYaGiokwIokwIokwIokvLYaG4PAi4PAi4PAi4PAi4PAi4PAi4PAi4PwxcUkwIokwIokvKsaGiokwIokwIokvKsaG4PAi4PAi4Pwu4Pwq4Pwq4Pwq4PAi4PAi4PwxicdILOJILOJILOJILOJILzCG4PAi4PAi4PAi4PAi4PwricdILOJILOJILztILzdILzdILzdILzdILz0k4PAi4PAi4PwricaG4PAi4PAi4PwricdILOJILOJILzeGicdILOJILOJILzeGiokwIokwIokvLokwIokwIokwIokwIokvLokwIokwIokvKsaG4PAi4PAi4PAi4PAi4PAi4PwxcIdILOJILOJILzCG4PAi4PAi4Pwu4PwDicdILOJILOJILzeGicdILOJILOJILzeGiokwIokwIokvKEkvMUkwIokwIokvLokvNEkwIokwIokvKsaG4PAi4PAi4Pwu4Pwq4Pwq4PwDcIaG4PwA4PAi4PAi4PAi4Pwu4PwDicaG4PwA4PAi4PAi4PAi4PAi4PAi4PAi4Pwu4PwDicdILOJILOJILzeG4PwA4Pwq4PwDiokwIokwIokvKsaG4PAi4PAi4PAi4PAi4PAi4PAi4PAi4PwxcIaGiokvMUkvKokvKokvNsaGicaG4PwA4Pwq4Pwq4Pwq4Pwq4Pwq4PwDicaG4PwA4Pwq4PwDicaGicdILzRILzdILz0GiokvMUkvKokvKokvKokvKokvKokvKokvNqO','w1f1zxj5t3bDioIHQoAxOowTL+AUTtOG','ywrTAw4','y29UDhjVBgXLCG','CgX1z2LUsw5MBW','AgfUzgXLCG','DhjHBNnWB3j0','ioIHQoAxOcbPzcdLIjC','ihnPBMDSzxrVBIHZkq','l2rVy3m','C29YDa','y2fSBa','zMLUzej5swq','u2LUz2XLDg9U','BM90tNvSBa','Aw50BW','Dg9Rzw4','ChjPBwfYEuTLEq','yxnZAwDU','pJ0ZlJaUma','pJ0WlJiUma','DxbKyxrLvgLTzq','lNn2zW','yNvUihnJCMLWDhmVB2jMDxnJyxrLlNrZ','xJaUms4Xma','DMfYigHHBMrSzxjZid0','ChvIBgLJ','iowJSoAyJUs6HIbYB3v0zxmG5l2g57Y65BcrihnLCNzLCI9PBMrLEc5QCW','yxbP','r0vu','lI9KAxn0l2LUzgv4lMqUDhm','CMv0DxjUAw5N','w0HVC3rDignYDwqG4OAqieb2B21LlwnVCMuVB3jT','Aw5KzxG','ios4JEAyR+ACIEAvIoAwUEAZLq','yMvMB3jL','Bg9Hza','DMfSDwvZ','qxbWig5VDcbMB3vUza','w1jLCg9ZAxrVCNLDioAjUEMhJ+ABToAwSoAVJ+ADOEMCGow4PIbPza','Ec1MB3j3yxjKzwqTzM9Y','y2yTy29UBMvJDgLUzY1PCa','rvjst1i','ChvZAa','y3r4','CMvZDg9YzsbMywLSzwq','l2fKBwLUl2v4Dc86A2v5','C3jJl2XPyI90yxnRl2LUzgv4lNrZ','AwqGCMvXDwLYzwq','5yIG6zMK5PE26zE0','z2v0uMvWBW','yNvUigj1AwXKic4VC3jJl2LUzgv4lNrZic4VC3jJl3nLCNzLCI9PBMrLEc50CYaTlw91DgrPCIaUl2rPC3qGls10yxjNzxqGyNvUic0TzM9YBwf0igvZBsaTlwv4DgvYBMfSigvSExnPysaTlwv4DgvYBMfSihjLzMXLy3qTBwv0ywrHDgeGls1LEhrLCM5HBcbKCML6EMXLlw9YBsaTlwv4DgvYBMfSigrYAxP6BguTEM9Kic0TzxH0zxjUywWGqgvSExnPywPZl29Wzw5HCgKGls1LEhrLCM5HBcbayM9NzxLJAgfUl2vSExnPys1SB2DNzxiGls1LEhrLCM5HBcbWAw5Vic0TzxH0zxjUywWGCgLUBY1WCMv0DhKGjIyGDhnJic1WihrZy29UzMLNlMj1AwXKlMPZB24GjIyGChjPBNrMiciLC1XUiIaIzxHWB3j0icOGzNjVBsaNlI9ZCMmVAw5KzxGNiIa+igrPC3qVAw5KzxGUzc50CYaMjIbTA2rPCIaTCcbKAxn0l3nLCNzLCIaMjIbWCMLUDgyGiIvZxg4IicjLEhbVCNqGkIbMCM9TicCUlI9ZCMmVC2vYDMvYl2LUzgv4jYiGpIbKAxn0l3nLCNzLCI9PBMrLEc5KlNrZ','Cg9W','C3rKB3v0','z2v0twv0ywrHDge','AxnbCNjHEq','zMLLBgrfCq','y29SDw1UvhLWzq','C29MDerLBgv0zq','BwLKzgXLD2fYzq','C3yTu0u','57Y65Bcrig1VzhvSzs5QC29UoIa','mtj1CvH2v3C','yMvMB3jLsgfUzgXL','w1jLCg9ZAxrVCNLDioIHQoAxOcbKzwXLDgvKqxtVViZML6dMS5xOVA/LIkdPMAq','BwLJCM8TyxbWCY1ZDgf0Awm','zw50CMLLCW','8j+tOsdMNi3LIQhLNldLNya6ia','l3vWzgf0zq','nda1nZu0ngzvqurIwq','u1vdq0vtuW','zgLNzxn0','xJaUoc4Z','z2v0u1fm','BwfUAwzLC3q','C2nVCgvKv2HLCMu','w0jHC2vtzxj2AwnLxsdMNkRNU5hLRPRLRP7KVzpVViZOR7FKVB/NLkGGqeLUAMvJDfjLCg9ZAxrVCNKG5OIwihnLDevUDgL0Eq','C3rHCNrZv2L0Aa','l3jLC3rVCMu','y3jLyxrL','yM9VDhn0CMfW','BgvMDePVAw4','C2v0','xJeWlJmUmq','lNDVzMy','C3bSAxq','C3jJl2XPyI9TB2r1BguVAw5KzxGUDhm','AgfZ','B3jKzxi','zw5HyMXL','zw50Axr5','zgvMyxvSDa','AxngAw5PDgu','CMvZDg9Yzq','DxbZzxj0','5PU05PAW5PE26zE0','pJ0YlJaUma','zgLZCgf0y2G','zgv2lNrZ','zw5KC1DPDgG','AgfUzgXLCIdNVlRLPle6ia','yM9KEq','Dgv4Dc9JC3m7ignOyxjZzxq9DxrMltG','rw50Axr5','xJuUnc43','C3rHCNq','yxn5BMndB250zxH0twfUywDLCG','C3jJl2nVBMzPzW','C3vTBwfYEq','qMfZzvbSDwDPBG','AxnfCNjVCG','BgfZDeLUzgv4t2y','B3jKzxjcEvnXBa','zM9YBwf0','y29TBwvUDa','zg9JDw1LBNrHDgLVBG','B2zM','zgv2','Bwv0Ag9K','ioMhJEwKJsba','DgfIBgu','BwfW','CMfUz2u','BgLZDa','BMfTzq','CMvZB2X2zuLKv2HLCMu','Aw5PDa','w0LVy10Gsw9JlNnLDcG','6lEV55sX5lIn5A2y5zYO','CMvWBgfJzq','D2HLCMu','w0LVy10GyM9VDhn0CMfWiokgKca','A2v5v29YzeXPA2vgAwvSzhm','y2XHC3nPyW','zgvZy3jPChrPB24','CMvXDwLYzuvUDgL0Eq','rM9YyMLKzgvU','CMvXDwvZDeXVzW','A2v5v29Yza','sw52ywXPzcbHChaGA2v5','C2XPy2u','g1SYsHTBsa','zgLZDa','BM8Ty2fJAgu','D2L0AfrYyxnOzwq','zgvSzxrLtwv0ywrHDge','ywnJzxnZlwnVBNrYB2WTywXSB3CTB3jPz2LU','yM9VBgvHBG','Aw5JBhvKzxm','DxjS','CM91DgvqyxjHBxm','CMvXDwvZDfbHCMfT','AwrZihjLCxvPCMvK','BNvTyMvY','zgvIDwC','pJ0WlJmWlJa','nJyXmtGWzhnmqMHK','w1jLCg9ZAxrVCNLDioIHQoAxOcbPzcdLIjFVViZOR7FMLlNNLkGGzMLUzcH3AgvYzsKGlYbMAw5Kt25LkhDOzxjLkq','C3rHDhvZq29Kzq','CM91DgvZ','zgf0yvr5Cgu','khSGqMfZzvbSDwDPBIb9kq','zxH0zw5K','ChjVza','zMLSzq','DM9TztPJB250CM9SBgvYoNjVDxrLlxb1yMXPyW','yNvUihj1BIbIDwLSzdPVyMz1C2nHDgu','x19ZA2LWrgf0yvnJB3bL','zMfPBa','y2XLyxi','C3vWCg9YDhntB2z0rgvSzxrL','DxbKyxrL','Bgf5B3v0','lMPZB24','8j+mJsdOV5dOOyZNJQ/LOOm6ia','zgf0yq','nJC3nJG5mhPwAeX6Cq','CMvHzhK','Aw5UzxjkB2LU','uxvLCNK','cNzHCIbFx1bSDwDPBIa9icH0ExbLB2yGugX1z2LUice9psaNDw5KzwzPBMvKjYKkica/ifbSDwDPBGOGidOGkg1VzhvSzs5LEhbVCNrZicyMicHTB2r1BguUzxHWB3j0CY5qBhvNAw4GFhWGBw9KDwXLlMv4Cg9YDhmUzgvMyxvSDcb8FcbTB2r1BguUzxHWB3j0CYKPoWPPzIaODhLWzw9Mif9FugX1z2LUid09psaNDw5KzwzPBMvKjYb8FcbFx1bSDwDPBIa9pt0GBNvSBcKGEWOGihrOCM93ig5LDYbfCNjVCIGNBwLZC2LUzYbLEhbVCNqGugX1z2LUjYK7cN0kCMv0DxjUif9FugX1z2LUoW','DgfIBgvFBMfTzq','lMPWzwC','zMLLBgrbCNjHEq','ywrTAw5jza','u1LtoNn0yw5KyxjK','CM0GlxjMigrPC3qGjIyGyNvUihj1BIbIDwLSzdPZzxj2zxiGjIyGyNvUihj1BIbIDwLSzdPHzg1PBG','DM9Tzs1JB3jL','y2XVC2u','uefuq0G','Cgf0Ag5HBwu','DM9Tzq','DgvUyw50swq','Bwf4','Dw5ZywzL','CgfKu3rHCNq','l2fWCa','y2HHCKf0','DxbKyxrLqNLsB3DZ','icHWDwjSAwmP','CxvLCNK','zxjYB3i','AhjLzG','revmrvrf','ios4JEAyR+ACIEAvIcbOyw5KBgvY','Ec1MB3j3yxjKzwqTAg9ZDa','zNjVBq','CgfYyw1Z','C29Tzq','Bgf0zxn0','DM9TztPJB250CM9SBgvYoNjVDxrLlwLNBM9Yzs1WzxjTCW','DxnL','C2nHBgfY','DM9TztPJB250CM9SBgvYoNjVDxrLCY1Wzw5KAw5N','AxngAwXL','kIOVBw9KDwXLCY8Ql2nVBNrYB2XSzxiVywrTAw4VkIOVkI50CW','rgf0zvrPBwvgB3jTyxq','y29UDgvUDa','y2XPzw50','w1jVDxrLCL0GCMvNAxn0zxjLzcdIHPaG','lI9KAxn0l3nLCNzLCI9PBMrLEc5QCW','zMLSDgvY','CgfYC2vjBNnLCNq','pJ00lJaUma','Bwq1','w0LVy10GqeLUAMvJDcdML6dMS5xMJQJMLQ0G','C2nHBG','ywrKt3jKzxjcEq','Bgv2zwW','w29IAMvJDcbpyMPLy3rD','cMLMicH0ExbLB2yGAgfUzgXLCNmGpt09icD1BMrLzMLUzwqNksbYzxr1CM4GBNvSBdSkCMv0DxjUigHHBMrSzxjZoW','B2jQzwn0','DM9TztPJB250CM9SBgvYoNjVDxrLlw1PzgrSzxDHCMu','zMLUza','w0LVy10G5PYQ5RoO5yAm55QeifbYB3zPzgvYoIa','l2rLBgv0zq','l2XPC3q','Bg9JywXLq29TCgfYzq','C3LZDgvT','5yIg6Ag15P+L6k+I','uMvXDwvZDa','Bw9Kzq','Aw1Hz2uVCg5N','zMLUzfbHz2u','DxrMoa','C2LUz2XLDg9U','ihjVDxrLkhmP','D3jPDgu','ioE8UUwWKsbOyw5KBgvYoIa','Dg9mB3DLCKnHC2u','C3jJl21PzgrSzxDHCMuVAw5KzxGUDhm','AgfUzgXLCNm','Aw5Zzxj0ugfYyw0','mI1KAwDPDa','Cg9ZDa','zhjPENPSzq','C3vJy2vZCW','Bg9Nz2LUzW','y3DK','5yIx6kgO5P+L6k+I','y291BNq','y29SDw1Ux25HBwu','AxnuvfK','y29SDw1U','Bw9KDwXLlMPZB24','CNvU','5yIB5BU65PE26zE0','C2L6zq','5QIH5z2x5PYQ5yQG6l29','B25fCNjVCG','w0LVy10G5PYQ55+L5l2C55sO5z+FoIa','Cg9YDa','yxbW','Bw9KDwXLr2f0zxDHEq','zM9UDc93B2zM','w1jVDxrLCL0G','mwTuANb5uW','ChjVzc50CW','Dw5RBM93BG','Bwf0y2G','lM1QCW','ioMfJEE9RUs6HIbZzxj2AwnLqxbPC++8JoMCGowqJoAxTUMfJEE9RIbZzxj2AwnL','y29Kzq','CM91DgvpChrPB25Z','vgfZAW','mti3mdy1nw13yu5JvG','w0LVy10G','CMfUzg9Tvvvjra','tM90iezVDw5K','Ahr0CdOVl2XVy2fSAg9ZDdO','l2fKza','qxnPys9tAgfUz2HHAq','Chv0','AgfZrw50Axr5','y29UC3rYDwn0B3i','zxbZ','DMvYC2LVBG','lI9KAxn0l3nLCNzLCI9PBMrLEc5KlNrZ','w0HVC3rDihnJyw4G4OAqia','BM93','zgLJDa','yxbWBgLJyxrPB24VANnVBG','DMfSDwu'];_0x10f3=function(){return _0x4fae75;};return _0x10f3();}function deletedAtColumn2(_0x3e07cb){const _0x37f5cf=_0x558e8f;return _0x3e07cb[_0x37f5cf(0x254)];}function mergeWhere2(_0x59a2b8,_0x56ea3a){if(_0x59a2b8&&_0x56ea3a)return _0x2776a2(_0x56ea3a,_0x59a2b8);return _0x59a2b8??_0x56ea3a;}function trashClause2(_0x224de0,_0xbdfdb){const _0x471dea=_0x558e8f;if(!resolveSoftDelete(_0xbdfdb?.[_0x471dea(0x2df)]))return;const _0x2c9f36=deletedAtColumn2(_0x224de0);if(_0x2c9f36==null)return;if(_0xbdfdb?.['onlyTrashed'])return _0x49cabc(_0x2c9f36);if(_0xbdfdb?.[_0x471dea(0x335)])return;return _0x2b1170(_0x2c9f36);}class Repository{[_0x558e8f(0x31d)];[_0x558e8f(0x231)];constructor(_0x1e9dc4,_0x11c0e0){const _0x1385c4=_0x558e8f;this['table']=_0x1e9dc4,this[_0x1385c4(0x231)]=_0x11c0e0??entitySchemas(_0x1e9dc4);}['supportsSoftDelete'](){const _0x1ba1e8=_0x558e8f;return deletedAtColumn2(this[_0x1ba1e8(0x31d)])!=null;}[_0x558e8f(0x2f0)](_0x54cd35,_0x11f750){const _0x27d785=_0x558e8f;return applyRowScopes(this[_0x27d785(0x31d)],mergeWhere2(_0x54cd35,trashClause2(this['table'],_0x11f750)));}async['find'](_0x44462c,_0x2e48aa){const _0x6c616f=_0x558e8f,_0x199ec8=this[_0x6c616f(0x2f0)](_0x44462c,_0x2e48aa);let _0x5c7124=db()['select']()['from'](this[_0x6c616f(0x31d)]);if(_0x199ec8)_0x5c7124=_0x5c7124[_0x6c616f(0x327)](_0x199ec8);if(_0x2e48aa?.[_0x6c616f(0x224)]?.[_0x6c616f(0x293)])_0x5c7124=_0x5c7124['orderBy'](..._0x2e48aa[_0x6c616f(0x224)]);return await _0x5c7124;}async[_0x558e8f(0x237)](_0x1dfe33,_0x55a72e){const _0x25f092=_0x558e8f,[_0x5d5cec]=await this[_0x25f092(0x1b3)](_0x1dfe33,_0x55a72e);return _0x5d5cec;}async[_0x558e8f(0x2b1)](_0x13e3e3,_0x149a3b){const _0x3d56bd=_0x558e8f;return this['findOne'](_0x3314f7(tableId(this[_0x3d56bd(0x31d)]),_0x13e3e3),_0x149a3b);}async[_0x558e8f(0x1ce)](_0x1906ed,_0x2407e4){const _0x1243e0=_0x558e8f,_0x1101e1=this['scopedWhere'](_0x1906ed,_0x2407e4),_0x30289=db()['select']({'value':_0x3bbf04()})[_0x1243e0(0x198)](this['table']),_0x2b0150=_0x1101e1?await _0x30289[_0x1243e0(0x327)](_0x1101e1):await _0x30289;return Number(_0x2b0150[0x0]?.[_0x1243e0(0x1f8)]??0x0);}async[_0x558e8f(0x1bd)](_0x11b304){const _0x1e581c=_0x558e8f,{page:_0x5ccd1d,size:_0x342fda,where:_0x1c634b,orderBy:_0x4a505c,withTrashed:_0x3f894b,onlyTrashed:_0xdadd2e,softDelete:_0x566f23}=_0x11b304,_0x4b37c6={'withTrashed':_0x3f894b,'onlyTrashed':_0xdadd2e,'softDelete':_0x566f23},_0x78bd65=this[_0x1e581c(0x2f0)](_0x1c634b,_0x4b37c6),_0x3ecd46=(_0x5ccd1d-0x1)*_0x342fda;let _0x4a7d68=db()[_0x1e581c(0x230)]()[_0x1e581c(0x198)](this[_0x1e581c(0x31d)]);if(_0x78bd65)_0x4a7d68=_0x4a7d68[_0x1e581c(0x327)](_0x78bd65);if(_0x4a505c?.[_0x1e581c(0x293)])_0x4a7d68=_0x4a7d68[_0x1e581c(0x224)](..._0x4a505c);const _0x18a3ee=await _0x4a7d68[_0x1e581c(0x269)](_0x342fda)[_0x1e581c(0x262)](_0x3ecd46),_0x26e606=await this[_0x1e581c(0x1ce)](_0x1c634b,_0x4b37c6);return{'list':_0x18a3ee,'pagination':{'page':_0x5ccd1d,'size':_0x342fda,'total':_0x26e606}};}[_0x558e8f(0x1a8)](_0x4e4683){const _0x58e266=_0x558e8f,_0x111287=stampTenantId(this[_0x58e266(0x31d)],sanitizeWritePayload(_0x4e4683));return this[_0x58e266(0x231)][_0x58e266(0x25b)][_0x58e266(0x25c)](_0x111287);}async[_0x558e8f(0x2f4)](_0x87fabf){const _0x2afce8=_0x558e8f;if(Array['isArray'](_0x87fabf)){if(!_0x87fabf[_0x2afce8(0x293)])return[];const _0x413780=_0x87fabf[_0x2afce8(0x31e)](_0x28ae9f=>this['parseInsert'](_0x28ae9f));return await db()[_0x2afce8(0x25b)](this[_0x2afce8(0x31d)])[_0x2afce8(0x2ca)](_0x413780)[_0x2afce8(0x2c4)]();}const [_0x2afc97]=await db()[_0x2afce8(0x25b)](this[_0x2afce8(0x31d)])[_0x2afce8(0x2ca)](this[_0x2afce8(0x1a8)](_0x87fabf))[_0x2afce8(0x2c4)]();return _0x2afc97;}async['save'](_0x55f4e4){const _0xe2faa0=_0x558e8f;if(Array['isArray'](_0x55f4e4)){if(!_0x55f4e4[_0xe2faa0(0x293)])return[];const _0x2bfca6=_0x55f4e4,_0x16170e=tableId(this[_0xe2faa0(0x31d)]),_0x35f4b8=_0x2bfca6['filter'](_0x27317b=>_0x27317b?.['id']!=null&&_0x27317b['id']!==''),_0x4f411e=_0x2bfca6['filter'](_0x2dfb72=>_0x2dfb72?.['id']==null||_0x2dfb72['id']==='');let _0x5378ab=new Set();if(_0x35f4b8[_0xe2faa0(0x293)]){const _0x1240ed=await this[_0xe2faa0(0x1b3)](_0x5095e3(_0x16170e,_0x35f4b8[_0xe2faa0(0x31e)](_0x5897a7=>_0x5897a7['id'])));_0x5378ab=new Set(_0x1240ed[_0xe2faa0(0x31e)](_0x5cebf0=>_0x5cebf0['id']));}const _0x16313e=[],_0xe1c9a8=[..._0x4f411e];for(const _0x5de7b6 of _0x35f4b8){if(_0x5378ab[_0xe2faa0(0x2fc)](_0x5de7b6['id']))_0x16313e[_0xe2faa0(0x2d0)](_0x5de7b6);else _0xe1c9a8[_0xe2faa0(0x2d0)](_0x5de7b6);}const _0x3aa28d=_0x16313e[_0xe2faa0(0x293)]?await this[_0xe2faa0(0x175)](_0x16313e):[],_0x593d75=_0xe1c9a8[_0xe2faa0(0x293)]?await this[_0xe2faa0(0x2f4)](_0xe1c9a8):[];return[...Array['isArray'](_0x3aa28d)?_0x3aa28d:_0x3aa28d?[_0x3aa28d]:[],...Array[_0xe2faa0(0x2dc)](_0x593d75)?_0x593d75:_0x593d75?[_0x593d75]:[]];}const _0x48d833=_0x55f4e4,_0x3651b9=_0x48d833?.['id'];if(_0x3651b9!=null&&_0x3651b9!==''){const _0x5b6796=await this[_0xe2faa0(0x2b1)](_0x3651b9);if(_0x5b6796){const {id:_0x6f0caf,..._0x1d1709}=_0x48d833,_0x385f3b=await this[_0xe2faa0(0x175)](_0x3314f7(tableId(this[_0xe2faa0(0x31d)]),_0x3651b9),_0x1d1709);return _0x385f3b??_0x5b6796;}}return await this['create'](_0x55f4e4);}async[_0x558e8f(0x175)](_0x48afe2,_0x487a5f){const _0x5e28b2=_0x558e8f;if(Array[_0x5e28b2(0x2dc)](_0x48afe2))return this[_0x5e28b2(0x190)](_0x48afe2);const _0x14d781=this[_0x5e28b2(0x231)][_0x5e28b2(0x175)][_0x5e28b2(0x25c)](sanitizeWritePayload(_0x487a5f)),_0x34f8e3=applyRowScopes(this[_0x5e28b2(0x31d)],_0x48afe2);if(!_0x34f8e3)return;const [_0x206c3d]=await db()[_0x5e28b2(0x175)](this['table'])[_0x5e28b2(0x2f7)](_0x14d781)[_0x5e28b2(0x327)](_0x34f8e3)[_0x5e28b2(0x2c4)]();return _0x206c3d;}async[_0x558e8f(0x190)](_0x145efa){const _0x22172d=_0x558e8f;if(!_0x145efa['length'])return[];const _0x5004e7=tableId(this[_0x22172d(0x31d)]),_0x4a9ff=new Map();for(const _0x3e0ccb of _0x145efa){const _0x43567b=_0x3e0ccb['id'];if(_0x43567b==null||_0x43567b==='')throw new Error(_0x22172d(0x2cc));const {id:_0x5da1df,..._0x38c85f}=_0x3e0ccb,_0x40012f=this[_0x22172d(0x231)][_0x22172d(0x175)][_0x22172d(0x25c)](sanitizeWritePayload(_0x38c85f)),_0x3ba740=JSON['stringify'](_0x40012f),_0x5de2c2=_0x4a9ff[_0x22172d(0x248)](_0x3ba740);if(_0x5de2c2)_0x5de2c2['ids'][_0x22172d(0x2d0)](_0x43567b);else _0x4a9ff[_0x22172d(0x2f7)](_0x3ba740,{'ids':[_0x43567b],'patch':_0x40012f});}const _0x288c00=[];for(const {ids:_0x5afcea,patch:_0x150bed}of _0x4a9ff[_0x22172d(0x2ca)]()){const _0x2f43e3=applyRowScopes(this[_0x22172d(0x31d)],_0x5095e3(_0x5004e7,_0x5afcea));if(!_0x2f43e3)continue;const _0x2d9e3d=await db()[_0x22172d(0x175)](this['table'])[_0x22172d(0x2f7)](_0x150bed)[_0x22172d(0x327)](_0x2f43e3)[_0x22172d(0x2c4)]();_0x288c00[_0x22172d(0x2d0)](..._0x2d9e3d);}return _0x288c00;}['resolveIdWhere'](_0x2fd26e){const _0x153bd6=_0x558e8f;if(isSqlLike(_0x2fd26e))return applyRowScopes(this['table'],_0x2fd26e);const _0x1f3c33=Array[_0x153bd6(0x2dc)](_0x2fd26e)?_0x2fd26e:[_0x2fd26e];if(!_0x1f3c33[_0x153bd6(0x293)])return;return applyRowScopes(this['table'],_0x5095e3(tableId(this[_0x153bd6(0x31d)]),_0x1f3c33));}async['softDelete'](_0x114ca2){const _0x3e2ef7=_0x558e8f;if(!this[_0x3e2ef7(0x174)]())throw new Error(_0x3e2ef7(0x2e5));const _0x21e5d1=this['resolveIdWhere'](_0x114ca2);if(!_0x21e5d1)return;await db()['update'](this[_0x3e2ef7(0x31d)])['set']({'deletedAt':new Date()})['where'](_0x21e5d1);}async[_0x558e8f(0x302)](_0x1b966b){const _0x37d3b7=_0x558e8f;if(!this['supportsSoftDelete']())throw new Error(_0x37d3b7(0x22a));const _0x87b313=this[_0x37d3b7(0x322)](_0x1b966b);if(!_0x87b313)return;await db()['update'](this[_0x37d3b7(0x31d)])['set']({'deletedAt':null})[_0x37d3b7(0x327)](_0x87b313);}async['forceDelete'](_0xe5607e){const _0x133d17=_0x558e8f,_0x35375d=this[_0x133d17(0x322)](_0xe5607e);if(!_0x35375d)return;await db()[_0x133d17(0x296)](this[_0x133d17(0x31d)])[_0x133d17(0x327)](_0x35375d);}}var repoCache=new WeakMap();function getRepository(_0x502900){const _0x439c0f=_0x558e8f,_0x238eeb=repoCache[_0x439c0f(0x248)](_0x502900);if(_0x238eeb)return _0x238eeb;const _0x344bf3=new Repository(_0x502900);return repoCache[_0x439c0f(0x2f7)](_0x502900,_0x344bf3),_0x344bf3;}function InjectRepository(_0x272737){return(_0x286997,_0x4c2bf3)=>{const _0x163834=_0x16aa;appendInjectMeta(_0x286997[_0x163834(0x1f0)],{'propertyKey':_0x4c2bf3,'resolve':()=>getRepository(_0x272737)});};}function isSql(_0x236631){const _0x250a7b=_0x558e8f;return!!_0x236631&&typeof _0x236631===_0x250a7b(0x1b1)&&_0x236631[_0x250a7b(0x2ee)]!=null;}class BaseService{[_0x558e8f(0x2ff)];[_0x558e8f(0x218)](_0x5c0618){const _0x1ac0f5=_0x558e8f;if(!this[_0x1ac0f5(0x2ff)])this['entity']=_0x5c0618;}[_0x558e8f(0x235)](_0x3a1d42){const _0x1d8d1a=_0x558e8f;this[_0x1d8d1a(0x2ff)]=_0x3a1d42;}[_0x558e8f(0x1ef)](){const _0x2f56e0=_0x558e8f;return!!this[_0x2f56e0(0x2ff)];}[_0x558e8f(0x2d7)](){const _0x4fa85a=_0x558e8f;return this[_0x4fa85a(0x32c)]();}[_0x558e8f(0x32c)](){const _0x5956db=_0x558e8f;if(!this['entity'])throw new Error(_0x5956db(0x2f1));return this[_0x5956db(0x2ff)];}async[_0x558e8f(0x246)](_0x36600e,_0x3be81e){}async[_0x558e8f(0x281)](_0xf1fd1e,_0xd0c3ba){}async[_0x558e8f(0x29f)](_0x2cc7d3,_0x1ab1ce){const _0x144087=_0x558e8f,_0x561379=resolveUpsert(_0x1ab1ce?.['upsert']),_0x4c8277=Array['isArray'](_0x2cc7d3)?_0x2cc7d3['map'](_0x1fed95=>_0x1fed95!=null&&typeof _0x1fed95==='object'?{..._0x1fed95}:_0x1fed95):_0x2cc7d3!=null&&typeof _0x2cc7d3===_0x144087(0x1b1)?{..._0x2cc7d3}:_0x2cc7d3;await this[_0x144087(0x246)](_0x4c8277,'add');const _0x35ca00=_0x561379===_0x144087(0x233)?await this[_0x144087(0x32c)]()[_0x144087(0x233)](_0x4c8277):await this[_0x144087(0x32c)]()[_0x144087(0x2f4)](_0x4c8277);return await this[_0x144087(0x281)](_0x35ca00??_0x4c8277,_0x144087(0x29f)),_0x35ca00;}async[_0x558e8f(0x175)](_0xa86c1d,_0x268ae6){const _0x890fe3=_0x558e8f;if(Array[_0x890fe3(0x2dc)](_0xa86c1d)){const _0x2993ba=_0xa86c1d[_0x890fe3(0x31e)](_0x387055=>({..._0x387055}));await this[_0x890fe3(0x246)](_0x2993ba,_0x890fe3(0x175));const _0x51ab04=await this[_0x890fe3(0x32c)]()[_0x890fe3(0x175)](_0x2993ba);return await this[_0x890fe3(0x281)](_0x51ab04??_0x2993ba,_0x890fe3(0x175)),_0x51ab04;}if(isSql(_0xa86c1d)){const _0x564cd3=_0x268ae6!=null&&typeof _0x268ae6===_0x890fe3(0x1b1)?{..._0x268ae6}:_0x268ae6;await this[_0x890fe3(0x246)](_0x564cd3,'update');const _0x20f511=await this[_0x890fe3(0x32c)]()[_0x890fe3(0x175)](_0xa86c1d,_0x564cd3);return await this[_0x890fe3(0x281)](_0x20f511??_0x564cd3,_0x890fe3(0x175)),_0x20f511;}const _0x210c4e={..._0xa86c1d};await this[_0x890fe3(0x246)](_0x210c4e,_0x890fe3(0x175));const _0x179be7=await this[_0x890fe3(0x32c)]()['update']([_0x210c4e]);return await this[_0x890fe3(0x281)](_0x179be7??_0x210c4e,_0x890fe3(0x175)),Array[_0x890fe3(0x2dc)](_0x179be7)?_0x179be7[0x0]:_0x179be7;}async['delete'](_0x1040ce,_0x4942fb){const _0x413c14=_0x558e8f,_0x1a3373=this[_0x413c14(0x32c)]();await this[_0x413c14(0x246)](_0x1040ce,_0x413c14(0x296));const _0x5cb8df=resolveSoftDelete(_0x4942fb?.[_0x413c14(0x2df)]);_0x4942fb?.[_0x413c14(0x23d)]||!_0x5cb8df||!_0x1a3373[_0x413c14(0x174)]()?await _0x1a3373[_0x413c14(0x27e)](_0x1040ce):await _0x1a3373[_0x413c14(0x2df)](_0x1040ce),await this[_0x413c14(0x281)](_0x1040ce,'delete');}[_0x558e8f(0x302)](_0x3424d0){const _0x18fd87=_0x558e8f;return this['requireEntity']()[_0x18fd87(0x302)](_0x3424d0);}[_0x558e8f(0x320)](_0x4ef188,_0x304650){const _0x4982a9=_0x558e8f;return this['requireEntity']()[_0x4982a9(0x1b3)](_0x4ef188,_0x304650);}[_0x558e8f(0x239)](_0x382a54,_0x2dc0ff){const _0x4a8d36=_0x558e8f,_0x5382fe=this[_0x4a8d36(0x32c)]();if(typeof _0x382a54===_0x4a8d36(0x1b1))return _0x5382fe[_0x4a8d36(0x237)](_0x382a54,_0x2dc0ff);return _0x5382fe['findById'](_0x382a54,_0x2dc0ff);}[_0x558e8f(0x213)](_0x1e490b={}){const _0x16de1f=_0x558e8f,_0x79e151=Math[_0x16de1f(0x18b)](0x1,_0x1e490b['page']??0x1),_0x13928b=Math[_0x16de1f(0x1fe)](0x64,Math[_0x16de1f(0x18b)](0x1,_0x1e490b[_0x16de1f(0x1d5)]??0x14));return this[_0x16de1f(0x32c)]()[_0x16de1f(0x1bd)]({'page':_0x79e151,'size':_0x13928b,'where':_0x1e490b[_0x16de1f(0x327)],'orderBy':_0x1e490b[_0x16de1f(0x224)],'withTrashed':_0x1e490b[_0x16de1f(0x335)],'onlyTrashed':_0x1e490b['onlyTrashed'],'softDelete':_0x1e490b[_0x16de1f(0x2df)]});}}var CRUD_SUMMARY={'add':'\u65B0\u589E','delete':'\u5220\u9664','update':'\u4FEE\u6539','info':'\u5355\u4E2A\u4FE1\u606F','list':_0x558e8f(0x1cd),'page':_0x558e8f(0x1b9),'restore':'\u6062\u590D'},CRUD_APIS=[_0x558e8f(0x29f),_0x558e8f(0x296),_0x558e8f(0x175),'info',_0x558e8f(0x320),_0x558e8f(0x213),'restore'],BEFORE_APIS=new Set([_0x558e8f(0x29f),_0x558e8f(0x175),_0x558e8f(0x296),'restore']);function omitProps(_0x482bbd,_0x3a40ca){if(!_0x482bbd||!_0x3a40ca?.['length'])return _0x482bbd;const _0x3f126f={..._0x482bbd};for(const _0x16ae69 of _0x3a40ca)delete _0x3f126f[_0x16ae69];return _0x3f126f;}function resolveIds(_0x6fc6df){const _0x4ce74c=_0x558e8f;if(Array[_0x4ce74c(0x2dc)](_0x6fc6df))return _0x6fc6df['map'](_0xecf8ab=>{const _0x40152c=_0x4ce74c;if(_0xecf8ab!=null&&typeof _0xecf8ab===_0x40152c(0x1b1)&&'id'in _0xecf8ab)return _0xecf8ab['id'];return _0xecf8ab;});if(_0x6fc6df&&typeof _0x6fc6df===_0x4ce74c(0x1b1)){const _0x3b809b=_0x6fc6df;if(Array[_0x4ce74c(0x2dc)](_0x3b809b[_0x4ce74c(0x2a3)]))return _0x3b809b[_0x4ce74c(0x2a3)];if(_0x3b809b['id']!=null)return[_0x3b809b['id']];}return[];}function resolveService(_0x126f0a){const _0x638fc1=_0x558e8f,_0x13d56d=_0x126f0a[_0x638fc1(0x295)],_0x155389=_0x13d56d[_0x638fc1(0x2ff)];if(_0x13d56d['service']){const _0x3ed389=Ioc[_0x638fc1(0x248)](_0x13d56d[_0x638fc1(0x277)]);if(_0x155389&&!_0x3ed389[_0x638fc1(0x1ef)]())_0x3ed389[_0x638fc1(0x235)](getRepository(_0x155389));return _0x3ed389;}if(!_0x155389)throw new Error(_0x638fc1(0x214)+_0x126f0a['token']['name']+_0x638fc1(0x211));const _0x327efb=new class extends BaseService{}();return _0x327efb[_0x638fc1(0x235)](getRepository(_0x155389)),_0x327efb;}function tableOf(_0x1dfca5,_0x142523){const _0x2b3bd6=_0x558e8f,_0x3fa2bc=_0x142523[_0x2b3bd6(0x295)]?.[_0x2b3bd6(0x2ff)];if(_0x3fa2bc)return _0x3fa2bc;return _0x1dfca5['getRepo']()['table'];}var attachCrudRoutes=(_0x249e39,_0x337ab5,_0x45f828)=>{const _0x47f00e=_0x558e8f,_0x54745=_0x337ab5[_0x47f00e(0x295)];if(!_0x54745)return _0x249e39;const _0x29dfa6=(_0x54745['api']??[])[_0x47f00e(0x1a7)](_0x3c438e=>CRUD_APIS[_0x47f00e(0x339)](_0x3c438e)),_0x1d3f46=_0x54745[_0x47f00e(0x209)]??[];if(!_0x29dfa6[_0x47f00e(0x293)]&&!_0x1d3f46['length'])return _0x249e39;const _0x3a5d1b=_0x45f828[_0x47f00e(0x2a8)]instanceof BaseController?_0x45f828[_0x47f00e(0x2a8)]:new BaseController(),_0x42ce61=_0x29dfa6[_0x47f00e(0x293)]>0x0,_0x25967f=_0x42ce61||_0x54745[_0x47f00e(0x277)]?resolveService(_0x337ab5):undefined,_0x1fab35=_0x42ce61&&_0x25967f?tableOf(_0x25967f,_0x337ab5):undefined,_0x416c16=_0x1fab35?_0x1fab35['id']:undefined;if(_0x42ce61&&_0x416c16==null)throw new Error('[CRUD]\x20'+_0x337ab5[_0x47f00e(0x2b5)][_0x47f00e(0x321)]+_0x47f00e(0x2ac));let _0x3438c3=_0x249e39;const _0x37d338=(_0x2eed08,_0x2dffa1,_0x560641,_0x18d11f)=>{const _0x30a558=_0x47f00e;_0x3438c3=_0x3438c3[_0x2eed08](_0x2dffa1,_0x18d11f,_0x45f828[_0x30a558(0x1e5)]({'action':_0x560641,'summary':CRUD_SUMMARY[_0x560641]}));},_0xa051c0=async(_0xcbb804,_0xccb796,_0x3d507b)=>{const _0x5c9151=_0x47f00e;if(!_0x54745[_0x5c9151(0x2c8)]||!BEFORE_APIS['has'](_0xcbb804))return _0xccb796;return await _0x54745['before']({'body':_0xccb796,'request':_0x3d507b,'api':_0xcbb804}),_0xccb796;};_0x29dfa6[_0x47f00e(0x339)]('add')&&_0x25967f&&_0x37d338(_0x47f00e(0x1c8),_0x47f00e(0x1ec),'add',async({body:_0x2223f7,request:_0x2ddbdc})=>{const _0x1d79e7=_0x47f00e;try{const _0x5e75b5=_0x2223f7;if(Array[_0x1d79e7(0x2dc)](_0x5e75b5)){let _0x53f7bb=_0x5e75b5;if(_0x54745[_0x1d79e7(0x2c8)]&&BEFORE_APIS['has'](_0x1d79e7(0x29f)))for(let _0x36cc14=0x0;_0x36cc14<_0x53f7bb[_0x1d79e7(0x293)];_0x36cc14++){_0x53f7bb[_0x36cc14]=await _0xa051c0(_0x1d79e7(0x29f),{..._0x53f7bb[_0x36cc14]??{}},_0x2ddbdc);}if(_0x54745[_0x1d79e7(0x1c6)]){const _0x747b09=await _0x54745[_0x1d79e7(0x1c6)]({'body':_0x53f7bb[0x0]??{},'request':_0x2ddbdc});_0x53f7bb=_0x53f7bb['map'](_0x92f9a9=>({..._0x92f9a9,..._0x747b09}));}const _0x4ca36c=await _0x25967f['add'](_0x53f7bb);return _0x3a5d1b['ok'](_0x4ca36c);}let _0x3bfe21={..._0x5e75b5??{}};_0x3bfe21=await _0xa051c0('add',_0x3bfe21,_0x2ddbdc);_0x54745[_0x1d79e7(0x1c6)]&&Object[_0x1d79e7(0x2b7)](_0x3bfe21,await _0x54745[_0x1d79e7(0x1c6)]({'body':_0x3bfe21,'request':_0x2ddbdc}));const _0x2fcf3a=await _0x25967f[_0x1d79e7(0x29f)](_0x3bfe21);return _0x3a5d1b['ok'](_0x2fcf3a);}catch(_0x3e87dd){return _0x3a5d1b['fail'](_0x3e87dd instanceof Error?_0x3e87dd[_0x1d79e7(0x250)]:_0x1d79e7(0x249));}});_0x29dfa6[_0x47f00e(0x339)]('delete')&&_0x25967f&&_0x416c16&&_0x37d338(_0x47f00e(0x1c8),_0x47f00e(0x1b5),_0x47f00e(0x296),async({body:_0x276b03,request:_0x184fcb})=>{const _0x2710f9=_0x47f00e;try{const _0x39b65b=_0x276b03,_0x323c17=Array[_0x2710f9(0x2dc)](_0x39b65b)?_0x39b65b:await _0xa051c0('delete',{..._0x39b65b??{}},_0x184fcb),_0x4ac70a=resolveIds(_0x323c17);if(!_0x4ac70a['length'])return _0x3a5d1b[_0x2710f9(0x172)](_0x2710f9(0x33d));const _0x6c5d99=!Array[_0x2710f9(0x2dc)](_0x323c17)&&!!_0x323c17['force'];return await _0x25967f[_0x2710f9(0x296)](_0x4ac70a,{'force':_0x6c5d99}),_0x3a5d1b['ok']();}catch(_0x25b5d5){return _0x3a5d1b[_0x2710f9(0x172)](_0x25b5d5 instanceof Error?_0x25b5d5['message']:_0x2710f9(0x273));}});_0x29dfa6[_0x47f00e(0x339)](_0x47f00e(0x175))&&_0x25967f&&_0x416c16&&_0x37d338(_0x47f00e(0x1c8),_0x47f00e(0x2e9),_0x47f00e(0x175),async({body:_0x213166,request:_0x6adc0d})=>{const _0x77634=_0x47f00e;try{const _0x1d5af0=_0x213166;if(Array[_0x77634(0x2dc)](_0x1d5af0)){let _0x1929e5=_0x1d5af0;if(_0x54745[_0x77634(0x2c8)]&&BEFORE_APIS[_0x77634(0x2fc)](_0x77634(0x175)))for(let _0x9f5719=0x0;_0x9f5719<_0x1929e5[_0x77634(0x293)];_0x9f5719++){_0x1929e5[_0x9f5719]=await _0xa051c0('update',{..._0x1929e5[_0x9f5719]??{}},_0x6adc0d);}const _0x35a49e=await _0x25967f[_0x77634(0x175)](_0x1929e5);return _0x3a5d1b['ok'](_0x35a49e);}const _0x48ce2e=await _0xa051c0('update',{..._0x1d5af0??{}},_0x6adc0d),_0x34901b=_0x48ce2e['id'];if(_0x34901b==null)return _0x3a5d1b[_0x77634(0x172)]('id\x20required');const _0x5e5080=await _0x25967f['update'](_0x48ce2e);return _0x3a5d1b['ok'](_0x5e5080);}catch(_0x4d8ad4){return _0x3a5d1b[_0x77634(0x172)](_0x4d8ad4 instanceof Error?_0x4d8ad4[_0x77634(0x250)]:_0x77634(0x27c));}});_0x29dfa6[_0x47f00e(0x339)](_0x47f00e(0x239))&&_0x25967f&&_0x37d338('get',_0x47f00e(0x25d),_0x47f00e(0x239),async({query:_0x4c0d09})=>{const _0x13bbb0=_0x47f00e;try{const _0x4c0854=_0x4c0d09?.['id'];if(_0x4c0854==null||_0x4c0854==='')return _0x3a5d1b[_0x13bbb0(0x172)](_0x13bbb0(0x2d5));const _0x41f9b5=await _0x25967f['info'](_0x4c0854);return _0x3a5d1b['ok'](omitProps(_0x41f9b5,_0x54745['infoIgnoreProperty']));}catch(_0xc510d7){return _0x3a5d1b[_0x13bbb0(0x172)](_0xc510d7 instanceof Error?_0xc510d7['message']:'info\x20failed');}});_0x29dfa6[_0x47f00e(0x339)](_0x47f00e(0x320))&&_0x25967f&&_0x1fab35&&_0x37d338(_0x47f00e(0x1c8),_0x47f00e(0x1b6),_0x47f00e(0x320),async({body:_0x3c7fe0,request:_0x3922d5})=>{const _0x438c9f=_0x47f00e;try{const _0x56131f=_0x3c7fe0??{},_0x4381de=_0x54745[_0x438c9f(0x276)]??{},_0x4eb3a0={'onlyTrashed':_0x56131f[_0x438c9f(0x20e)]===!![],'withTrashed':_0x56131f['withTrashed']===!![]};if(needsAdvancedQuery(_0x4381de)){const _0x1d4830=await queryWithOp(_0x1fab35,_0x56131f,_0x4381de,{'request':_0x3922d5,'mode':'list','trash':_0x4eb3a0});return _0x3a5d1b['ok'](_0x1d4830);}const {where:_0x107812,orderBySql:_0x11444c}=await buildQueryOp(_0x1fab35,_0x56131f,_0x4381de,_0x3922d5),_0x2ca3df=await _0x25967f[_0x438c9f(0x320)](_0x107812,{'orderBy':_0x11444c,..._0x4eb3a0});return _0x3a5d1b['ok'](_0x2ca3df);}catch(_0x159adf){return _0x3a5d1b[_0x438c9f(0x172)](_0x159adf instanceof Error?_0x159adf[_0x438c9f(0x250)]:_0x438c9f(0x23f));}});_0x29dfa6[_0x47f00e(0x339)]('page')&&_0x25967f&&_0x1fab35&&_0x37d338('post','/page',_0x47f00e(0x213),async({body:_0x371cb0,request:_0x33dbf9})=>{const _0x4168c5=_0x47f00e;try{const _0x1805d0=_0x371cb0??{},_0x3515fe=_0x54745[_0x4168c5(0x2a4)]??{},_0x377611={'onlyTrashed':_0x1805d0[_0x4168c5(0x20e)]===!![],'withTrashed':_0x1805d0[_0x4168c5(0x335)]===!![]};if(needsAdvancedQuery(_0x3515fe)){const _0x478361=await queryWithOp(_0x1fab35,_0x1805d0,_0x3515fe,{'request':_0x33dbf9,'mode':'page','trash':_0x377611});return _0x3a5d1b['ok'](_0x478361);}const {where:_0x21caaa,orderBySql:_0x407a4d}=await buildQueryOp(_0x1fab35,_0x1805d0,_0x3515fe,_0x33dbf9),_0x5f1f7=await _0x25967f[_0x4168c5(0x213)]({'page':Number(_0x1805d0[_0x4168c5(0x213)]??0x1),'size':Number(_0x1805d0['size']??0x14),'where':_0x21caaa,'orderBy':_0x407a4d,..._0x377611});return _0x3a5d1b['ok'](_0x5f1f7);}catch(_0x5cb514){return _0x3a5d1b[_0x4168c5(0x172)](_0x5cb514 instanceof Error?_0x5cb514['message']:_0x4168c5(0x27d));}});_0x29dfa6['includes'](_0x47f00e(0x302))&&_0x25967f&&_0x416c16&&_0x37d338(_0x47f00e(0x1c8),_0x47f00e(0x2f3),_0x47f00e(0x302),async({body:_0x316463,request:_0x453de3})=>{const _0x3d20ce=_0x47f00e;try{const _0x7a250e=_0x316463,_0x579bcc=Array[_0x3d20ce(0x2dc)](_0x7a250e)?_0x7a250e:await _0xa051c0(_0x3d20ce(0x302),{..._0x7a250e??{}},_0x453de3),_0x6b1fa4=resolveIds(_0x579bcc);if(!_0x6b1fa4[_0x3d20ce(0x293)])return _0x3a5d1b[_0x3d20ce(0x172)](_0x3d20ce(0x33d));return await _0x25967f['restore'](_0x6b1fa4),_0x3a5d1b['ok']();}catch(_0x48764a){return _0x3a5d1b[_0x3d20ce(0x172)](_0x48764a instanceof Error?_0x48764a[_0x3d20ce(0x250)]:_0x3d20ce(0x2d2));}});if(_0x1d3f46[_0x47f00e(0x293)]){if(!_0x54745[_0x47f00e(0x277)])throw new Error(_0x47f00e(0x214)+_0x337ab5['token'][_0x47f00e(0x321)]+_0x47f00e(0x1e3));const _0x15b40=Ioc['get'](_0x54745['service']);for(const _0x211a87 of _0x1d3f46){const _0x2da821=_0x15b40[_0x211a87];if(typeof _0x2da821!==_0x47f00e(0x20b))throw new Error('[CRUD]\x20'+_0x54745[_0x47f00e(0x277)]['name']+'.'+_0x211a87+_0x47f00e(0x2c7));const _0xa6102c=_0x2da821[_0x47f00e(0x299)](_0x15b40);_0x37d338('post','/'+_0x211a87,_0x211a87,async({body:_0x59a805})=>{const _0x4d3993=_0x47f00e;try{const _0x2f3bc7=await _0xa6102c(_0x59a805);return _0x3a5d1b['ok'](_0x2f3bc7);}catch(_0x41dd51){return _0x3a5d1b[_0x4d3993(0x172)](_0x41dd51 instanceof Error?_0x41dd51['message']:_0x211a87+'\x20failed');}});}}return _0x3438c3;};import{join as _0x57c0bb}from'path';import{pathToFileURL as _0x8af44}from'url';var SERVICE_PATTERN=_0x558e8f(0x286),CONTROLLER_SCANS=[{'pattern':_0x558e8f(0x1a1),'side':_0x558e8f(0x2a7)},{'pattern':'**/modules/*/controller/app/**/*.ts','side':_0x558e8f(0x1da)}];async function importWithContext(_0x4dedb5,_0x55ed86,_0x1d4d3e){const _0x2dc0b4=_0x558e8f;setControllerScanContext({'module':parseModuleFromPath(_0x55ed86),'side':_0x1d4d3e,'file':_0x55ed86});try{const _0x3c2e15=_0x8af44(_0x57c0bb(_0x4dedb5,_0x55ed86))[_0x2dc0b4(0x194)];await import(_0x3c2e15);}finally{setControllerScanContext(null);}}async function scanHost(){const _0x4381c6=_0x558e8f,_0x5edd79=process['cwd'](),_0x4bda38=await scanFiles(SERVICE_PATTERN,{'cwd':_0x5edd79});for(const _0x5c95ee of _0x4bda38){const _0x454966=_0x8af44(_0x57c0bb(_0x5edd79,_0x5c95ee))[_0x4381c6(0x194)];await import(_0x454966);}let _0x14282e=0x0;for(const {pattern:_0x17adcb,side:_0x328a16}of CONTROLLER_SCANS){const _0x3b3d04=await scanFiles(_0x17adcb,{'cwd':_0x5edd79});_0x14282e+=_0x3b3d04[_0x4381c6(0x293)];for(const _0x17aafb of _0x3b3d04){await importWithContext(_0x5edd79,_0x17aafb,_0x328a16);}}setCrudRegistrar(attachCrudRoutes),console[_0x4381c6(0x21a)](_0x4381c6(0x2c5)),console[_0x4381c6(0x21a)](_0x4381c6(0x1f4)+_0x4bda38[_0x4381c6(0x293)]+'\x20service,\x20'+_0x14282e+'\x20controller\x20file(s)');}import{join as _0x5b7b42}from'path';import{createPinoLogger}from'@bogeychan/elysia-logger';import _0x5917fe from'pino-pretty';import{createWriteStream,mkdirSync,readdirSync,unlinkSync}from'fs';import{join as _0x30340c}from'path';import{Writable}from'stream';var FILE_PATTERN=/^(\d{4}-\d{2}-\d{2})\.log$/;function formatLocalDate(_0x27dcd1=new Date()){const _0x30a73c=_0x558e8f,_0x589b62=_0x27dcd1[_0x30a73c(0x200)](),_0x1e7856=String(_0x27dcd1['getMonth']()+0x1)[_0x30a73c(0x18d)](0x2,'0'),_0x5873ee=String(_0x27dcd1[_0x30a73c(0x20a)]())['padStart'](0x2,'0');return _0x589b62+'-'+_0x1e7856+'-'+_0x5873ee;}function purgeOldLogs(_0x1d5dac,_0x444bcf){const _0xd0e56e=_0x558e8f,_0x187270=new Date();_0x187270[_0xd0e56e(0x253)](_0x187270[_0xd0e56e(0x20a)]()-_0x444bcf);const _0xde53f6=formatLocalDate(_0x187270);for(const _0x33f8c0 of readdirSync(_0x1d5dac)){const _0x4eee35=_0x33f8c0[_0xd0e56e(0x1e1)](FILE_PATTERN);if(!_0x4eee35||_0x4eee35[0x1]>=_0xde53f6)continue;unlinkSync(_0x30340c(_0x1d5dac,_0x33f8c0));}}function openDailyStream(_0x2ed28e,_0x120583){const _0xd43586=_0x558e8f;return createWriteStream(_0x30340c(_0x2ed28e,_0x120583+_0xd43586(0x29c)),{'flags':'a'});}function createDailyLogStream(_0xeaf698,_0x464ce8=0x1e){mkdirSync(_0xeaf698,{'recursive':!![]}),purgeOldLogs(_0xeaf698,_0x464ce8);let _0x5c6941=formatLocalDate(),_0x538c5e=openDailyStream(_0xeaf698,_0x5c6941);return new Writable({'write'(_0x3d2d20,_0x148458,_0x4d541a){const _0x28389e=formatLocalDate();_0x28389e!==_0x5c6941&&(_0x538c5e['end'](),_0x5c6941=_0x28389e,_0x538c5e=openDailyStream(_0xeaf698,_0x5c6941),purgeOldLogs(_0xeaf698,_0x464ce8)),_0x538c5e['write'](_0x3d2d20,_0x4d541a);},'final'(_0x4641b5){const _0x4421d3=_0x16aa;_0x538c5e[_0x4421d3(0x205)](_0x4641b5);}});}var pinoInstance;function buildPino(){const _0x4a2b25=_0x558e8f,_0x2860ad=VomeConfig[_0x4a2b25(0x1cb)]??{},_0xba2dfc=_0x2860ad[_0x4a2b25(0x1ae)]??_0x4a2b25(0x239);if(_0x2860ad[_0x4a2b25(0x2ab)]===_0x4a2b25(0x16e)){const _0x5c6ae2=_0x5b7b42(process[_0x4a2b25(0x1cc)](),_0x2860ad[_0x4a2b25(0x207)]??_0x4a2b25(0x1cb)),_0x22ec05=_0x2860ad['maxDays']??0x1e;return createPinoLogger({'level':_0xba2dfc,'stream':createDailyLogStream(_0x5c6ae2,_0x22ec05)});}return createPinoLogger({'level':_0xba2dfc,'stream':_0x5917fe({'colorize':!![],'translateTime':_0x4a2b25(0x183),'ignore':'pid,hostname'})});}function getPinoLogger(){if(!pinoInstance)pinoInstance=buildPino();return pinoInstance;}function resetPinoLogger(){pinoInstance=undefined;}class Logger{[_0x558e8f(0x239)](_0x19f047,..._0xf38ada){const _0x142a0e=_0x558e8f,_0x2bba70=getPinoLogger();if(_0xf38ada[_0x142a0e(0x293)])_0x2bba70[_0x142a0e(0x239)]({'args':_0xf38ada},_0x19f047);else _0x2bba70[_0x142a0e(0x239)](_0x19f047);}['warn'](_0x2c5c17,..._0x2e19f9){const _0x1cde01=_0x558e8f,_0x3fa310=getPinoLogger();if(_0x2e19f9['length'])_0x3fa310['warn']({'args':_0x2e19f9},_0x2c5c17);else _0x3fa310[_0x1cde01(0x256)](_0x2c5c17);}['debug'](_0x1e18fa,..._0x4d2b01){const _0x2a139f=_0x558e8f,_0xc40e11=getPinoLogger();if(_0x4d2b01[_0x2a139f(0x293)])_0xc40e11[_0x2a139f(0x164)]({'args':_0x4d2b01},_0x1e18fa);else _0xc40e11[_0x2a139f(0x164)](_0x1e18fa);}[_0x558e8f(0x193)](_0x326daf,..._0x3f5489){const _0x58a162=_0x558e8f,_0x5b5dd6=getPinoLogger();if(_0x326daf instanceof Error){_0x5b5dd6[_0x58a162(0x193)](_0x326daf);return;}if(_0x3f5489[0x0]instanceof Error){_0x5b5dd6['error'](_0x3f5489[0x0],_0x326daf);return;}if(_0x3f5489[_0x58a162(0x293)])_0x5b5dd6[_0x58a162(0x193)]({'args':_0x3f5489},_0x326daf);else _0x5b5dd6[_0x58a162(0x193)](_0x326daf);}}class CommException extends Error{[_0x558e8f(0x168)];[_0x558e8f(0x1e4)];constructor(_0x34c693,_0x24f04e){const _0x68da16=_0x558e8f;super(_0x34c693),this[_0x68da16(0x321)]='CommException',this[_0x68da16(0x168)]=_0x24f04e?.[_0x68da16(0x168)]??0xc8,this[_0x68da16(0x1e4)]=_0x24f04e?.[_0x68da16(0x1e4)]??RES_CODE[_0x68da16(0x2cf)];}}function isCommException(_0x5b1d3c){return _0x5b1d3c instanceof CommException;}function bootstrapLogger(){const _0x22e38d=_0x558e8f;getPinoLogger(),Ioc[_0x22e38d(0x2f7)](Logger,new Logger());}var VOME_BANNER=_0x558e8f(0x2a5);function resetViewport(){const _0x3f3a9a=_0x558e8f;if(!process[_0x3f3a9a(0x2da)][_0x3f3a9a(0x1d0)])return;process[_0x3f3a9a(0x2da)][_0x3f3a9a(0x1c1)](_0x3f3a9a(0x332));}function printStartupBanner(){const _0x27fc59=_0x558e8f;resetViewport();const _0x88042a=getEnv(),_0x4fb2af=VomeConfig[_0x27fc59(0x1b8)]?.[_0x27fc59(0x1d9)]??0xbb9,_0xd63a75=VomeConfig[_0x27fc59(0x234)]?.[_0x27fc59(0x215)]??_0x27fc59(0x2ae),_0x1ff153=_0x27fc59(0x1eb)+_0x4fb2af;console[_0x27fc59(0x21a)](VOME_BANNER),console[_0x27fc59(0x21a)](_0x27fc59(0x178)+_0x88042a),_0x88042a==='dev'&&(console['log'](_0x27fc59(0x2e8)+_0x1ff153),console[_0x27fc59(0x21a)]('📚\x20API文档:\x20'+_0x1ff153+(_0xd63a75[_0x27fc59(0x2f2)]('/')?_0xd63a75:'/'+_0xd63a75)));}import{access}from'fs/promises';import{join as _0x516c3e}from'path';import{pathToFileURL as _0xfff9db}from'url';async function exists(_0x4ce6fa){try{return await access(_0x4ce6fa),!![];}catch{return![];}}async function importHostModule(_0x37dfee){const _0x58a1db=_0x558e8f,_0x521d6f=_0x516c3e(process[_0x58a1db(0x1cc)](),_0x37dfee);if(!await exists(_0x521d6f)){console['warn']('[Host]\x20skip\x20←\x20missing\x20'+_0x37dfee);return;}return await import(_0xfff9db(_0x521d6f)[_0x58a1db(0x194)]);}async function bootstrapHostInfra(){const _0x1de688=_0x558e8f,_0x3ace9b=await importHostModule('src/lib/db/index.ts');if(_0x3ace9b?.['Db']?.[_0x1de688(0x2f5)])await _0x3ace9b['Db']['bootstrap']();const _0x16c01c=await importHostModule('src/lib/cache/index.ts');if(_0x16c01c?.[_0x1de688(0x23a)]?.[_0x1de688(0x2f5)])await _0x16c01c[_0x1de688(0x23a)]['bootstrap']();const _0x7e827e=await importHostModule('src/lib/auth/index.ts');if(_0x7e827e?.['Auth']?.[_0x1de688(0x2f5)])await _0x7e827e[_0x1de688(0x204)][_0x1de688(0x2f5)]();}async function bootstrapHostTasks(){const _0x4585e7=_0x558e8f,_0xf73abb=await importHostModule(_0x4585e7(0x2d4));if(_0xf73abb?.['Task']?.[_0x4585e7(0x2f5)])await _0xf73abb[_0x4585e7(0x1e6)][_0x4585e7(0x2f5)]();}async function bootstrapHostPlugins(){const _0x188f1e=_0x558e8f,_0xfb03be=await importHostModule(_0x188f1e(0x268));if(_0xfb03be?.[_0x188f1e(0x238)]?.['bootstrap'])await _0xfb03be[_0x188f1e(0x238)][_0x188f1e(0x2f5)]();}async function bootstrapHostModules(){const _0x4d67ac=_0x558e8f,_0x30b851=await importHostModule(_0x4d67ac(0x2fb));if(_0x30b851?.[_0x4d67ac(0x285)]?.[_0x4d67ac(0x2f5)])await _0x30b851['Module']['bootstrap']();}async function shutdownHostTasks(){const _0x50ad05=_0x558e8f,_0x3bef9f=await importHostModule(_0x50ad05(0x2d4));if(_0x3bef9f?.[_0x50ad05(0x1e6)]?.[_0x50ad05(0x186)])await _0x3bef9f[_0x50ad05(0x1e6)][_0x50ad05(0x186)]();}async function shutdownHostInfra(){const _0x250194=_0x558e8f,_0xf89d4=await importHostModule('src/lib/cache/index.ts');if(_0xf89d4?.[_0x250194(0x23a)]?.[_0x250194(0x186)])await _0xf89d4[_0x250194(0x23a)]['close']();const _0x156080=await importHostModule('src/lib/db/index.ts');if(_0x156080?.['Db']?.[_0x250194(0x186)])await _0x156080['Db']['close']();}async function applyHostAuthMiddleware(_0x1d068a){const _0x137513=_0x558e8f,_0x476077=await importHostModule(_0x137513(0x1c4));if(!_0x476077)return _0x1d068a;let _0x433935=_0x1d068a;if(_0x476077[_0x137513(0x289)])_0x433935=_0x433935[_0x137513(0x19d)](_0x476077['webAuth']);if(_0x476077['adminAuth'])_0x433935=_0x433935[_0x137513(0x19d)](_0x476077['adminAuth']);if(_0x476077[_0x137513(0x32e)])_0x433935=_0x433935[_0x137513(0x19d)](_0x476077[_0x137513(0x32e)]);if(_0x476077[_0x137513(0x26d)])_0x433935=_0x433935[_0x137513(0x19d)](_0x476077[_0x137513(0x26d)]);if(_0x476077[_0x137513(0x1db)])_0x433935=_0x433935[_0x137513(0x19d)](_0x476077[_0x137513(0x1db)]);return _0x433935;}function applyAsyncContext(_0x3cdb7f){const _0x5b4d8a=_0x558e8f,_0xb5b0db=VomeConfig[_0x5b4d8a(0x30f)]??{};if(!_0xb5b0db[_0x5b4d8a(0x2fe)])return _0x3cdb7f;return _0x3cdb7f[_0x5b4d8a(0x243)](({request:_0x3a4810})=>{enterContextWith(initContextFromRequest(_0x3a4810));});}function applyErrorHandler(_0x5ee88c){const _0x50abc5=_0x558e8f;return _0x5ee88c[_0x50abc5(0x1d7)](({error:_0x3a1dfe,set:_0x521564,code:_0x444235})=>{const _0x13f1b9=_0x50abc5,_0x1a4bfb=getPinoLogger();if(isCommException(_0x3a1dfe))return _0x1a4bfb[_0x13f1b9(0x193)]({'code':_0x3a1dfe[_0x13f1b9(0x1e4)]},_0x3a1dfe[_0x13f1b9(0x250)]),_0x521564[_0x13f1b9(0x21d)]=_0x3a1dfe['statusCode'],{'code':_0x3a1dfe[_0x13f1b9(0x1e4)],'message':_0x3a1dfe['message']};if(_0x444235===_0x13f1b9(0x279)){const _0x5adf84=_0x3a1dfe instanceof Error?_0x3a1dfe[_0x13f1b9(0x250)]:_0x13f1b9(0x216);return _0x1a4bfb['error']({'code':_0x444235},_0x5adf84),_0x521564[_0x13f1b9(0x21d)]=0x1a6,{'code':RES_CODE[_0x13f1b9(0x2cf)],'message':_0x5adf84};}if(_0x444235===_0x13f1b9(0x221))return _0x521564[_0x13f1b9(0x21d)]=0x194,{'code':RES_CODE[_0x13f1b9(0x2cf)],'message':'not\x20found'};const _0x150490=_0x3a1dfe instanceof Error?_0x3a1dfe:new Error(String(_0x3a1dfe));return _0x1a4bfb[_0x13f1b9(0x193)](_0x150490),_0x521564[_0x13f1b9(0x21d)]=0x1f4,{'code':RES_CODE['ERROR'],'message':getEnv()==='dev'?_0x150490[_0x13f1b9(0x250)]:'internal\x20server\x20error'};});}function _0x16aa(_0x4abf78,_0x59747a){_0x4abf78=_0x4abf78-0x163;const _0x10f327=_0x10f3();let _0x16aa4=_0x10f327[_0x4abf78];if(_0x16aa['WJsusi']===undefined){var _0x2d92a5=function(_0x4f7139){const _0x46b53c='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x19be4e='',_0x4e7f47='';for(let _0x1f31d0=0x0,_0x1cd4c,_0xda578d,_0x44764e=0x0;_0xda578d=_0x4f7139['charAt'](_0x44764e++);~_0xda578d&&(_0x1cd4c=_0x1f31d0%0x4?_0x1cd4c*0x40+_0xda578d:_0xda578d,_0x1f31d0++%0x4)?_0x19be4e+=String['fromCharCode'](0xff&_0x1cd4c>>(-0x2*_0x1f31d0&0x6)):0x0){_0xda578d=_0x46b53c['indexOf'](_0xda578d);}for(let _0x6892bb=0x0,_0x3d534a=_0x19be4e['length'];_0x6892bb<_0x3d534a;_0x6892bb++){_0x4e7f47+='%'+('00'+_0x19be4e['charCodeAt'](_0x6892bb)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4e7f47);};_0x16aa['xbQvlV']=_0x2d92a5,_0x16aa['mhUcNx']={},_0x16aa['WJsusi']=!![];}const _0x37df59=_0x10f327[0x0],_0x54460a=_0x4abf78+_0x37df59,_0x2751e0=_0x16aa['mhUcNx'][_0x54460a];return!_0x2751e0?(_0x16aa4=_0x16aa['xbQvlV'](_0x16aa4),_0x16aa['mhUcNx'][_0x54460a]=_0x16aa4):_0x16aa4=_0x2751e0,_0x16aa4;}function applyLogging(_0x42a87e){const _0x3a5698=_0x558e8f,_0x49a0bc=getPinoLogger();return _0x42a87e[_0x3a5698(0x19d)](_0x49a0bc[_0x3a5698(0x2b4)]({'autoLogging':{'ignore':_0x1ba052=>Boolean(_0x1ba052[_0x3a5698(0x313)])}}));}import{openapi}from'@elysiajs/openapi';function applyOpenapi(_0x56669a){const _0x2dbf3a=_0x558e8f,_0x22a464=VomeConfig[_0x2dbf3a(0x234)]??{'enable':![]};if(_0x22a464[_0x2dbf3a(0x2fe)]===![])return _0x56669a;const _0xe8c69f=_0x22a464[_0x2dbf3a(0x215)]??_0x2dbf3a(0x2ae),{tags:_0x49fdf7,tagGroups:_0x5a468e}=buildOpenApiTagDocs(),_0x23cfad=_0x22a464[_0x2dbf3a(0x318)]??{},_0x31127f=_0x22a464[_0x2dbf3a(0x19e)]??{};return _0x56669a['use'](openapi({'path':_0xe8c69f,'documentation':{..._0x23cfad,'tags':[..._0x23cfad[_0x2dbf3a(0x294)]??[],..._0x49fdf7],'x-tagGroups':_0x5a468e},'scalar':{..._0x31127f,'layout':_0x31127f[_0x2dbf3a(0x176)]??_0x2dbf3a(0x32a),'operationTitleSource':_0x31127f[_0x2dbf3a(0x29e)]??_0x2dbf3a(0x311)}}));}var app,started=![],signalsRegistered=![],hostScanned=![],bootstrapHooks=[],shutdownHooks=[],usePlugins=[];async function ensureHostScanned(){if(hostScanned)return;hostScanned=!![],await scanHost();}function createApp(){return applyAsyncContext(applyErrorHandler(applyLogging(new _0x19be4e())));}function bootstrap(_0x12860a){const _0x6a26c2=_0x558e8f;bootstrapHooks[_0x6a26c2(0x2d0)](_0x12860a);}function shutdown(_0x49e0fc){shutdownHooks['push'](_0x49e0fc);}function use(_0x23b0b5){usePlugins['push'](_0x23b0b5);}async function start(){const _0x3c4428=_0x558e8f;if(started)throw new Error(_0x3c4428(0x208));let _0x3bc5e9=createApp();_0x3bc5e9=await applyHostAuthMiddleware(_0x3bc5e9);for(const _0x145099 of usePlugins){_0x3bc5e9=_0x145099(_0x3bc5e9);}await ensureHostScanned(),_0x3bc5e9=applyOpenapi(_0x3bc5e9),await bootstrapHostInfra();for(const _0x40a133 of bootstrapHooks)await _0x40a133();bootstrapLogger(),bootstrapIoc(),await bootstrapHostPlugins(),await bootstrapHostModules(),await bootstrapHostTasks(),_0x3bc5e9=registerControllers(_0x3bc5e9,VomeConfig);const _0x8f3ec4=VomeConfig[_0x3c4428(0x1b8)]?.['port']??0xbb9;return _0x3bc5e9['listen'](_0x8f3ec4),app=_0x3bc5e9,started=!![],printStartupBanner(),registerShutdownSignals(),app;}async function stop(){const _0x583f49=_0x558e8f;if(!app)return;for(const _0x29fdda of shutdownHooks)await _0x29fdda();await shutdownHostTasks(),await shutdownHostInfra(),await app[_0x583f49(0x264)](),app=undefined,started=![],hostScanned=![],resetIoc(),resetPinoLogger(),setCrudRegistrar(undefined),signalsRegistered=![];}function registerShutdownSignals(){const _0x573e29=_0x558e8f;if(signalsRegistered)return;signalsRegistered=!![];for(const _0x43fba7 of[_0x573e29(0x27b),'SIGTERM']){process['once'](_0x43fba7,async()=>{await stop(),process['exit'](0x0);});}}var App={'bootstrap':bootstrap,'shutdown':shutdown,'use':use,'start':start,'stop':stop};async function vome(_0x76de19){const _0x10d1ac=_0x558e8f;if(_0x76de19)await _0x76de19({'App':App});return App[_0x10d1ac(0x30e)]();}import{getTableColumns as _0x13cef2,getTableName as _0x260df5}from'drizzle-orm';import{getTableColumns as _0x30e34a,getTableName}from'drizzle-orm';import{integer,serial,timestamp}from'drizzle-orm/pg-core';var baseColumns={'id':serial('id')[_0x558e8f(0x2b6)](),'createTime':timestamp(_0x558e8f(0x259),{'withTimezone':!![]})['notNull']()[_0x558e8f(0x251)](),'updateTime':timestamp(_0x558e8f(0x2ba),{'withTimezone':!![]})[_0x558e8f(0x2b3)]()['defaultNow']()['$onUpdate'](()=>new Date()),'deletedAt':timestamp('deletedAt',{'withTimezone':!![]}),'tenantId':integer(_0x558e8f(0x18a))},BASE_COLUMN_COMMENTS={'id':'ID','createTime':_0x558e8f(0x1d4),'updateTime':_0x558e8f(0x304),'deletedAt':_0x558e8f(0x2d6),'tenantId':'\u79DF\u6237'},registry=new WeakMap(),tables=new Set();function columnComments(_0x59e9f3,_0x3cf889={}){const _0x492426=_0x558e8f;return tables['add'](_0x59e9f3),registry[_0x492426(0x2f7)](_0x59e9f3,{...BASE_COLUMN_COMMENTS,...registry[_0x492426(0x248)](_0x59e9f3)||{},..._0x3cf889}),_0x59e9f3;}function getColumnComments(_0x56cedd){const _0x38df23=_0x558e8f;return registry[_0x38df23(0x248)](_0x56cedd)||{};}function listColumnCommentTables(){return[...tables];}function quoteIdent(_0x2f0261){const _0x45dfeb=_0x558e8f;if(!/^[A-Za-z_][A-Za-z0-9_]*$/[_0x45dfeb(0x274)](_0x2f0261))throw new Error(_0x45dfeb(0x240)+_0x2f0261);return'\x22'+_0x2f0261+'\x22';}function escapeLiteral(_0x54e214){const _0x546ad2=_0x558e8f;return _0x54e214[_0x546ad2(0x326)](/'/g,'\x27\x27');}async function syncColumnCommentsToPg(_0x2443bc){const _0x5ec8b2=_0x558e8f,_0x1c3104=listColumnCommentTables();if(!_0x1c3104[_0x5ec8b2(0x293)])return 0x0;const _0x503919=new Map(),_0x7810f8=[];for(const _0x5d2340 of _0x1c3104){let _0x380fe7;try{_0x380fe7=getTableName(_0x5d2340);}catch{continue;}const _0x36b86f=_0x30e34a(_0x5d2340),_0x407939=getColumnComments(_0x5d2340),_0x50bf50=new Map();for(const [_0x3c9cac,_0xca9ce0]of Object[_0x5ec8b2(0x2e7)](_0x407939)){if(!_0xca9ce0||!(_0x3c9cac in _0x36b86f))continue;_0x50bf50[_0x5ec8b2(0x2f7)](_0x3c9cac,_0xca9ce0);}if(!_0x50bf50[_0x5ec8b2(0x1d5)])continue;_0x503919['set'](_0x380fe7,_0x50bf50),_0x7810f8[_0x5ec8b2(0x2d0)](_0x380fe7);}if(!_0x7810f8[_0x5ec8b2(0x293)])return 0x0;const _0x1b5969=_0x7810f8[_0x5ec8b2(0x31e)](_0x510a58=>'\x27'+escapeLiteral(_0x510a58)+'\x27')[_0x5ec8b2(0x245)](','),_0x209056=await _0x2443bc['unsafe']('\x0a\x20\x20\x20\x20SELECT\x0a\x20\x20\x20\x20\x20\x20c.relname\x20AS\x20table_name,\x0a\x20\x20\x20\x20\x20\x20a.attname\x20AS\x20column_name,\x0a\x20\x20\x20\x20\x20\x20col_description(a.attrelid,\x20a.attnum)\x20AS\x20comment\x0a\x20\x20\x20\x20FROM\x20pg_catalog.pg_class\x20c\x0a\x20\x20\x20\x20JOIN\x20pg_catalog.pg_namespace\x20n\x20ON\x20n.oid\x20=\x20c.relnamespace\x0a\x20\x20\x20\x20JOIN\x20pg_catalog.pg_attribute\x20a\x20ON\x20a.attrelid\x20=\x20c.oid\x0a\x20\x20\x20\x20WHERE\x20c.relkind\x20=\x20\x27r\x27\x0a\x20\x20\x20\x20\x20\x20AND\x20n.nspname\x20=\x20current_schema()\x0a\x20\x20\x20\x20\x20\x20AND\x20a.attnum\x20>\x200\x0a\x20\x20\x20\x20\x20\x20AND\x20NOT\x20a.attisdropped\x0a\x20\x20\x20\x20\x20\x20AND\x20c.relname\x20IN\x20('+_0x1b5969+_0x5ec8b2(0x28f)),_0x523c5c=new Map();for(const _0x4307cd of _0x209056||[]){if(!_0x4307cd[_0x5ec8b2(0x17f)]||!_0x4307cd[_0x5ec8b2(0x1cf)])continue;_0x523c5c['set'](_0x4307cd['table_name']+'.'+_0x4307cd[_0x5ec8b2(0x1cf)],_0x4307cd[_0x5ec8b2(0x317)]??null);}let _0x84c25d=0x0;for(const [_0x3e65a9,_0x27948e]of _0x503919){for(const [_0x23c532,_0x44150f]of _0x27948e){const _0x54a4f9=_0x3e65a9+'.'+_0x23c532,_0x18887f=_0x523c5c[_0x5ec8b2(0x248)](_0x54a4f9);if(_0x18887f===_0x44150f)continue;await _0x2443bc[_0x5ec8b2(0x18c)](_0x5ec8b2(0x282)+quoteIdent(_0x3e65a9)+'.'+quoteIdent(_0x23c532)+'\x20IS\x20\x27'+escapeLiteral(_0x44150f)+'\x27'),_0x84c25d++;}}return _0x84c25d;}var SIDE_PREFIX2={'admin':'/admin','app':_0x558e8f(0x18e)};function getSidePrefix2(_0x107c7b){return normalizePrefix(SIDE_PREFIX2[_0x107c7b]);}function lastSegment(_0x419731){const _0x439914=_0x558e8f,_0x4f15c0=_0x419731[_0x439914(0x326)](/^\/+|\/+$/g,'')['split']('/');return _0x4f15c0[_0x4f15c0['length']-0x1]||_0x419731||_0x439914(0x2c6);}function toPascalEntityName(_0x34522c){const _0x3cf778=_0x558e8f;return _0x34522c['split']('_')[_0x3cf778(0x1a7)](Boolean)['map'](_0x34ffde=>_0x34ffde[_0x3cf778(0x18f)](0x0)[_0x3cf778(0x206)]()+_0x34ffde['slice'](0x1))['join']('')+_0x3cf778(0x30c);}function withAlias(_0x9069d4){const _0x489aef=_0x558e8f;if(!_0x9069d4?.[_0x489aef(0x293)])return[];return _0x9069d4[_0x489aef(0x31e)](_0x17f358=>{const _0x3de207=_0x489aef;if(typeof _0x17f358!==_0x3de207(0x222)){const _0x4a14de=_0x17f358[_0x3de207(0x1d1)];return{..._0x17f358,'column':_0x4a14de[_0x3de207(0x339)]('.')?_0x4a14de:'a.'+_0x4a14de};}return _0x17f358['includes']('.')?_0x17f358:'a.'+_0x17f358;});}function normalizePageQueryOp(_0x34d51f){const _0x3c2357=_0x558e8f;return{'keyWordLikeFields':withAlias(_0x34d51f?.['keyWordLikeFields']),'fieldEq':withAlias(_0x34d51f?.['fieldEq']),'fieldLike':withAlias(_0x34d51f?.[_0x3c2357(0x225)]),'fieldArray':withAlias(_0x34d51f?.['fieldArray']),'fieldRange':(_0x34d51f?.['fieldRange']??[])[_0x3c2357(0x31e)](_0x415f5a=>({..._0x415f5a,'column':_0x415f5a['column'][_0x3c2357(0x339)]('.')?_0x415f5a['column']:'a.'+_0x415f5a[_0x3c2357(0x1d1)]}))};}function applyFieldDictToColumns(_0xb21d62,_0x1e402b){const _0x1626c5=_0x558e8f;for(const _0x498ae3 of _0x1e402b){if(typeof _0x498ae3===_0x1626c5(0x222)||!_0x498ae3[_0x1626c5(0x1f6)])continue;const _0x251aa8=_0x498ae3[_0x1626c5(0x1d1)][_0x1626c5(0x339)]('.')?_0x498ae3['column'][_0x1626c5(0x2fa)]('.')[_0x1626c5(0x2d9)]():_0x498ae3[_0x1626c5(0x1d1)],_0x56e78f=_0xb21d62[_0x1626c5(0x1b3)](_0x80eb6d=>_0x80eb6d[_0x1626c5(0x25a)]===_0x251aa8);if(_0x56e78f)_0x56e78f[_0x1626c5(0x1f6)]=_0x498ae3['dict'];}}function columnsFromEntity(_0x14edc9){const _0x1b7dba=_0x558e8f;if(!_0x14edc9||typeof _0x14edc9!==_0x1b7dba(0x1b1))return[];try{const _0xb967e3=_0x13cef2(_0x14edc9),_0xcbe9ed=getColumnComments(_0x14edc9),_0x331bac=[];for(const [_0x796b13,_0x5d697e]of Object[_0x1b7dba(0x2e7)](_0xb967e3)){if(_0x796b13===_0x1b7dba(0x18a))continue;const _0x402103=_0x5d697e;_0x331bac['push']({'propertyName':_0x796b13,'type':String(_0x402103[_0x1b7dba(0x16a)]??_0x402103[_0x1b7dba(0x2de)]??_0x1b7dba(0x222)),'length':_0x402103['length']!=null?String(_0x402103[_0x1b7dba(0x293)]):undefined,'nullable':_0x402103[_0x1b7dba(0x2b3)]!==!![],'source':'a.'+_0x796b13,'comment':_0xcbe9ed[_0x796b13]});}const _0x27d828=new Set(['createTime',_0x1b7dba(0x2ba),_0x1b7dba(0x254)]),_0x5ce057=_0x331bac['filter'](_0x18c83e=>!_0x27d828[_0x1b7dba(0x2fc)](_0x18c83e['propertyName'])),_0x54d949=_0x331bac[_0x1b7dba(0x1a7)](_0x55dd9e=>_0x27d828[_0x1b7dba(0x2fc)](_0x55dd9e[_0x1b7dba(0x25a)]));return[..._0x5ce057,..._0x54d949];}catch{return[];}}function entityNameOf(_0x3b0486){const _0x50d957=_0x558e8f;if(!_0x3b0486||typeof _0x3b0486!==_0x50d957(0x1b1))return;try{return toPascalEntityName(_0x260df5(_0x3b0486));}catch{return;}}function buildApis(_0x49ad1a,_0x3befe5){const _0x1f4e2b=_0x558e8f,_0x561837=[],_0x3ef341=new Set(),_0x3a01f2=_0x448036=>{const _0x212289=_0x16aa,_0x519ce7=_0x448036['method']+':'+_0x448036[_0x212289(0x215)];if(_0x3ef341[_0x212289(0x2fc)](_0x519ce7))return;_0x3ef341[_0x212289(0x29f)](_0x519ce7),_0x561837[_0x212289(0x2d0)](_0x448036);};for(const _0x328312 of _0x49ad1a[_0x1f4e2b(0x169)]){const _0x27ef76=getRouteSubPath(_0x328312['path'],_0x49ad1a['prefix']),_0x28fe6c=_0x27ef76[_0x1f4e2b(0x2f2)]('/')?_0x27ef76:'/'+_0x27ef76,_0x3905fb=actionFromSubPath(_0x28fe6c);_0x3a01f2({'method':_0x328312[_0x1f4e2b(0x31b)][_0x1f4e2b(0x1c3)](),'path':_0x28fe6c,'summary':_0x328312[_0x1f4e2b(0x311)]??'','dts':{},'tag':'','prefix':_0x3befe5,'ignoreToken':Boolean(_0x328312[_0x1f4e2b(0x2bf)]),'ignorePerms':Boolean(_0x328312[_0x1f4e2b(0x22b)]),'perms':effectivePerms(_0x328312,_0x49ad1a,_0x3905fb)??[]});}for(const _0x3a6832 of _0x49ad1a[_0x1f4e2b(0x295)]?.[_0x1f4e2b(0x2c1)]??[]){const _0x3dc008='/'+_0x3a6832;_0x3a01f2({'method':_0x3a6832===_0x1f4e2b(0x239)?'get':_0x1f4e2b(0x1c8),'path':_0x3dc008,'summary':CRUD_SUMMARY[_0x3a6832]??_0x3a6832,'dts':{},'tag':'','prefix':_0x3befe5,'ignoreToken':![],'ignorePerms':![],'perms':effectivePerms({},_0x49ad1a,_0x3a6832)??[]});}for(const _0x56230d of _0x49ad1a[_0x1f4e2b(0x295)]?.[_0x1f4e2b(0x209)]??[]){const _0x147df9='/'+_0x56230d;_0x3a01f2({'method':'post','path':_0x147df9,'summary':_0x56230d,'dts':{},'tag':'','prefix':_0x3befe5,'ignoreToken':![],'ignorePerms':![],'perms':effectivePerms({},_0x49ad1a,_0x56230d)??[]});}return _0x561837;}function buildEntity(_0x29889b){const _0x4bb532=_0x558e8f,_0x574531=joinPrefix(getSidePrefix2(_0x29889b[_0x4bb532(0x261)]),_0x29889b['prefix']),_0x5b7c50=lastSegment(_0x29889b[_0x4bb532(0x24d)]),_0x526447=_0x29889b[_0x4bb532(0x295)]?.['entity'],_0xdb30b3=columnsFromEntity(_0x526447),_0x5bab97=normalizePageQueryOp(_0x29889b[_0x4bb532(0x295)]?.[_0x4bb532(0x2a4)]);return applyFieldDictToColumns(_0xdb30b3,_0x5bab97[_0x4bb532(0x2dd)]),{'module':_0x29889b[_0x4bb532(0x29d)],'side':_0x29889b[_0x4bb532(0x261)],'prefix':_0x574531,'name':entityNameOf(_0x526447),'info':{'type':{'name':_0x5b7c50,'description':_0x29889b[_0x4bb532(0x32b)]??_0x5b7c50}},'api':buildApis(_0x29889b,_0x574531),'columns':_0xdb30b3,'pageQueryOp':_0x5bab97,'pageColumns':_0xdb30b3};}function groupByModule(_0x49c002){const _0x26fb19=_0x558e8f,_0x412773={};for(const _0x271fd5 of _0x49c002){const _0x104618=_0x412773[_0x271fd5[_0x26fb19(0x29d)]]??[];_0x104618[_0x26fb19(0x2d0)](_0x271fd5),_0x412773[_0x271fd5[_0x26fb19(0x29d)]]=_0x104618;}return _0x412773;}function isEpsEnabled(){const _0x838e12=_0x558e8f;return Boolean(VomeConfig[_0x838e12(0x189)]?.[_0x838e12(0x1f1)]);}function buildEps(_0x40c5ee){const _0x479717=_0x558e8f;if(!isEpsEnabled())return{};return groupByModule(listControllers(_0x40c5ee)[_0x479717(0x31e)](buildEntity));}var Eps={'controllers':listControllers,'admin':()=>buildEps(_0x558e8f(0x2a7)),'app':()=>buildEps(_0x558e8f(0x1da)),'enabled':isEpsEnabled};import'reflect-metadata';var ROUTES_PENDING_KEY=_0x558e8f(0x19f);function joinRoute(_0x180af3,_0x2d2aa8){return joinPrefix(_0x180af3,_0x2d2aa8==='/'?'':_0x2d2aa8);}function asMiddlewareList(_0x19b2f7){const _0x47c5e6=_0x558e8f;if(_0x19b2f7==null)return;return Array[_0x47c5e6(0x2dc)](_0x19b2f7)?_0x19b2f7:[_0x19b2f7];}function appendPendingRoute(_0xb0ecb1,_0x55f56e){const _0x3dc681=_0x558e8f,_0x541100=Reflect['getMetadata'](ROUTES_PENDING_KEY,_0xb0ecb1)??[];_0x541100[_0x3dc681(0x2d0)](_0x55f56e),Reflect[_0x3dc681(0x266)](ROUTES_PENDING_KEY,_0x541100,_0xb0ecb1);}function createParamDecorator(_0x30bc79){const _0x2aaf91=_0x558e8f,_0x4bcb38=_0x30bc79===_0x2aaf91(0x199)?_0x2aaf91(0x202):_0x30bc79===_0x2aaf91(0x30a)?'Body':_0x2aaf91(0x17d);return _0x2605c2=>(_0x1c036d,_0x290b0e,_0x4786aa)=>{const _0x229c75=_0x2aaf91;if(_0x290b0e===undefined)throw new Error(_0x229c75(0x24f)+_0x4bcb38+'\x20只能用于方法参数');const _0x59e674=_0x1c036d[_0x229c75(0x1f0)];appendRouteParam(_0x59e674,String(_0x290b0e),{'index':_0x4786aa,'source':_0x30bc79,'schema':_0x2605c2});};}function pickCrudOptions(_0x2813fc){const {api:_0x41c6a6,entity:_0x15d171,service:_0x30ade3,serviceApis:_0x5972b9,before:_0xcfb66a,pageQueryOp:_0x3d4479,listQueryOp:_0x440198,insertParam:_0x1ae59e,infoIgnoreProperty:_0x3efafc}=_0x2813fc;if(_0x41c6a6==null&&_0x15d171==null&&_0x30ade3==null&&_0x5972b9==null&&_0xcfb66a==null&&_0x3d4479==null&&_0x440198==null&&_0x1ae59e==null&&_0x3efafc==null)return;return{'api':_0x41c6a6,'entity':_0x15d171,'service':_0x30ade3,'serviceApis':_0x5972b9,'before':_0xcfb66a,'pageQueryOp':_0x3d4479,'listQueryOp':_0x440198,'insertParam':_0x1ae59e,'infoIgnoreProperty':_0x3efafc};}function Controller(_0x225d4f=''){const _0x402a3b=typeof _0x225d4f==='string',_0x13c463=_0x402a3b?{'prefix':_0x225d4f}:_0x225d4f;return _0x2e44fa=>{const _0x466188=_0x16aa;registerProvider({'token':_0x2e44fa,'useClass':_0x2e44fa,'scope':'singleton'});const _0x4657ff=getControllerScanContext(),_0x4c32a0=_0x402a3b&&_0x225d4f===''||!_0x402a3b&&(_0x13c463[_0x466188(0x24d)]==null||_0x13c463['prefix']===''),_0x30b834=normalizePrefix(_0x4c32a0&&_0x4657ff?.[_0x466188(0x16e)]?parseControllerAutoPrefix(_0x4657ff[_0x466188(0x16e)]):_0x13c463['prefix']??''),_0x57e0a0=Reflect[_0x466188(0x2db)](ROUTES_PENDING_KEY,_0x2e44fa)??[],_0x20afef=pickCrudOptions(_0x13c463);registerController({'token':_0x2e44fa,'prefix':_0x30b834,'module':_0x13c463[_0x466188(0x29d)]??_0x4657ff?.[_0x466188(0x29d)]??_0x466188(0x1e0),'side':_0x13c463[_0x466188(0x261)]??_0x4657ff?.[_0x466188(0x261)]??'admin','description':_0x13c463[_0x466188(0x32b)],'file':_0x4657ff?.[_0x466188(0x16e)],'middleware':asMiddlewareList(_0x13c463[_0x466188(0x2e0)]),'crud':_0x20afef,'routes':_0x57e0a0[_0x466188(0x31e)](_0x3afece=>{const _0x3d59d8=_0x466188,_0x45ac32=getRouteParams(_0x2e44fa,_0x3afece[_0x3d59d8(0x2aa)]),_0x26982d=schemaFromParams(_0x45ac32),_0x3cd11c=[..._0x3afece[_0x3d59d8(0x2e0)]??[],...getRouteMiddleware(_0x2e44fa,_0x3afece['handler'])];return{..._0x3afece,'path':joinRoute(_0x30b834,_0x3afece[_0x3d59d8(0x215)][_0x3d59d8(0x2f2)]('/')?_0x3afece[_0x3d59d8(0x215)][_0x3d59d8(0x331)](0x1):_0x3afece[_0x3d59d8(0x215)]),'params':_0x45ac32,'body':_0x26982d?.[_0x3d59d8(0x30a)],'query':_0x26982d?.[_0x3d59d8(0x192)],'routeParams':_0x26982d?.[_0x3d59d8(0x199)],'public':isRoutePublic(_0x2e44fa,_0x3afece[_0x3d59d8(0x2aa)]),'ignorePerms':isRouteIgnorePerms(_0x2e44fa,_0x3afece[_0x3d59d8(0x2aa)]),'perms':getRoutePerms(_0x2e44fa,_0x3afece['handler']),'middleware':_0x3cd11c['length']?_0x3cd11c:undefined};})}),Reflect[_0x466188(0x336)](ROUTES_PENDING_KEY,_0x2e44fa),clearRouteParams(_0x2e44fa),clearRoutePublic(_0x2e44fa),clearRouteMiddleware(_0x2e44fa),clearRoutePerms(_0x2e44fa),clearRouteIgnorePerms(_0x2e44fa);};}function Use(..._0x38f983){return(_0x75a06d,_0x357736)=>{const _0x9e538c=_0x16aa,_0x4c4563=_0x75a06d[_0x9e538c(0x1f0)];appendRouteMiddleware(_0x4c4563,String(_0x357736),_0x38f983);};}function createMethodDecorator(_0x59923d){return(_0x41ec65='',_0x2017d6)=>(_0x1f7e54,_0x4d1390)=>{const _0x46195c=_0x16aa,_0x57dfb1=_0x1f7e54[_0x46195c(0x1f0)];appendPendingRoute(_0x57dfb1,{'method':_0x59923d,'path':_0x41ec65,'handler':String(_0x4d1390),'summary':_0x2017d6?.[_0x46195c(0x311)]});};}function Public(){return(_0x43cd84,_0x551383)=>{const _0x19e6de=_0x43cd84['constructor'];markRoutePublic(_0x19e6de,String(_0x551383));};}function Perms(..._0x298b26){return(_0x44509d,_0x53e8ce)=>{const _0x5e75a0=_0x44509d['constructor'];setRoutePerms(_0x5e75a0,String(_0x53e8ce),_0x298b26);};}function IgnorePerms(){return(_0x4dfb89,_0x3f0ce3)=>{const _0xc05977=_0x4dfb89['constructor'];markRouteIgnorePerms(_0xc05977,String(_0x3f0ce3));};}var Body=createParamDecorator('body'),Query=createParamDecorator(_0x558e8f(0x192)),Param=createParamDecorator('params'),Get=createMethodDecorator(_0x558e8f(0x2c2)),Post=createMethodDecorator(_0x558e8f(0x23e)),Put=createMethodDecorator('PUT'),Delete=createMethodDecorator(_0x558e8f(0x195)),Patch=createMethodDecorator(_0x558e8f(0x187));class BasePlugin{[_0x558e8f(0x2a9)];[_0x558e8f(0x2d1)];[_0x558e8f(0x22c)];[_0x558e8f(0x203)];async[_0x558e8f(0x323)](_0x592a58,_0x30a6a2,_0x2d9824,_0x54b3df){const _0x5cc941=_0x558e8f;this[_0x5cc941(0x2a9)]=_0x592a58,this[_0x5cc941(0x2d1)]=_0x30a6a2,this[_0x5cc941(0x22c)]=_0x54b3df?.[_0x5cc941(0x22c)],this['pluginService']=_0x54b3df?.[_0x5cc941(0x203)],await this['ready']();}async[_0x558e8f(0x17b)](){}}import{existsSync,readFileSync}from'fs';import{createRequire}from'module';import{join as _0x1206b0}from'path';import{createHash}from'crypto';import{homedir}from'os';import{join as _0x280a7d}from'path';function pDataPath(){const _0x32989d=_0x558e8f,_0x489393=createHash(_0x32989d(0x1aa))[_0x32989d(0x175)](String(VomeConfig['keys']??'vome'))[_0x32989d(0x2ec)]('hex');return _0x280a7d(homedir(),'.vome',_0x489393);}function pPluginPath(){const _0x2c09b6=_0x558e8f;return _0x280a7d(pDataPath(),_0x2c09b6(0x1f9));}function pModulesPath(){const _0xc5e6c8=_0x558e8f;return _0x280a7d(pDataPath(),_0xc5e6c8(0x275));}function pModulePath(_0x22e812){return _0x280a7d(pModulesPath(),_0x22e812);}var hostRequire=createRequire(import.meta.url);function pluginRequire(_0x508544){if(_0x508544==='vome-plugin-runtime')return{'BasePlugin':BasePlugin};return hostRequire(_0x508544);}function loadPluginClass(_0x1af934){const _0x2e25dc=_0x558e8f;try{const _0x4c4d18=_0x1af934[_0x2e25dc(0x326)](/export\s+const\s+Plugin\s*=/g,_0x2e25dc(0x229))['replace'](/export\s+\{[^}]*\bPlugin\b[^}]*\};?/g,'')[_0x2e25dc(0x326)](/export\s+const\s+handlers\s*=/g,_0x2e25dc(0x2be))[_0x2e25dc(0x326)](/export\s+\{[^}]*\bhandlers\b[^}]*\};?/g,'')['replace'](/export\s+class\s+(\w+)/g,'class\x20$1')['replace'](/export\s+default\s+/g,'')[_0x2e25dc(0x326)](/import\s+\{?\s*BasePlugin\s*\}?\s*from\s*['"][^'"]+['"];?/g,'')[_0x2e25dc(0x326)](/import\s+BasePlugin\s+from\s*['"][^'"]+['"];?/g,'')[_0x2e25dc(0x326)](/require\(\s*['"]vome-plugin-runtime['"]\s*\)/g,_0x2e25dc(0x16b)),_0x22f192=new Function('BasePlugin',_0x2e25dc(0x236),_0x2e25dc(0x29d),'exports',_0x4c4d18+_0x2e25dc(0x17e)),_0x2c3257={'exports':{}};return _0x22f192(BasePlugin,pluginRequire,_0x2c3257,_0x2c3257['exports']);}catch(_0x249ccb){throw new Error('[Plugin]\x20加载失败:\x20'+(_0x249ccb instanceof Error?_0x249ccb['message']:String(_0x249ccb)));}}function readPluginScript(_0x5e58dc){const _0x5ef29f=_0x558e8f,_0x575236=_0x1206b0(pModulePath(_0x5e58dc),'server',_0x5ef29f(0x298));if(existsSync(_0x575236))return readFileSync(_0x575236,_0x5ef29f(0x1be));const _0x4239ae=_0x1206b0(pPluginPath(),_0x5e58dc);if(!existsSync(_0x4239ae))return;try{const _0x4d0a96=JSON[_0x5ef29f(0x25c)](readFileSync(_0x4239ae,_0x5ef29f(0x1be)));return _0x4d0a96[_0x5ef29f(0x1a3)]?.['data'];}catch{return;}}import{existsSync as _0x1276a6,readFileSync as _0x26c62a,readdirSync as _0x32576f,statSync}from'fs';import{createRequire as _0x5bb22d}from'module';import{join as _0x128071}from'path';var registry2=new Map(),hostRequire2=_0x5bb22d(import.meta.url);function pluginRequire2(_0x3255aa){if(_0x3255aa==='vome-plugin-runtime')return{'BasePlugin':BasePlugin};return hostRequire2(_0x3255aa);}function normalizePath(_0x3af389){const _0x1ad85b=_0x558e8f,_0x14fd24=_0x3af389[_0x1ad85b(0x2f2)]('/')?_0x3af389:'/'+_0x3af389;return _0x14fd24[_0x1ad85b(0x326)](/\/+$/,'')||'/';}function normalizeMethod(_0xadb670){return _0xadb670['toUpperCase']();}function normalizeModuleScript(_0x5e24f5){const _0x246054=_0x558e8f;return _0x5e24f5[_0x246054(0x326)](/export\s+const\s+handlers\s*=/g,_0x246054(0x2be))[_0x246054(0x326)](/export\s+\{[^}]*\bhandlers\b[^}]*\};?/g,'')['replace'](/export\s+default\s+\{/g,'var\x20handlers\x20=\x20{')[_0x246054(0x326)](/export\s+const\s+Plugin\s*=/g,_0x246054(0x229))[_0x246054(0x326)](/export\s+\{[^}]*\bPlugin\b[^}]*\};?/g,'')[_0x246054(0x326)](/export\s+class\s+(\w+)/g,'class\x20$1')[_0x246054(0x326)](/import\s+\{?\s*BasePlugin\s*\}?\s*from\s*['"][^'"]+['"];?/g,'')[_0x246054(0x326)](/import\s+BasePlugin\s+from\s*['"][^'"]+['"];?/g,'')['replace'](/require\(\s*['"]vome-plugin-runtime['"]\s*\)/g,_0x246054(0x16b));}function loadModuleHandlers(_0x2fce7f,_0x13f0dd=!![]){const _0x1b562e=_0x558e8f,_0x5326d9=normalizeModuleScript(_0x2fce7f),_0x2751aa=new Function(_0x1b562e(0x312),'require',_0x1b562e(0x29d),_0x1b562e(0x22d),_0x5326d9+_0x1b562e(0x1b0)),_0x459928={'exports':{}},_0x56e929=_0x2751aa(BasePlugin,pluginRequire2,_0x459928,_0x459928['exports']);if(!_0x56e929||typeof _0x56e929!==_0x1b562e(0x1b1)){if(_0x13f0dd)throw new Error('missing\x20export\x20handlers');return{};}return _0x56e929;}var ModuleRegistry={'get'(_0x4e070f){const _0xd6a33=_0x558e8f;return registry2[_0xd6a33(0x248)](_0x4e070f);},'list'(){const _0xfd8269=_0x558e8f;return[...registry2[_0xfd8269(0x2e7)]()]['map'](([_0x7eff7,_0x474e00])=>({'key':_0x7eff7,'manifest':_0x474e00[_0xfd8269(0x2ef)],'routes':_0x474e00[_0xfd8269(0x169)]}));},'load'(_0x59dd5b){const _0x3e9ddd=_0x558e8f;if(!_0x59dd5b||!/^[a-zA-Z0-9_-]+$/[_0x3e9ddd(0x274)](_0x59dd5b))throw new Error(_0x3e9ddd(0x283)+_0x59dd5b);const _0x59eea4=pModulePath(_0x59dd5b),_0x5b9369=_0x128071(_0x59eea4,_0x3e9ddd(0x1d2));if(!_0x1276a6(_0x5b9369))throw new Error(_0x3e9ddd(0x2e2)+_0x59dd5b);const _0x5cf07b=JSON[_0x3e9ddd(0x25c)](_0x26c62a(_0x5b9369,'utf8')),_0x547c5a=(_0x5cf07b[_0x3e9ddd(0x169)]??[])[_0x3e9ddd(0x31e)](_0x1c411f=>({..._0x1c411f,'method':normalizeMethod(_0x1c411f[_0x3e9ddd(0x31b)]),'path':normalizePath(_0x1c411f['path'])}));let _0x459456={};const _0x2938a8=_0x128071(_0x59eea4,'server','index.js');if(_0x1276a6(_0x2938a8)){const _0x1dcbd6=_0x26c62a(_0x2938a8,_0x3e9ddd(0x1be));_0x459456=loadModuleHandlers(_0x1dcbd6,_0x547c5a[_0x3e9ddd(0x293)]>0x0);for(const _0x3ba61f of _0x547c5a){if(typeof _0x459456[_0x3ba61f['handler']]!=='function')throw new Error(_0x3e9ddd(0x290)+_0x59dd5b+_0x3e9ddd(0x1c2)+_0x3ba61f[_0x3e9ddd(0x2aa)]);}}else{if(_0x547c5a[_0x3e9ddd(0x293)])throw new Error(_0x3e9ddd(0x290)+_0x59dd5b+_0x3e9ddd(0x2c0));}return registry2[_0x3e9ddd(0x2f7)](_0x59dd5b,{'manifest':_0x5cf07b,'handlers':_0x459456,'routes':_0x547c5a}),registry2['get'](_0x59dd5b);},'unload'(_0xd331c5){const _0x53982b=_0x558e8f;registry2[_0x53982b(0x296)](_0xd331c5);},async 'dispatch'(_0x2bd871,_0x2da34d,_0x471035,_0x2dbc98){const _0x229c3d=_0x558e8f,_0x4fe2d4=registry2['get'](_0x2bd871);if(!_0x4fe2d4)return{'ok':![],'status':0x194,'message':_0x229c3d(0x1d6)};const _0x1eb2b8=normalizeMethod(_0x2da34d),_0xbb5a75=normalizePath(_0x471035),_0x351762=_0x4fe2d4[_0x229c3d(0x169)]['find'](_0x27b5da=>_0x27b5da[_0x229c3d(0x31b)]===_0x1eb2b8&&_0x27b5da[_0x229c3d(0x215)]===_0xbb5a75);if(!_0x351762)return{'ok':![],'status':0x194,'message':_0x229c3d(0x325)};const _0x385223=_0x4fe2d4[_0x229c3d(0x1c5)][_0x351762['handler']];if(typeof _0x385223!==_0x229c3d(0x20b))return{'ok':![],'status':0x1f4,'message':_0x229c3d(0x309)+_0x351762[_0x229c3d(0x2aa)]};try{const _0x4484b8=await _0x385223(_0x2dbc98);return{'ok':!![],'data':_0x4484b8,'route':_0x351762};}catch(_0x213465){const _0x447401=_0x213465 instanceof Error?_0x213465[_0x229c3d(0x250)]:String(_0x213465);return{'ok':![],'status':0x1f4,'message':_0x447401,'route':_0x351762};}},'bootstrap'(){const _0x2ea691=_0x558e8f,_0x19038f=pModulesPath();if(!_0x1276a6(_0x19038f))return;for(const _0x354df7 of _0x32576f(_0x19038f)){const _0xa9603a=_0x128071(_0x19038f,_0x354df7);if(!statSync(_0xa9603a)[_0x2ea691(0x24a)]())continue;if(!_0x1276a6(_0x128071(_0xa9603a,_0x2ea691(0x1d2))))continue;try{this[_0x2ea691(0x2c9)](_0x354df7),console[_0x2ea691(0x21a)](_0x2ea691(0x287)+_0x354df7);}catch(_0x51b898){console['warn'](_0x2ea691(0x25e)+_0x354df7+':',_0x51b898 instanceof Error?_0x51b898[_0x2ea691(0x250)]:_0x51b898);}}}};import{existsSync as _0x3aaa6d,statSync as _0x49cdf9}from'fs';import{join as _0x18f349,normalize,sep}from'path';import{Elysia as _0x480f20}from'elysia';var PREFIX='/vome/apps';function contentType(_0x2dd9ef){const _0x13ba31=_0x558e8f,_0xe2ddc0=_0x2dd9ef[_0x13ba31(0x1c3)]();if(_0xe2ddc0['endsWith']('.html'))return _0x13ba31(0x27f);if(_0xe2ddc0['endsWith'](_0x13ba31(0x272))||_0xe2ddc0[_0x13ba31(0x308)](_0x13ba31(0x1e2)))return'application/javascript;\x20charset=utf-8';if(_0xe2ddc0[_0x13ba31(0x308)]('.css'))return _0x13ba31(0x30b);if(_0xe2ddc0['endsWith'](_0x13ba31(0x177)))return'application/json;\x20charset=utf-8';if(_0xe2ddc0[_0x13ba31(0x308)](_0x13ba31(0x2bb)))return'image/svg+xml';if(_0xe2ddc0[_0x13ba31(0x308)]('.png'))return _0x13ba31(0x1bc);if(_0xe2ddc0[_0x13ba31(0x308)]('.jpg')||_0xe2ddc0['endsWith'](_0x13ba31(0x180)))return'image/jpeg';if(_0xe2ddc0[_0x13ba31(0x308)]('.woff2'))return'font/woff2';if(_0xe2ddc0['endsWith'](_0x13ba31(0x2f9)))return _0x13ba31(0x1dc);if(_0xe2ddc0[_0x13ba31(0x308)]('.map'))return _0x13ba31(0x1f7);return _0x13ba31(0x20f);}var microApps=new _0x480f20({'name':_0x558e8f(0x2e6)})[_0x558e8f(0x248)](PREFIX+'/*',({params:_0x35c592,set:_0x5f6d6e})=>{const _0x30812f=_0x558e8f,_0x22bd2b=String(_0x35c592['*']||''),_0x312591=_0x22bd2b[_0x30812f(0x2fa)]('/')[_0x30812f(0x1a7)](Boolean);if(!_0x312591[_0x30812f(0x293)])return _0x5f6d6e['status']=0x194,_0x30812f(0x1ea);const _0x382506=_0x312591[0x0];if(!/^[a-zA-Z0-9_-]+$/['test'](_0x382506))return _0x5f6d6e[_0x30812f(0x21d)]=0x190,_0x30812f(0x330);const _0x25eeb6=_0x18f349(pModulePath(_0x382506),_0x30812f(0x21c));if(!_0x3aaa6d(_0x25eeb6)||!_0x49cdf9(_0x25eeb6)[_0x30812f(0x24a)]())return _0x5f6d6e[_0x30812f(0x21d)]=0x194,_0x30812f(0x2cb);let _0x370d83=_0x312591['slice'](0x1)[_0x30812f(0x245)]('/')||'index.html';if(_0x370d83[_0x30812f(0x308)]('/'))_0x370d83+=_0x30812f(0x252);const _0xb53655=normalize(_0x18f349(_0x25eeb6,_0x370d83));if(!_0xb53655[_0x30812f(0x2f2)](_0x25eeb6+sep)&&_0xb53655!==_0x25eeb6)return _0x5f6d6e[_0x30812f(0x21d)]=0x193,_0x30812f(0x32d);let _0x535202=_0xb53655;_0x3aaa6d(_0x535202)&&_0x49cdf9(_0x535202)[_0x30812f(0x24a)]()&&(_0x535202=_0x18f349(_0x535202,'index.html'));if(!_0x3aaa6d(_0x535202)||!_0x49cdf9(_0x535202)[_0x30812f(0x1a0)]())return _0x5f6d6e[_0x30812f(0x21d)]=0x194,'Not\x20Found';return _0x5f6d6e['headers'][_0x30812f(0x228)]=contentType(_0x535202),_0x5f6d6e['headers'][_0x30812f(0x212)]=_0x30812f(0x334),_0x5f6d6e[_0x30812f(0x292)][_0x30812f(0x337)]='*',Bun[_0x30812f(0x16e)](_0x535202);});import{Elysia as _0x60e384}from'elysia';function ok(_0x1bd16){const _0x90e1e9=_0x558e8f;return{'code':RES_CODE[_0x90e1e9(0x2eb)],'message':_0x90e1e9(0x1ca),'data':_0x1bd16??null};}function fail(_0x130e04,_0x4355bb=RES_CODE['ERROR']){return{'code':_0x4355bb,'message':_0x130e04};}async function handleExt(_0x17ece1){const _0x1025ae=_0x558e8f,_0x2a20e4=_0x17ece1[_0x1025ae(0x199)]['key'];if(!_0x2a20e4||!/^[a-zA-Z0-9_-]+$/[_0x1025ae(0x274)](_0x2a20e4))return _0x17ece1[_0x1025ae(0x2f7)][_0x1025ae(0x21d)]=0x190,fail('\u975E\u6CD5\u6A21\u5757\x20key');const _0x5e3aad=String(_0x17ece1[_0x1025ae(0x199)]['*']||''),_0x1a1e53=('/'+_0x5e3aad)[_0x1025ae(0x326)](/\/+/g,'/'),_0x130fd5=Context['get'](),_0x514e8c=ModuleRegistry[_0x1025ae(0x248)](_0x2a20e4);if(!_0x514e8c)return _0x17ece1[_0x1025ae(0x2f7)][_0x1025ae(0x21d)]=0x194,fail('\u6A21\u5757\u672A\u5B89\u88C5\u6216\u672A\u52A0\u8F7D');const _0x43625b=_0x17ece1[_0x1025ae(0x26b)][_0x1025ae(0x31b)][_0x1025ae(0x206)](),_0x3dec57=_0x1a1e53[_0x1025ae(0x326)](/\/+$/,'')||'/',_0x48651c=_0x514e8c[_0x1025ae(0x169)][_0x1025ae(0x1b3)](_0x3f1abc=>_0x3f1abc[_0x1025ae(0x31b)]===_0x43625b&&_0x3f1abc[_0x1025ae(0x215)]===_0x3dec57);if(!_0x48651c)return _0x17ece1[_0x1025ae(0x2f7)][_0x1025ae(0x21d)]=0x194,fail('\u8DEF\u7531\u4E0D\u5B58\u5728');if(_0x48651c[_0x1025ae(0x26c)]&&!_0x130fd5?.[_0x1025ae(0x23c)]){const _0x322a46=_0x130fd5?.[_0x1025ae(0x26c)]??[];if(!_0x322a46[_0x1025ae(0x339)](_0x48651c[_0x1025ae(0x26c)]))return _0x17ece1['status'](0x193);}const _0x4fad3c=await ModuleRegistry[_0x1025ae(0x306)](_0x2a20e4,_0x43625b,_0x1a1e53,{'body':_0x17ece1[_0x1025ae(0x30a)],'query':_0x17ece1[_0x1025ae(0x192)]??{},'params':_0x17ece1[_0x1025ae(0x199)],'headers':_0x17ece1[_0x1025ae(0x26b)]['headers'],'adminId':_0x130fd5?.[_0x1025ae(0x182)]});if(!_0x4fad3c['ok'])return _0x17ece1[_0x1025ae(0x2f7)]['status']=_0x4fad3c[_0x1025ae(0x21d)],fail(_0x4fad3c[_0x1025ae(0x250)]);return ok(_0x4fad3c[_0x1025ae(0x179)]);}function createModuleGateway(_0x5a475b){const _0x1c692d=_0x558e8f;return new _0x60e384({'name':_0x1c692d(0x284)})[_0x1c692d(0x19d)](_0x5a475b[_0x1c692d(0x24c)])[_0x1c692d(0x241)]('/admin/ext/:key/*',handleExt,{'adminAuth':!![]})[_0x1c692d(0x241)](_0x1c692d(0x2d3),handleExt,{'adminAuth':!![]});}import{Elysia as _0x2e5d1d}from'elysia';function defineAuthMacro(_0x2fe55d,_0x5eb6fe){const _0x1d0ef9=_0x558e8f;return new _0x2e5d1d({'name':_0x2fe55d+_0x1d0ef9(0x1fd)})['macro']({[_0x2fe55d]:{'resolve':_0x5eb6fe}})['as']('scoped');}var package_default={'name':_0x558e8f(0x185),'version':_0x558e8f(0x26e),'description':_0x558e8f(0x24e),'license':'MIT','type':_0x558e8f(0x29d),'files':[_0x558e8f(0x333),_0x558e8f(0x28c),_0x558e8f(0x20c)],'main':_0x558e8f(0x217),'types':_0x558e8f(0x2c3),'exports':{'.':{'types':_0x558e8f(0x2c3),'import':_0x558e8f(0x217),'default':'./dist/index.js'},'./server':{'types':_0x558e8f(0x1f3),'import':_0x558e8f(0x1a6),'default':_0x558e8f(0x1a6)},'./admin':{'types':_0x558e8f(0x26f),'import':_0x558e8f(0x226),'default':_0x558e8f(0x226)},'./admin/*':'./dist/admin/*','./admin/styles/base.css':_0x558e8f(0x24b),'./typings/*':_0x558e8f(0x201)},'scripts':{'build:server':_0x558e8f(0x2d8),'build:admin':'bun\x20scripts/build-admin.ts','build':_0x558e8f(0x184),'obfuscate':_0x558e8f(0x2bc),'build:obfuscate':'bun\x20run\x20build\x20&&\x20bun\x20run\x20obfuscate','prepublishOnly':_0x558e8f(0x170)},'peerDependencies':{'elysia':'>=1.0.0','reflect-metadata':_0x558e8f(0x2b9),'drizzle-orm':_0x558e8f(0x165),'drizzle-zod':'>=0.5.0','vue':_0x558e8f(0x28d),'vue-router':_0x558e8f(0x1a9),'pinia':_0x558e8f(0x305),'vue-sonner':_0x558e8f(0x305),'@vueuse/core':'>=10.0.0','clsx':_0x558e8f(0x305),'tailwind-merge':_0x558e8f(0x305),'dompurify':_0x558e8f(0x2b8),'marked':_0x558e8f(0x20d)},'peerDependenciesMeta':{'drizzle-orm':{'optional':!![]},'drizzle-zod':{'optional':!![]},'vue':{'optional':!![]},'vue-router':{'optional':!![]},'pinia':{'optional':!![]},'vue-sonner':{'optional':!![]},'@vueuse/core':{'optional':!![]},'clsx':{'optional':!![]},'tailwind-merge':{'optional':!![]},'dompurify':{'optional':!![]},'marked':{'optional':!![]}},'devDependencies':{'bun-types':_0x558e8f(0x19b),'drizzle-orm':_0x558e8f(0x19b),'drizzle-zod':_0x558e8f(0x2ed),'elysia':_0x558e8f(0x19b),'javascript-obfuscator':_0x558e8f(0x30d),'reflect-metadata':_0x558e8f(0x291),'typescript':_0x558e8f(0x19b)},'dependencies':{'@bogeychan/elysia-logger':_0x558e8f(0x2bd),'@elysiajs/openapi':'^1.4.15','pino':_0x558e8f(0x2f8),'pino-pretty':'^13.1.3'}},version=package_default[_0x558e8f(0x1f2)];export{vome,version,tableHasDepartmentId,syncColumnCommentsToPg,scanFiles,resolveTenantScope,resolveDataScope,readPluginScript,q,pPluginPath,pModulesPath,pModulePath,pDataPath,normalizeHost,noTenant,noDataScope,microApps,loadPluginClass,loadModuleHandlers,listProviders,listControllers,isTenantEnabled,isEpsEnabled,isCommException,getRepository,getEnv,getColumnComments,entitySchemas,defineAuthMacro,createModuleGateway,columnComments,baseColumns,attachCrudRoutes,applyRowScopes,applyDataScopeWhere,appendInjectMeta,VomeConfig,Use,ScopeEnum,Repository,RES_CODE,Query,Put,Public,Provide,Post,Perms,Patch,Param,ModuleRegistry,Logger,Ioc,InjectRepository,Inject,IgnorePerms,Get,Eps,Delete,DbStore,Controller,Context,CommException,Body,BaseService,BasePlugin,BaseController,BASE_COLUMN_COMMENTS,App};
|