@_tc/template-core 0.2.0 → 0.2.1-bate.1
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/AGENT_README.md +5 -2
- package/README.md +76 -31
- package/cjs/app/controller/project.js +1 -1
- package/cjs/app/controller/view.js +1 -1
- package/cjs/app/extends/db.js +4 -4
- package/cjs/app/middleware.js +1 -1
- package/cjs/app/middlewares/error-handle.js +1 -1
- package/cjs/app/middlewares/project-handler.js +1 -1
- package/cjs/app/utils/i18n.js +1 -0
- package/cjs/app/view/entry.tpl +1 -0
- package/cjs/config/config.default.js +1 -1
- package/cjs/packages/common/i18n/default.js +1 -1
- package/cjs/packages/common/i18n/en-US.js +1 -1
- package/cjs/packages/common/index.js +1 -1
- package/esm/app/controller/project.js +12 -11
- package/esm/app/controller/view.js +2 -1
- package/esm/app/extends/db.js +64 -60
- package/esm/app/middleware.js +1 -1
- package/esm/app/middlewares/error-handle.js +16 -15
- package/esm/app/middlewares/project-handler.js +8 -7
- package/esm/app/utils/i18n.js +36 -0
- package/esm/app/view/entry.tpl +1 -0
- package/esm/config/config.default.js +2 -1
- package/esm/packages/common/i18n/default.js +13 -0
- package/esm/packages/common/i18n/en-US.js +13 -0
- package/esm/packages/common/index.js +9 -9
- package/fe/frontend/apps/dash/Dashboard.js +6 -4
- package/fe/frontend/apps/dash/dash.entry.js +2 -0
- package/fe/frontend/src/common/generateMenuData.d.ts +4 -1
- package/fe/frontend/src/common/generateMenuData.js +3 -3
- package/fe/frontend/src/common/language.d.ts +1 -2
- package/fe/frontend/src/common/language.js +10 -10
- package/fe/frontend/src/common/request.js +3 -1
- package/fe/frontend/src/components/AsyncSelect/AsyncSelect.js +10 -2
- package/fe/frontend/src/components/BasePage/HeaderView.js +2 -2
- package/fe/frontend/src/components/LanguageSwitch/LanguageSwitch.js +13 -9
- package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.js +4 -3
- package/fe/frontend/src/defaultPages/NotFoundPage/index.js +4 -3
- package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/DetailPanel.js +14 -9
- package/fe/frontend/src/defaultPages/SchemaPage/components/CallCom/PopFrom.js +8 -7
- package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaSearch/index.js +6 -12
- package/fe/frontend/src/defaultPages/SchemaPage/components/SchemaTable/index.js +25 -18
- package/fe/frontend/src/defaultPages/SchemaPage/index.js +5 -3
- package/fe/frontend/src/defaultPages/SidebarSlotPageTmp.js +4 -2
- package/fe/frontend/src/hooks/useText.d.ts +3 -0
- package/fe/frontend/src/hooks/useText.js +14 -0
- package/fe/frontend/src/index.d.ts +1 -0
- package/fe/frontend/src/index.js +3 -2
- package/fe/frontend/src/language/index.d.ts +0 -2
- package/fe/frontend/src/language/index.js +1 -7
- package/fe/frontend/src/language/resources.d.ts +2 -0
- package/fe/frontend/src/language/resources.js +9 -0
- package/fe/packages/common/i18n/default.d.ts +15 -0
- package/fe/packages/common/i18n/default.js +16 -0
- package/fe/packages/common/i18n/en-US.d.ts +15 -0
- package/fe/packages/common/i18n/en-US.js +18 -2
- package/fe/packages/common/i18n/index.js +13 -0
- package/fe/packages/common/i18n/locales.js +7 -0
- package/fe/packages/react/ui/components/Date/Calendar.js +9 -5
- package/fe/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
- package/fe/packages/react/ui/components/Date/LocaleContext.js +28 -3
- package/fe/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
- package/fe/packages/react/ui/components/Date/LocaleProvider.js +7 -16
- package/fe/packages/react/ui/components/Date/index.js +2 -2
- package/fe/packages/react/ui/components/Date/locales.d.ts +2 -0
- package/fe/packages/react/ui/components/Date/locales.js +29 -13
- package/fe/packages/react/ui/components/TableSearch/TableSearch.js +21 -1
- package/fe/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
- package/fe/packages/react/ui/components/TableSearch/lang.js +18 -7
- package/model/frontend/src/common/language.d.ts +1 -2
- package/model/frontend/src/hooks/useText.d.ts +3 -0
- package/model/frontend/src/language/index.d.ts +0 -2
- package/model/frontend/src/language/resources.d.ts +2 -0
- package/model/packages/common/i18n/default.d.ts +15 -0
- package/model/packages/common/i18n/en-US.d.ts +15 -0
- package/model/packages/react/ui/components/Date/LocaleContext.d.ts +22 -1
- package/model/packages/react/ui/components/Date/LocaleProvider.d.ts +1 -1
- package/model/packages/react/ui/components/Date/locales.d.ts +2 -0
- package/model/packages/react/ui/components/TableSearch/lang.d.ts +2 -0
- package/package.json +1 -1
- package/types/app/utils/i18n.d.ts +12 -0
- package/types/config/config.default.d.ts +6 -0
- package/types/packages/common/i18n/default.d.ts +19 -0
- package/types/packages/common/i18n/en-US.d.ts +21 -2
- package/types/packages/common/i18n/index.d.ts +21 -0
- package/types/packages/common/i18n/locales.d.ts +10 -0
- package/types/packages/common/i18n/types.d.ts +40 -0
package/esm/app/extends/db.js
CHANGED
|
@@ -1,141 +1,145 @@
|
|
|
1
1
|
import { __require as e } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { createI18nError as t } from "../utils/i18n.js";
|
|
3
|
+
import { mkdirSync as n } from "node:fs";
|
|
4
|
+
import { dirname as r, isAbsolute as i, resolve as a } from "node:path";
|
|
4
5
|
//#region app/extends/db.ts
|
|
5
|
-
var
|
|
6
|
-
function
|
|
7
|
-
let
|
|
8
|
-
dbPath:
|
|
6
|
+
var o = "framework", s = ".template-core/template-core.sqlite";
|
|
7
|
+
function c(e) {
|
|
8
|
+
let t = d(e), i, a = !1, o = 0, s = () => (S(a), i || (n(r(t), { recursive: !0 }), i = l(t), u(i)), i), c = {
|
|
9
|
+
dbPath: t,
|
|
9
10
|
getDBConnection: s,
|
|
10
11
|
execDB: (e) => {
|
|
11
12
|
s().exec(e);
|
|
12
13
|
},
|
|
13
14
|
runDB: (e, t) => {
|
|
14
|
-
let n = s().prepare(e).run(...
|
|
15
|
+
let n = s().prepare(e).run(...m(t));
|
|
15
16
|
return {
|
|
16
17
|
changes: Number(n.changes ?? 0),
|
|
17
18
|
lastInsertRowid: n.lastInsertRowid ?? 0
|
|
18
19
|
};
|
|
19
20
|
},
|
|
20
|
-
queryDB: (e, t) => s().prepare(e).all(...
|
|
21
|
-
getDBFirst: (e, t) => s().prepare(e).get(...
|
|
21
|
+
queryDB: (e, t) => s().prepare(e).all(...m(t)),
|
|
22
|
+
getDBFirst: (e, t) => s().prepare(e).get(...m(t)),
|
|
22
23
|
transactionDB: (e) => {
|
|
23
24
|
let t = s(), n = `tc_savepoint_${o}`, r = o === 0;
|
|
24
25
|
t.exec(r ? "BEGIN IMMEDIATE" : `SAVEPOINT ${n}`), o += 1;
|
|
25
26
|
try {
|
|
26
|
-
let i = e(
|
|
27
|
+
let i = e(c);
|
|
27
28
|
return --o, t.exec(r ? "COMMIT" : `RELEASE SAVEPOINT ${n}`), i;
|
|
28
29
|
} catch (e) {
|
|
29
30
|
throw --o, t.exec(r ? "ROLLBACK" : `ROLLBACK TO SAVEPOINT ${n}`), r || t.exec(`RELEASE SAVEPOINT ${n}`), e;
|
|
30
31
|
}
|
|
31
32
|
},
|
|
32
|
-
getDBData: (e, t) =>
|
|
33
|
+
getDBData: (e, t) => c.getDBDataRecord(e, t)?.value,
|
|
33
34
|
getDBDataRecord: (e, t) => {
|
|
34
|
-
let n =
|
|
35
|
-
return n ?
|
|
35
|
+
let n = c.getDBFirst("SELECT namespace, data_key, data_value, created_at, updated_at FROM tc_framework_data WHERE namespace = ? AND data_key = ? LIMIT 1", [h(t?.namespace), g(e)]);
|
|
36
|
+
return n ? x(n) : void 0;
|
|
36
37
|
},
|
|
37
38
|
setDBData: (e, t, n) => {
|
|
38
39
|
let r = (/* @__PURE__ */ new Date()).toISOString();
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return c.runDB("INSERT INTO tc_framework_data (namespace, data_key, data_value, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(namespace, data_key) DO UPDATE SET\n data_value = excluded.data_value,\n updated_at = excluded.updated_at", [
|
|
41
|
+
h(n?.namespace),
|
|
42
|
+
g(e),
|
|
43
|
+
y(t),
|
|
43
44
|
r,
|
|
44
45
|
r
|
|
45
46
|
]);
|
|
46
47
|
},
|
|
47
|
-
hasDBData: (e, t) => !!
|
|
48
|
-
deleteDBData: (e, t) =>
|
|
48
|
+
hasDBData: (e, t) => !!c.getDBFirst("SELECT 1 AS exists_value FROM tc_framework_data WHERE namespace = ? AND data_key = ? LIMIT 1", [h(t?.namespace), g(e)]),
|
|
49
|
+
deleteDBData: (e, t) => c.runDB("DELETE FROM tc_framework_data WHERE namespace = ? AND data_key = ?", [h(t?.namespace), g(e)]).changes > 0,
|
|
49
50
|
listDBData: (e) => {
|
|
50
|
-
let t =
|
|
51
|
-
return
|
|
52
|
-
|
|
51
|
+
let t = _(e?.limit), n = v(e?.offset);
|
|
52
|
+
return c.queryDB("SELECT namespace, data_key, data_value, created_at, updated_at\n FROM tc_framework_data\n WHERE namespace = ?\n ORDER BY updated_at DESC, data_key ASC\n LIMIT ? OFFSET ?", [
|
|
53
|
+
h(e?.namespace),
|
|
53
54
|
t,
|
|
54
55
|
n
|
|
55
|
-
]).map((e) =>
|
|
56
|
+
]).map((e) => x(e));
|
|
56
57
|
},
|
|
57
58
|
countDBData: (e) => {
|
|
58
|
-
let t =
|
|
59
|
+
let t = c.getDBFirst("SELECT COUNT(1) AS count_value FROM tc_framework_data WHERE namespace = ?", [h(e?.namespace)]);
|
|
59
60
|
return Number(t?.count_value ?? 0);
|
|
60
61
|
},
|
|
61
|
-
clearDBData: (e) =>
|
|
62
|
+
clearDBData: (e) => c.runDB("DELETE FROM tc_framework_data WHERE namespace = ?", [h(e?.namespace)]).changes,
|
|
62
63
|
closeDB: () => {
|
|
63
64
|
a ||= (i?.close(), !0);
|
|
64
65
|
}
|
|
65
66
|
};
|
|
66
|
-
return
|
|
67
|
+
return c;
|
|
67
68
|
}
|
|
68
|
-
function
|
|
69
|
-
let
|
|
69
|
+
function l(n) {
|
|
70
|
+
let r = "node:sqlite", i;
|
|
70
71
|
try {
|
|
71
|
-
|
|
72
|
+
i = e(r);
|
|
72
73
|
} catch (e) {
|
|
73
|
-
throw
|
|
74
|
+
throw t("server.errors.dbNodeSqliteUnavailable", {
|
|
75
|
+
sqliteSpecifier: r,
|
|
76
|
+
cause: C(e)
|
|
77
|
+
});
|
|
74
78
|
}
|
|
75
|
-
if (!
|
|
76
|
-
return new
|
|
77
|
-
}
|
|
78
|
-
function l(e) {
|
|
79
|
-
e.exec("\n CREATE TABLE IF NOT EXISTS tc_framework_data (\n namespace TEXT NOT NULL,\n data_key TEXT NOT NULL,\n data_value TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (namespace, data_key)\n );\n CREATE INDEX IF NOT EXISTS idx_tc_framework_data_namespace_updated_at\n ON tc_framework_data (namespace, updated_at);\n ");
|
|
79
|
+
if (!i.DatabaseSync) throw t("server.errors.dbDatabaseSyncUnavailable", { sqliteSpecifier: r });
|
|
80
|
+
return new i.DatabaseSync(n);
|
|
80
81
|
}
|
|
81
82
|
function u(e) {
|
|
82
|
-
|
|
83
|
-
return n ? r(n) ? n : i(e.baseDir, n) : i(e.baseDir, o);
|
|
83
|
+
e.exec("\n CREATE TABLE IF NOT EXISTS tc_framework_data (\n namespace TEXT NOT NULL,\n data_key TEXT NOT NULL,\n data_value TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (namespace, data_key)\n );\n CREATE INDEX IF NOT EXISTS idx_tc_framework_data_namespace_updated_at\n ON tc_framework_data (namespace, updated_at);\n ");
|
|
84
84
|
}
|
|
85
85
|
function d(e) {
|
|
86
|
+
let t = f(e), n = typeof t == "string" ? t : t?.path ?? t?.filename ?? t?.sqlitePath ?? p(t?.sqlite);
|
|
87
|
+
return n ? i(n) ? n : a(e.baseDir, n) : a(e.baseDir, s);
|
|
88
|
+
}
|
|
89
|
+
function f(e) {
|
|
86
90
|
let t = e.config;
|
|
87
91
|
return t.db ?? (t.sqlite ? { sqlite: t.sqlite } : void 0);
|
|
88
92
|
}
|
|
89
|
-
function
|
|
93
|
+
function p(e) {
|
|
90
94
|
if (e) return typeof e == "string" ? e : e.path ?? e.filename;
|
|
91
95
|
}
|
|
92
|
-
function
|
|
96
|
+
function m(e) {
|
|
93
97
|
return e ? Array.isArray(e) ? e : [e] : [];
|
|
94
98
|
}
|
|
95
|
-
function
|
|
96
|
-
let
|
|
97
|
-
if (!
|
|
98
|
-
return
|
|
99
|
+
function h(e = o) {
|
|
100
|
+
let n = e.trim();
|
|
101
|
+
if (!n) throw t("server.errors.dbNamespaceRequired");
|
|
102
|
+
return n;
|
|
99
103
|
}
|
|
100
|
-
function
|
|
101
|
-
let
|
|
102
|
-
if (!
|
|
103
|
-
return
|
|
104
|
+
function g(e) {
|
|
105
|
+
let n = e.trim();
|
|
106
|
+
if (!n) throw t("server.errors.dbKeyRequired");
|
|
107
|
+
return n;
|
|
104
108
|
}
|
|
105
|
-
function
|
|
106
|
-
if (!Number.isSafeInteger(e) || e <= 0) throw
|
|
109
|
+
function _(e = 100) {
|
|
110
|
+
if (!Number.isSafeInteger(e) || e <= 0) throw t("server.errors.dbLimitInvalid");
|
|
107
111
|
return e;
|
|
108
112
|
}
|
|
109
|
-
function
|
|
110
|
-
if (!Number.isSafeInteger(e) || e < 0) throw
|
|
113
|
+
function v(e = 0) {
|
|
114
|
+
if (!Number.isSafeInteger(e) || e < 0) throw t("server.errors.dbOffsetInvalid");
|
|
111
115
|
return e;
|
|
112
116
|
}
|
|
113
|
-
function
|
|
117
|
+
function y(e) {
|
|
114
118
|
try {
|
|
115
119
|
let t = JSON.stringify(e);
|
|
116
120
|
if (t === void 0) throw Error("value is not JSON serializable");
|
|
117
121
|
return t;
|
|
118
122
|
} catch (e) {
|
|
119
|
-
throw
|
|
123
|
+
throw t("server.errors.dbValueNotSerializable", { cause: C(e) });
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
|
-
function
|
|
126
|
+
function b(e) {
|
|
123
127
|
return JSON.parse(e);
|
|
124
128
|
}
|
|
125
|
-
function
|
|
129
|
+
function x(e) {
|
|
126
130
|
return {
|
|
127
131
|
key: e.data_key,
|
|
128
|
-
value:
|
|
132
|
+
value: b(e.data_value),
|
|
129
133
|
namespace: e.namespace,
|
|
130
134
|
createdAt: e.created_at,
|
|
131
135
|
updatedAt: e.updated_at
|
|
132
136
|
};
|
|
133
137
|
}
|
|
134
|
-
function x(e) {
|
|
135
|
-
if (e) throw Error("[db] SQLite 数据库连接已关闭");
|
|
136
|
-
}
|
|
137
138
|
function S(e) {
|
|
139
|
+
if (e) throw t("server.errors.dbClosed");
|
|
140
|
+
}
|
|
141
|
+
function C(e) {
|
|
138
142
|
return e instanceof Error && e.message ? ` Cause: ${e.message}` : "";
|
|
139
143
|
}
|
|
140
144
|
//#endregion
|
|
141
|
-
export {
|
|
145
|
+
export { c as default };
|
package/esm/app/middleware.js
CHANGED
|
@@ -15,7 +15,7 @@ var r = t({
|
|
|
15
15
|
setHeaders(e) {
|
|
16
16
|
e.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate"), e.setHeader("Pragma", "no-cache"), e.setHeader("Expires", "0");
|
|
17
17
|
}
|
|
18
|
-
} : { maxage:
|
|
18
|
+
} : { maxage: t.config.resourceCacheTimeMs ?? 300 * 1e3 };
|
|
19
19
|
t.use(t.middlewares.errorHandle), t.use(e({ threshold: 2048 })), t.publicsPath.forEach((e) => t.use(n(e, i))), t.use(r), t.use(t.middlewares.requestParameterParsing), t.use(t.middlewares.projectHandler), !t.envs.isLocal() && t.use(t.middlewares.apiSignVerify), t.use(t.middlewares.apiParamsVerify);
|
|
20
20
|
};
|
|
21
21
|
//#endregion
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
import { getRequestErrorMessage as e, requestT as t } from "../utils/i18n.js";
|
|
1
2
|
//#region app/middlewares/error-handle.ts
|
|
2
|
-
var
|
|
3
|
+
var n = {}, r = (r) => async (i, a) => {
|
|
3
4
|
try {
|
|
4
|
-
await
|
|
5
|
-
} catch (
|
|
6
|
-
let { status:
|
|
7
|
-
if (
|
|
8
|
-
let
|
|
9
|
-
if (e
|
|
10
|
-
|
|
5
|
+
await a();
|
|
6
|
+
} catch (a) {
|
|
7
|
+
let o = a, { status: s = 200, message: c, detail: l, code: u = 5e4, returnError: d } = o, f = e(i, o, c);
|
|
8
|
+
if (r.extends.logger?.info(`error info -> ${JSON.stringify(a)}`), r.extends.logger?.error("-- [excption] --", a), r.extends.logger?.error("-- [excption] info --", s, c, l), c?.includes("template not found")) {
|
|
9
|
+
let e = i.path ?? i.req.url ?? i.url;
|
|
10
|
+
if (n[e] === void 0 ? n[e] = 0 : n[e] += 1, n[e] < r.config.notFoundRedirectCount) {
|
|
11
|
+
i.status = 302, i.redirect(r.options?.homePage ?? "/");
|
|
11
12
|
return;
|
|
12
|
-
} else e
|
|
13
|
+
} else n[e] = 0;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
code:
|
|
16
|
-
message:
|
|
17
|
-
}) : (
|
|
15
|
+
d ? (i.status = s, i.body = {
|
|
16
|
+
code: u,
|
|
17
|
+
message: f
|
|
18
|
+
}) : (i.status = 200, i.body = {
|
|
18
19
|
code: 5e4,
|
|
19
|
-
message: "
|
|
20
|
+
message: t(i, "server.errors.network")
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
//#endregion
|
|
24
|
-
export {
|
|
25
|
+
export { r as default };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { requestT as e } from "../utils/i18n.js";
|
|
1
2
|
//#region app/middlewares/project-handler.ts
|
|
2
|
-
var
|
|
3
|
-
let
|
|
4
|
-
if (
|
|
5
|
-
|
|
3
|
+
var t = (t) => async (n, r) => {
|
|
4
|
+
let i = n.headers.projk, { path: a } = n;
|
|
5
|
+
if (a.indexOf(`${t.options.apiPrefix}/proj/`) !== -1 && (!i || ["undefined", "null"].includes(i))) {
|
|
6
|
+
n.status = 200, n.body = {
|
|
6
7
|
code: 110,
|
|
7
8
|
data: null,
|
|
8
|
-
message: "
|
|
9
|
+
message: e(n, "server.errors.invalidRequest")
|
|
9
10
|
};
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
n.extInfo = { key: i }, await r();
|
|
13
14
|
};
|
|
14
15
|
//#endregion
|
|
15
|
-
export {
|
|
16
|
+
export { t as default };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { i18n as e, i18nStore as t } from "../../packages/common/i18n/index.js";
|
|
2
|
+
//#region app/utils/i18n.ts
|
|
3
|
+
var n = "x-tc-language", r = "en-US", i = [
|
|
4
|
+
n,
|
|
5
|
+
"tc_language",
|
|
6
|
+
"tc-language",
|
|
7
|
+
"language",
|
|
8
|
+
"lang",
|
|
9
|
+
"locale"
|
|
10
|
+
], a = (e) => Array.isArray(e) ? e[0] : e, o = (e, t) => a(e[t.toLowerCase()]), s = (e) => e ? e.split(",").map((e) => e.trim().split(";")[0]?.trim()).filter((e) => !!e) : [], c = (e) => {
|
|
11
|
+
if (!e) return r;
|
|
12
|
+
let n = Object.keys(t.getState().resources), i = e.trim().toLowerCase(), a = n.find((e) => e.toLowerCase() === i);
|
|
13
|
+
if (a) return a;
|
|
14
|
+
let o = i.split("-")[0];
|
|
15
|
+
return n.find((e) => e.toLowerCase().split("-")[0] === o) ?? r;
|
|
16
|
+
}, l = (e) => {
|
|
17
|
+
for (let t of i) {
|
|
18
|
+
let n = o(e.headers, t);
|
|
19
|
+
if (n) return c(n);
|
|
20
|
+
}
|
|
21
|
+
let t = s(o(e.headers, "accept-language"));
|
|
22
|
+
for (let e of t) {
|
|
23
|
+
let t = c(e);
|
|
24
|
+
if (t) return t;
|
|
25
|
+
}
|
|
26
|
+
return r;
|
|
27
|
+
}, u = (t, n, i, a) => e(n, i, {
|
|
28
|
+
...a,
|
|
29
|
+
language: a?.language ?? l(t),
|
|
30
|
+
fallbackLanguage: a?.fallbackLanguage ?? r
|
|
31
|
+
}), d = (e, t, n) => {
|
|
32
|
+
let r = Error(n ?? e);
|
|
33
|
+
return r.i18nKey = e, r.i18nData = t, r;
|
|
34
|
+
}, f = (e, t, n) => t.i18nKey ? u(e, t.i18nKey, t.i18nData, { fallback: n ?? t.message }) : n ?? t.message;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { n as LANGUAGE_HEADER_KEY, d as createI18nError, f as getRequestErrorMessage, l as getRequestLanguage, c as normalizeI18nLanguage, u as requestT };
|
package/esm/app/view/entry.tpl
CHANGED
|
@@ -8,6 +8,19 @@ var e = {
|
|
|
8
8
|
submit: "提交",
|
|
9
9
|
reset: "重置"
|
|
10
10
|
},
|
|
11
|
+
server: { errors: {
|
|
12
|
+
network: "网络错误",
|
|
13
|
+
invalidRequest: "请求不合法",
|
|
14
|
+
getProjectFailed: "获取项目异常",
|
|
15
|
+
dbNodeSqliteUnavailable: "[db] 默认数据库依赖 Node.js 内置 {sqliteSpecifier},当前运行环境不可用。请升级 Node.js,或在业务项目覆盖 app/extends/db.ts。{cause}",
|
|
16
|
+
dbDatabaseSyncUnavailable: "[db] {sqliteSpecifier} 未提供 DatabaseSync,无法初始化默认 SQLite 数据库。",
|
|
17
|
+
dbNamespaceRequired: "[db] namespace 不能为空",
|
|
18
|
+
dbKeyRequired: "[db] key 不能为空",
|
|
19
|
+
dbLimitInvalid: "[db] limit 必须是大于 0 的整数",
|
|
20
|
+
dbOffsetInvalid: "[db] offset 必须是大于等于 0 的整数",
|
|
21
|
+
dbValueNotSerializable: "[db] value 必须可以被 JSON.stringify 序列化。{cause}",
|
|
22
|
+
dbClosed: "[db] SQLite 数据库连接已关闭"
|
|
23
|
+
} },
|
|
11
24
|
components: {
|
|
12
25
|
breadcrumb: { close: "关闭" },
|
|
13
26
|
confirmDialog: {
|
|
@@ -8,6 +8,19 @@ var e = {
|
|
|
8
8
|
submit: "Submit",
|
|
9
9
|
reset: "Reset"
|
|
10
10
|
},
|
|
11
|
+
server: { errors: {
|
|
12
|
+
network: "Network error",
|
|
13
|
+
invalidRequest: "Invalid request",
|
|
14
|
+
getProjectFailed: "Failed to get project",
|
|
15
|
+
dbNodeSqliteUnavailable: "[db] The default database depends on Node.js built-in {sqliteSpecifier}, which is unavailable in the current runtime. Upgrade Node.js or override app/extends/db.ts in the business project.{cause}",
|
|
16
|
+
dbDatabaseSyncUnavailable: "[db] {sqliteSpecifier} does not provide DatabaseSync, so the default SQLite database cannot be initialized.",
|
|
17
|
+
dbNamespaceRequired: "[db] namespace cannot be empty",
|
|
18
|
+
dbKeyRequired: "[db] key cannot be empty",
|
|
19
|
+
dbLimitInvalid: "[db] limit must be an integer greater than 0",
|
|
20
|
+
dbOffsetInvalid: "[db] offset must be an integer greater than or equal to 0",
|
|
21
|
+
dbValueNotSerializable: "[db] value must be serializable by JSON.stringify.{cause}",
|
|
22
|
+
dbClosed: "[db] SQLite database connection is closed"
|
|
23
|
+
} },
|
|
11
24
|
components: {
|
|
12
25
|
breadcrumb: { close: "Close" },
|
|
13
26
|
confirmDialog: {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { defaultLanguageResources as e } from "./i18n/default.js";
|
|
2
|
+
import { defaultEnglishResources as t } from "./i18n/en-US.js";
|
|
3
|
+
import { defaultLanguage as n, languageLocalKey as r, translations as i } from "./i18n/locales.js";
|
|
4
|
+
import { getI18nPathValue as a, getLanguage as o, i18n as s, i18nStore as c, interpolateI18nMessage as l, isPlainI18nDictionary as u, mergeI18nDictionary as d, mergeI18nResources as f, t as p, translate as m } from "./i18n/index.js";
|
|
5
|
+
import { isBoolean as h, isFunction as g, isNil as _, isNonNullable as v, isNumber as y, isPlainObject as b, isString as x } from "./guards/index.js";
|
|
6
|
+
import { chunk as S, compact as C, groupBy as w, toArray as T, uniqueBy as E } from "./array/index.js";
|
|
7
|
+
import { LRUCache as D } from "./cache/LRUCache.js";
|
|
8
|
+
import { FetchAxios as O, axios as k, createInstance as A } from "./http/index.js";
|
|
9
9
|
import { ANSI_RESET as j, ansiColors as M, colorLog as N, colorize as P, joinColorized as F, logColor as I, logColorized as L, logGreen as R, logJoinColorized as z, logPink as B, logRed as V, logWhite as H, logYellow as U } from "./log/index.js";
|
|
10
10
|
import { clamp as W, toFiniteNumber as G } from "./number/index.js";
|
|
11
11
|
import { filterEmpty as K, filtereEmpty as q } from "./object/filterEmpty.js";
|
|
12
12
|
import { mapValues as J, omit as Y, pick as X } from "./object/index.js";
|
|
13
13
|
import { clearRafTimer as Z, rafClearInterval as Q, rafClearTimeout as $, rafSetInterval as ee, rafSetTimeout as te } from "./rafTimer.js";
|
|
14
14
|
import { capitalize as ne, isBlank as re, joinStr as ie, kebabCase as ae } from "./string/index.js";
|
|
15
|
-
export { j as ANSI_RESET,
|
|
15
|
+
export { j as ANSI_RESET, O as FetchAxios, D as LRUCache, M as ansiColors, k as axios, ne as capitalize, S as chunk, W as clamp, Z as clearRafTimer, N as colorLog, P as colorize, C as compact, A as createInstance, t as defaultEnglishResources, n as defaultLanguage, e as defaultLanguageResources, K as filterEmpty, q as filtereEmpty, a as getI18nPathValue, o as getLanguage, w as groupBy, s as i18n, c as i18nStore, l as interpolateI18nMessage, re as isBlank, h as isBoolean, g as isFunction, _ as isNil, v as isNonNullable, y as isNumber, u as isPlainI18nDictionary, b as isPlainObject, x as isString, F as joinColorized, ie as joinStr, ae as kebabCase, r as languageLocalKey, I as logColor, L as logColorized, R as logGreen, z as logJoinColorized, B as logPink, V as logRed, H as logWhite, U as logYellow, J as mapValues, d as mergeI18nDictionary, f as mergeI18nResources, Y as omit, X as pick, Q as rafClearInterval, $ as rafClearTimeout, ee as rafSetInterval, te as rafSetTimeout, p as t, T as toArray, G as toFiniteNumber, m as translate, i as translations, E as uniqueBy };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getAuthToken } from "../../src/common/auth/index.js";
|
|
2
|
-
import { getText } from "../../src/common/language.js";
|
|
3
2
|
import { generateMenuItemData } from "../../src/common/generateMenuData.js";
|
|
4
3
|
import { Menu } from "../../../packages/react/ui/components/Menu/Menu.js";
|
|
5
4
|
import "../../../packages/react/ui/components/index.js";
|
|
6
5
|
import { useModeStore } from "../../src/stores/mode.js";
|
|
7
6
|
import { findMenuItem, leftSidebarBasePath } from "../../src/common/menu.js";
|
|
7
|
+
import { useText } from "../../src/hooks/useText.js";
|
|
8
8
|
import HeaderView from "../../src/components/BasePage/HeaderView.js";
|
|
9
9
|
import useRouterParams from "../../src/hooks/useRouterParams.js";
|
|
10
10
|
import useInit from "../../../packages/react/hooks/useInit.js";
|
|
@@ -83,6 +83,7 @@ var getRenderableHomePage = (projectInfo) => {
|
|
|
83
83
|
var Dashboard = () => {
|
|
84
84
|
const { initModeData, initData, projectInfo } = useModeStore();
|
|
85
85
|
const HeaderUserArea = dashComponents["HeaderView.userArea"];
|
|
86
|
+
const text = useText();
|
|
86
87
|
useInit(() => {
|
|
87
88
|
!initData && initModeData();
|
|
88
89
|
});
|
|
@@ -94,7 +95,7 @@ var Dashboard = () => {
|
|
|
94
95
|
if (initData && projectInfo?.menuLayout === "top") return /* @__PURE__ */ jsx(Menu, {
|
|
95
96
|
className: " w-full",
|
|
96
97
|
mode: "top",
|
|
97
|
-
items: generateMenuItemData(projectInfo.menu),
|
|
98
|
+
items: generateMenuItemData(projectInfo.menu, text),
|
|
98
99
|
selectedKey: SK,
|
|
99
100
|
onSelect: (e) => {
|
|
100
101
|
uSK(e);
|
|
@@ -107,7 +108,8 @@ var Dashboard = () => {
|
|
|
107
108
|
initData,
|
|
108
109
|
projectInfo,
|
|
109
110
|
SK,
|
|
110
|
-
nav
|
|
111
|
+
nav,
|
|
112
|
+
text
|
|
111
113
|
]);
|
|
112
114
|
useEffect(() => {
|
|
113
115
|
if (initData && projectInfo) {
|
|
@@ -165,7 +167,7 @@ var Dashboard = () => {
|
|
|
165
167
|
const getTitle = () => {
|
|
166
168
|
const title = projectInfo?.desc ?? projectInfo?.name;
|
|
167
169
|
if (!isInit.current && title) document.title = projectInfo?.name ?? title;
|
|
168
|
-
return title ?
|
|
170
|
+
return title ? text(title) : void 0;
|
|
169
171
|
};
|
|
170
172
|
return /* @__PURE__ */ jsxs("div", {
|
|
171
173
|
className: "dash-main h-screen flex flex-col overflow-hidden bg-theme-bg text-foreground",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { registerFrontendI18nResources } from "../../src/common/language.js";
|
|
1
2
|
import { QK, leftSidebarBasePath } from "../../src/common/menu.js";
|
|
2
3
|
import Dashboard from "./Dashboard.js";
|
|
3
4
|
import { renderImportComponent } from "../../src/common/importComponent.js";
|
|
@@ -55,6 +56,7 @@ initApp(({ children }) => /* @__PURE__ */ jsx("div", {
|
|
|
55
56
|
}), {
|
|
56
57
|
routes: getDefaultPageRoutes(),
|
|
57
58
|
beforeRender: async (context) => {
|
|
59
|
+
await registerFrontendI18nResources();
|
|
58
60
|
initThemeMode();
|
|
59
61
|
if (typeof initDash === "function") await initDash(context);
|
|
60
62
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { ProjectInfo } from "../api/baseInfo";
|
|
2
2
|
import type { MenuItemData } from "../../../packages/react/ui/components/index";
|
|
3
|
-
|
|
3
|
+
import { getText } from "./language";
|
|
4
|
+
type TextResolver = typeof getText;
|
|
5
|
+
export declare const generateMenuItemData: (data: ProjectInfo["menu"], text?: TextResolver) => MenuItemData[];
|
|
6
|
+
export {};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { getText } from "./language.js";
|
|
2
2
|
//#region frontend/src/common/generateMenuData.ts
|
|
3
|
-
var generateMenuItemData = (data) => {
|
|
3
|
+
var generateMenuItemData = (data, text = getText) => {
|
|
4
4
|
return data.map((m) => {
|
|
5
|
-
const children = m.menuType === "group" && m.subMenu.length ? generateMenuItemData(m.subMenu) : void 0;
|
|
5
|
+
const children = m.menuType === "group" && m.subMenu.length ? generateMenuItemData(m.subMenu, text) : void 0;
|
|
6
6
|
return {
|
|
7
7
|
key: m.key,
|
|
8
|
-
label:
|
|
8
|
+
label: text(m.name),
|
|
9
9
|
icon: m.icon,
|
|
10
10
|
children,
|
|
11
11
|
minWidth: 100
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { I18nAddResourcesOptions, I18nDictionary, I18nInterpolationValues, I18nLanguage, I18nResources, I18nSetResourcesOptions, I18nTranslateOptions } from "../../../packages/react/ui/i18n/index";
|
|
2
2
|
export declare const addLanguageResources: (language: I18nLanguage, messages: I18nDictionary, options?: I18nAddResourcesOptions) => void;
|
|
3
|
-
export declare const addResources: (language: I18nLanguage, messages: I18nDictionary, options?: I18nAddResourcesOptions) => void;
|
|
4
|
-
export declare const addLanguage: (language: I18nLanguage, messages?: I18nDictionary, options?: I18nAddResourcesOptions) => void;
|
|
5
3
|
export declare const setLanguage: (language: I18nLanguage) => void;
|
|
6
4
|
export declare const setFallbackLanguage: (language: I18nLanguage) => void;
|
|
7
5
|
export declare const setResources: (resources: I18nResources, options?: I18nSetResourcesOptions) => void;
|
|
@@ -9,6 +7,7 @@ export declare const getCurrentLanguage: () => string;
|
|
|
9
7
|
export declare const getFallbackLanguage: () => string;
|
|
10
8
|
export declare const getI18nResources: () => Partial<Record<string, I18nDictionary>>;
|
|
11
9
|
export declare const getSupportedLanguages: () => string[];
|
|
10
|
+
export declare const registerFrontendI18nResources: (resources?: I18nResources) => Promise<void>;
|
|
12
11
|
export declare const getText: (key: string, fillingData?: I18nInterpolationValues, options?: I18nTranslateOptions) => string;
|
|
13
12
|
export declare const t: <T = string>(key: string, fillingData?: I18nInterpolationValues, options?: I18nTranslateOptions) => string | T;
|
|
14
13
|
export type { I18nAddResourcesOptions, I18nDictionary, I18nInterpolationValues, I18nLanguage, I18nResources, I18nSetResourcesOptions, I18nTranslateOptions, };
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i18nKeyPrefix } from "../language/index.js";
|
|
2
2
|
import { i18n, i18nStore } from "../../../packages/common/i18n/index.js";
|
|
3
3
|
import "../../../packages/react/ui/i18n/index.js";
|
|
4
4
|
//#region frontend/src/common/language.ts
|
|
5
5
|
var addLanguageResources = (language, messages, options) => {
|
|
6
6
|
i18nStore.getState().addResources(language, messages, options);
|
|
7
7
|
};
|
|
8
|
-
var addResources = addLanguageResources;
|
|
9
|
-
var addLanguage = (language, messages = {}, options) => {
|
|
10
|
-
addLanguageResources(language, messages, options);
|
|
11
|
-
};
|
|
12
8
|
var setLanguage = (language) => {
|
|
13
9
|
i18nStore.getState().setLanguage(language);
|
|
14
10
|
};
|
|
@@ -22,12 +18,16 @@ var getCurrentLanguage = () => i18nStore.getState().language;
|
|
|
22
18
|
var getFallbackLanguage = () => i18nStore.getState().fallbackLanguage;
|
|
23
19
|
var getI18nResources = () => i18nStore.getState().resources;
|
|
24
20
|
var getSupportedLanguages = () => Object.keys(getI18nResources());
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
var registerFrontendI18nResources = async (resources) => {
|
|
22
|
+
const nextResources = resources ?? (await import("../language/resources.js")).frontendI18nResources;
|
|
23
|
+
Object.entries(nextResources).forEach(([language, messages]) => {
|
|
24
|
+
addLanguageResources(language, messages ?? {});
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
27
|
var getText = (key, fillingData, options) => {
|
|
28
|
-
if (key.
|
|
29
|
-
return key;
|
|
28
|
+
if (key.startsWith("$i18n::")) return i18n(key.slice(i18nKeyPrefix.length), fillingData, options);
|
|
29
|
+
return i18n(key, fillingData, options);
|
|
30
30
|
};
|
|
31
31
|
var t = i18n;
|
|
32
32
|
//#endregion
|
|
33
|
-
export {
|
|
33
|
+
export { addLanguageResources, getCurrentLanguage, getFallbackLanguage, getI18nResources, getSupportedLanguages, getText, registerFrontendI18nResources, setFallbackLanguage, setLanguage, setResources, t };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { API_AUTH_HEADER_KEY, AUTH_HEADER_KEY, clearAuthToken, getApiAuth, getAuthToken } from "./auth/index.js";
|
|
2
2
|
import { frontendLangKeys } from "../language/index.js";
|
|
3
|
-
import { getText } from "./language.js";
|
|
3
|
+
import { getCurrentLanguage, getText } from "./language.js";
|
|
4
4
|
import { FreezeState, apiFreezerStore } from "../stores/apiFreezer.js";
|
|
5
5
|
import FetchAxios from "../../../packages/common/http/index.js";
|
|
6
6
|
import md5 from "md5";
|
|
7
7
|
//#region frontend/src/common/request.ts
|
|
8
|
+
var LANGUAGE_HEADER_KEY = "x-tc-language";
|
|
8
9
|
var BASE_URL = "/api";
|
|
9
10
|
var NumberConcurrentCalls = 4;
|
|
10
11
|
var isRequestWhitelisted = (api, params) => {
|
|
@@ -102,6 +103,7 @@ api.interceptors.request.use(async (config) => {
|
|
|
102
103
|
config.headers = {
|
|
103
104
|
"Content-Type": "application/json",
|
|
104
105
|
...config.headers,
|
|
106
|
+
[LANGUAGE_HEADER_KEY]: getCurrentLanguage(),
|
|
105
107
|
s_t: time + "",
|
|
106
108
|
s_sign: md5(`${window["_signKey"]}_${time}`),
|
|
107
109
|
[API_AUTH_HEADER_KEY]: aauto
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Select } from "../../../../packages/react/ui/components/Select/Select.js";
|
|
2
2
|
import "../../../../packages/react/ui/index.js";
|
|
3
3
|
import { request } from "../../common/request.js";
|
|
4
|
+
import { useText } from "../../hooks/useText.js";
|
|
4
5
|
import { handlingRequestErrors } from "../../common/fetchErrorShow.js";
|
|
5
6
|
import useExecuteOnce from "../../../../packages/react/hooks/useExecuteOnce.js";
|
|
6
|
-
import { useState, useTransition } from "react";
|
|
7
|
+
import { useMemo, useState, useTransition } from "react";
|
|
7
8
|
import { jsx } from "react/jsx-runtime";
|
|
8
9
|
//#region frontend/src/components/AsyncSelect/AsyncSelect.tsx
|
|
9
10
|
var AsyncSelect = (props) => {
|
|
10
11
|
const { fetchConfig, ...params } = props;
|
|
12
|
+
const text = useText();
|
|
11
13
|
const [options, setOptions] = useState([]);
|
|
12
14
|
const [loading, setLoading] = useState(false);
|
|
13
15
|
const [lzayLoading, startTranstion] = useTransition();
|
|
@@ -26,9 +28,15 @@ var AsyncSelect = (props) => {
|
|
|
26
28
|
}
|
|
27
29
|
});
|
|
28
30
|
}, { executionPhase: "mount" });
|
|
31
|
+
const options_ = useMemo(() => {
|
|
32
|
+
return options.map((i) => {
|
|
33
|
+
i.label = i.searchText = text(i.searchText);
|
|
34
|
+
return i;
|
|
35
|
+
});
|
|
36
|
+
}, [options, text]);
|
|
29
37
|
return /* @__PURE__ */ jsx(Select, {
|
|
30
38
|
loading: lzayLoading || loading,
|
|
31
|
-
options,
|
|
39
|
+
options: options_,
|
|
32
40
|
...params
|
|
33
41
|
});
|
|
34
42
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { frontendLangKeys } from "../../language/index.js";
|
|
2
|
-
import { getText } from "../../common/language.js";
|
|
3
2
|
import { cn } from "../../../../packages/react/ui/lib/utils.js";
|
|
4
3
|
import "../../../../packages/react/ui/index.js";
|
|
4
|
+
import { useText } from "../../hooks/useText.js";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Boxes } from "lucide-react";
|
|
7
7
|
//#region frontend/src/components/BasePage/HeaderView.tsx
|
|
@@ -14,7 +14,7 @@ var headerThemeStyle = {
|
|
|
14
14
|
var imageLogoPattern = /^(https?:\/\/|data:image\/|\/|\.\/|\.\.\/|.*\.(svg|png|jpe?g|webp|gif)$)/i;
|
|
15
15
|
var HeaderView = (props) => {
|
|
16
16
|
const { icon, title, menu, userArea, children } = props ?? defaultProps;
|
|
17
|
-
const defaultTitle =
|
|
17
|
+
const defaultTitle = useText()(frontendLangKeys.appTitle);
|
|
18
18
|
const brandLogo = icon ? typeof icon === "string" ? imageLogoPattern.test(icon) ? /* @__PURE__ */ jsx("img", {
|
|
19
19
|
className: "h-full max-w-[112px] object-contain",
|
|
20
20
|
src: icon,
|