@nocobase/plugin-localization 2.1.0-alpha.4 → 2.1.0-alpha.40
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/LICENSE +201 -661
- package/README.md +79 -10
- package/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/ai/ai-employees/lina.d.ts +10 -0
- package/dist/ai/ai-employees/lina.js +60 -0
- package/dist/client/300.1f79b801d226f40d.js +10 -0
- package/dist/client/i18n-missing-handler.d.ts +1 -17
- package/dist/client/index.js +1 -1
- package/dist/client-v2/796.0ec484505de4b04a.js +10 -0
- package/dist/client-v2/common/constants.d.ts +13 -0
- package/dist/client-v2/common/i18n-missing-handler.d.ts +23 -0
- package/dist/{client/Localization.d.ts → client-v2/i18n-missing-handler.d.ts} +1 -2
- package/dist/client-v2/index.d.ts +9 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/locale.d.ts +11 -0
- package/dist/client-v2/pages/LocalizationPage.d.ts +11 -0
- package/dist/client-v2/plugin.d.ts +13 -0
- package/dist/externalVersion.js +18 -13
- package/dist/locale/en-US.json +38 -1
- package/dist/locale/zh-CN.json +38 -1
- package/dist/server/actions/aiTranslate.d.ts +14 -0
- package/dist/server/actions/aiTranslate.js +151 -0
- package/dist/server/actions/localization.js +30 -15
- package/dist/server/actions/localizationTexts.js +8 -9
- package/dist/server/migrations/20260511230000-delete-official-plugin-package-resource-modules.d.ts +14 -0
- package/dist/server/migrations/20260511230000-delete-official-plugin-package-resource-modules.js +64 -0
- package/dist/server/plugin.d.ts +5 -2
- package/dist/server/plugin.js +76 -14
- package/dist/server/tasks/localization-ai-translate.d.ts +48 -0
- package/dist/server/tasks/localization-ai-translate.js +606 -0
- package/dist/server/translation-scope.d.ts +31 -0
- package/dist/server/translation-scope.js +107 -0
- package/package.json +8 -3
- package/dist/client/177bd849c95cf6cc.js +0 -10
- package/dist/server/source-manager.d.ts +0 -35
- package/dist/server/source-manager.js +0 -77
package/dist/server/plugin.js
CHANGED
|
@@ -42,17 +42,29 @@ __export(plugin_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(plugin_exports);
|
|
43
43
|
var import_server = require("@nocobase/server");
|
|
44
44
|
var import_localization = __toESM(require("./actions/localization"));
|
|
45
|
+
var import_aiTranslate = __toESM(require("./actions/aiTranslate"));
|
|
45
46
|
var import_localizationTexts = __toESM(require("./actions/localizationTexts"));
|
|
46
47
|
var import_resources = __toESM(require("./resources"));
|
|
47
48
|
var import_utils = require("./utils");
|
|
48
49
|
var import_constants = require("./constants");
|
|
49
|
-
var import_source_manager = require("./source-manager");
|
|
50
50
|
var import_utils2 = require("@nocobase/utils");
|
|
51
|
+
var import_localization_ai_translate = require("./tasks/localization-ai-translate");
|
|
51
52
|
var import_package = __toESM(require("../../package.json"));
|
|
52
53
|
class PluginLocalizationServer extends import_server.Plugin {
|
|
53
54
|
resources;
|
|
54
|
-
|
|
55
|
+
aiTranslateTaskRegistered = false;
|
|
56
|
+
localeSourceTextHookKeys = /* @__PURE__ */ new Set();
|
|
57
|
+
normalizeResourceModule(module2) {
|
|
58
|
+
const prefix = "resources.";
|
|
59
|
+
const namespace = module2.startsWith(prefix) ? module2.slice(prefix.length) : module2;
|
|
60
|
+
const normalizedNamespace = namespace.startsWith(import_server.OFFICIAL_PLUGIN_PREFIX) ? namespace.replace(import_server.OFFICIAL_PLUGIN_PREFIX, "") : namespace;
|
|
61
|
+
return `${prefix}${normalizedNamespace}`;
|
|
62
|
+
}
|
|
55
63
|
addNewTexts = async (texts, options) => {
|
|
64
|
+
texts = texts.map(({ text, module: module2 }) => ({
|
|
65
|
+
text,
|
|
66
|
+
module: this.normalizeResourceModule(module2)
|
|
67
|
+
}));
|
|
56
68
|
texts = await this.resources.filterExists(texts, options == null ? void 0 : options.transaction);
|
|
57
69
|
await this.db.getModel("localizationTexts").bulkCreate(
|
|
58
70
|
texts.map(({ text, module: module2 }) => ({
|
|
@@ -88,23 +100,44 @@ class PluginLocalizationServer extends import_server.Plugin {
|
|
|
88
100
|
});
|
|
89
101
|
};
|
|
90
102
|
afterAdd() {
|
|
91
|
-
this.app.on("afterLoad", () => this.
|
|
103
|
+
this.app.on("afterLoad", () => this.handleLocaleSourceTextsSaved());
|
|
104
|
+
this.app.on("afterLoad", () => this.registerAITranslateTaskType());
|
|
92
105
|
}
|
|
93
106
|
beforeLoad() {
|
|
94
107
|
}
|
|
108
|
+
registerAITranslateTaskType() {
|
|
109
|
+
if (this.aiTranslateTaskRegistered) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const taskManager = this.app.container.get("AsyncTaskManager");
|
|
114
|
+
taskManager.registerTaskType(import_localization_ai_translate.LocalizationAITranslateTask);
|
|
115
|
+
this.aiTranslateTaskRegistered = true;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
this.log.warn("AsyncTaskManager is not available, skip localization AI translate task registration.");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
95
120
|
async load() {
|
|
121
|
+
this.registerAITranslateTaskType();
|
|
96
122
|
this.app.resourceManager.define({
|
|
97
123
|
name: "localizationTexts",
|
|
98
124
|
actions: import_localizationTexts.default
|
|
99
125
|
});
|
|
100
126
|
this.app.resourceManager.define({
|
|
101
127
|
name: "localization",
|
|
102
|
-
actions:
|
|
128
|
+
actions: {
|
|
129
|
+
...import_localization.default,
|
|
130
|
+
...import_aiTranslate.default
|
|
131
|
+
}
|
|
103
132
|
});
|
|
104
133
|
this.app.acl.registerSnippet({
|
|
105
134
|
name: `pm.${this.name}.localization`,
|
|
106
135
|
actions: ["localization:*", "localizationTexts:*", "localizationTranslations:*"]
|
|
107
136
|
});
|
|
137
|
+
this.app.acl.registerSnippet({
|
|
138
|
+
name: "ui.localization",
|
|
139
|
+
actions: ["localizationTexts:missing"]
|
|
140
|
+
});
|
|
108
141
|
this.app.localeManager.registerResourceStorer("plugin-localization", {
|
|
109
142
|
getResources: (lang) => this.resources.getResources(lang),
|
|
110
143
|
reset: () => this.resources.reset()
|
|
@@ -115,24 +148,22 @@ class PluginLocalizationServer extends import_server.Plugin {
|
|
|
115
148
|
store: "memory"
|
|
116
149
|
});
|
|
117
150
|
this.resources = new import_resources.default(this.db, cache);
|
|
118
|
-
this.
|
|
151
|
+
this.app.localeManager.registerSource("local", {
|
|
119
152
|
title: (0, import_utils2.tval)("System & Plugins", { ns: import_package.default.name }),
|
|
120
153
|
sync: async (ctx) => {
|
|
121
|
-
const resources = await ctx.app.localeManager.
|
|
154
|
+
const resources = await ctx.app.localeManager.getBuiltInResources(ctx.get("X-Locale") || "en-US");
|
|
122
155
|
const result = {};
|
|
123
156
|
Object.entries(resources).forEach(([module2, resource]) => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
result[module2] = resource;
|
|
157
|
+
const name = module2.startsWith(import_server.OFFICIAL_PLUGIN_PREFIX) ? module2.replace(import_server.OFFICIAL_PLUGIN_PREFIX, "") : module2;
|
|
158
|
+
result[name] = {
|
|
159
|
+
...result[name] || {},
|
|
160
|
+
...resource
|
|
161
|
+
};
|
|
131
162
|
});
|
|
132
163
|
return result;
|
|
133
164
|
}
|
|
134
165
|
});
|
|
135
|
-
this.
|
|
166
|
+
this.app.localeManager.registerSource("db", {
|
|
136
167
|
title: (0, import_utils2.tval)("Collections & Fields", { ns: import_package.default.name }),
|
|
137
168
|
namespace: import_constants.NAMESPACE_COLLECTIONS,
|
|
138
169
|
sync: async (ctx) => {
|
|
@@ -181,6 +212,37 @@ class PluginLocalizationServer extends import_server.Plugin {
|
|
|
181
212
|
await this.addNewTexts(texts, options);
|
|
182
213
|
});
|
|
183
214
|
}
|
|
215
|
+
handleLocaleSourceTextsSaved() {
|
|
216
|
+
for (const [sourceName, source] of this.app.localeManager.sources.getEntities()) {
|
|
217
|
+
if (!source.collections) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const [index, collectionOptions] of source.collections.entries()) {
|
|
221
|
+
const hookKey = `${sourceName}:${index}:${collectionOptions.collection}`;
|
|
222
|
+
if (this.localeSourceTextHookKeys.has(hookKey)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
this.localeSourceTextHookKeys.add(hookKey);
|
|
226
|
+
this.db.on(`${collectionOptions.collection}.afterSave`, async (instance, options) => {
|
|
227
|
+
let texts = [];
|
|
228
|
+
if (collectionOptions.getTexts) {
|
|
229
|
+
texts = await collectionOptions.getTexts(instance, options);
|
|
230
|
+
} else {
|
|
231
|
+
const fields = collectionOptions.fields || [];
|
|
232
|
+
const changedFields = fields.filter((field) => instance["_changed"].has(field));
|
|
233
|
+
if (!changedFields.length) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
texts = changedFields.map((field) => instance.get(field)).filter(Boolean).map((text) => ({ text, module: `resources.${source.namespace}` }));
|
|
237
|
+
}
|
|
238
|
+
if (!(texts == null ? void 0 : texts.length)) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
await this.addNewTexts(texts, options);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
184
246
|
async handleSyncMessage(message) {
|
|
185
247
|
switch (message.type) {
|
|
186
248
|
case "updateCacheTexts":
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { TaskType } from '@nocobase/plugin-async-task-manager';
|
|
10
|
+
import type { LocalizationTextRecord } from '../translation-scope';
|
|
11
|
+
export declare const LOCALIZATION_AI_TRANSLATE_TASK_TYPE = "localization:ai-translate";
|
|
12
|
+
export declare const pickBuiltInResourceReference: (row: LocalizationTextRecord, references: Map<string, Map<string, string>>, locales: ReferenceLocaleConfig) => {
|
|
13
|
+
locale: string;
|
|
14
|
+
translation: string;
|
|
15
|
+
} | {
|
|
16
|
+
locale?: undefined;
|
|
17
|
+
translation?: undefined;
|
|
18
|
+
};
|
|
19
|
+
type ReferenceLocaleConfig = {
|
|
20
|
+
primary?: string;
|
|
21
|
+
fallback?: string;
|
|
22
|
+
};
|
|
23
|
+
export type TranslationReferenceLocales = {
|
|
24
|
+
builtIn?: ReferenceLocaleConfig;
|
|
25
|
+
custom?: ReferenceLocaleConfig;
|
|
26
|
+
};
|
|
27
|
+
export declare class LocalizationAITranslateTask extends TaskType {
|
|
28
|
+
static type: string;
|
|
29
|
+
execute(): Promise<{
|
|
30
|
+
translated: number;
|
|
31
|
+
total: number;
|
|
32
|
+
}>;
|
|
33
|
+
private countTexts;
|
|
34
|
+
private getLocaleReferences;
|
|
35
|
+
private getReferenceMaps;
|
|
36
|
+
private getBuiltInReferenceMaps;
|
|
37
|
+
private pickDbReference;
|
|
38
|
+
private getSystemDefaultLocale;
|
|
39
|
+
private resolveReferenceLocales;
|
|
40
|
+
private buildTranslationItems;
|
|
41
|
+
private translateItem;
|
|
42
|
+
private translateText;
|
|
43
|
+
private getEmployeeSystemPrompt;
|
|
44
|
+
private buildProviderContext;
|
|
45
|
+
private getLanguageName;
|
|
46
|
+
private extractTextContent;
|
|
47
|
+
}
|
|
48
|
+
export {};
|