kythia-core 0.11.0-beta → 0.12.0-beta
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/Kythia.d.ts +45 -0
- package/dist/Kythia.d.ts.map +1 -0
- package/dist/Kythia.js +443 -0
- package/dist/Kythia.js.map +1 -0
- package/dist/KythiaClient.d.ts +3 -0
- package/dist/KythiaClient.d.ts.map +1 -0
- package/dist/KythiaClient.js +69 -0
- package/dist/KythiaClient.js.map +1 -0
- package/dist/cli/Command.d.ts +9 -0
- package/dist/cli/Command.d.ts.map +1 -0
- package/dist/cli/Command.js +19 -0
- package/dist/cli/Command.js.map +1 -0
- package/dist/cli/commands/CacheClearCommand.d.ts +8 -0
- package/dist/cli/commands/CacheClearCommand.d.ts.map +1 -0
- package/dist/cli/commands/CacheClearCommand.js +94 -0
- package/dist/cli/commands/CacheClearCommand.js.map +1 -0
- package/dist/cli/commands/LangCheckCommand.d.ts +7 -0
- package/dist/cli/commands/LangCheckCommand.d.ts.map +1 -0
- package/dist/cli/commands/LangCheckCommand.js +345 -0
- package/dist/cli/commands/LangCheckCommand.js.map +1 -0
- package/dist/cli/commands/LangTranslateCommand.d.ts +8 -0
- package/dist/cli/commands/LangTranslateCommand.d.ts.map +1 -0
- package/dist/cli/commands/LangTranslateCommand.js +221 -0
- package/dist/cli/commands/LangTranslateCommand.js.map +1 -0
- package/dist/cli/commands/MakeMigrationCommand.d.ts +7 -0
- package/dist/cli/commands/MakeMigrationCommand.d.ts.map +1 -0
- package/dist/cli/commands/MakeMigrationCommand.js +55 -0
- package/dist/cli/commands/MakeMigrationCommand.js.map +1 -0
- package/dist/cli/commands/MakeModelCommand.d.ts +7 -0
- package/dist/cli/commands/MakeModelCommand.d.ts.map +1 -0
- package/dist/cli/commands/MakeModelCommand.js +56 -0
- package/dist/cli/commands/MakeModelCommand.js.map +1 -0
- package/dist/cli/commands/MigrateCommand.d.ts +14 -0
- package/dist/cli/commands/MigrateCommand.d.ts.map +1 -0
- package/dist/cli/commands/MigrateCommand.js +190 -0
- package/dist/cli/commands/MigrateCommand.js.map +1 -0
- package/dist/cli/commands/NamespaceCommand.d.ts +7 -0
- package/dist/cli/commands/NamespaceCommand.d.ts.map +1 -0
- package/dist/cli/commands/NamespaceCommand.js +92 -0
- package/dist/cli/commands/NamespaceCommand.js.map +1 -0
- package/dist/cli/commands/StructureCommand.d.ts +7 -0
- package/dist/cli/commands/StructureCommand.d.ts.map +1 -0
- package/dist/cli/commands/StructureCommand.js +51 -0
- package/dist/cli/commands/StructureCommand.js.map +1 -0
- package/dist/cli/commands/UpversionCommand.d.ts +7 -0
- package/dist/cli/commands/UpversionCommand.d.ts.map +1 -0
- package/dist/cli/commands/UpversionCommand.js +68 -0
- package/dist/cli/commands/UpversionCommand.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +44 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/db.d.ts +9 -0
- package/dist/cli/utils/db.d.ts.map +1 -0
- package/dist/cli/utils/db.js +90 -0
- package/dist/cli/utils/db.js.map +1 -0
- package/dist/database/KythiaMigrator.d.ts +4 -0
- package/dist/database/KythiaMigrator.d.ts.map +1 -0
- package/dist/database/KythiaMigrator.js +94 -0
- package/dist/database/KythiaMigrator.js.map +1 -0
- package/dist/database/KythiaModel.d.ts +83 -0
- package/dist/database/KythiaModel.d.ts.map +1 -0
- package/dist/database/KythiaModel.js +1121 -0
- package/dist/database/KythiaModel.js.map +1 -0
- package/dist/database/KythiaSequelize.d.ts +4 -0
- package/dist/database/KythiaSequelize.d.ts.map +1 -0
- package/dist/database/KythiaSequelize.js +99 -0
- package/dist/database/KythiaSequelize.js.map +1 -0
- package/dist/database/KythiaStorage.d.ts +21 -0
- package/dist/database/KythiaStorage.d.ts.map +1 -0
- package/dist/database/KythiaStorage.js +80 -0
- package/dist/database/KythiaStorage.js.map +1 -0
- package/dist/database/ModelLoader.d.ts +4 -0
- package/dist/database/ModelLoader.d.ts.map +1 -0
- package/dist/database/ModelLoader.js +54 -0
- package/dist/database/ModelLoader.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/lang/en.json +85 -0
- package/dist/managers/AddonManager.d.ts +45 -0
- package/dist/managers/AddonManager.d.ts.map +1 -0
- package/dist/managers/AddonManager.js +932 -0
- package/dist/managers/AddonManager.js.map +1 -0
- package/dist/managers/EventManager.d.ts +19 -0
- package/dist/managers/EventManager.d.ts.map +1 -0
- package/dist/managers/EventManager.js +55 -0
- package/dist/managers/EventManager.js.map +1 -0
- package/dist/managers/InteractionManager.d.ts +41 -0
- package/dist/managers/InteractionManager.d.ts.map +1 -0
- package/dist/managers/InteractionManager.js +441 -0
- package/dist/managers/InteractionManager.js.map +1 -0
- package/dist/managers/MiddlewareManager.d.ts +14 -0
- package/dist/managers/MiddlewareManager.d.ts.map +1 -0
- package/dist/managers/MiddlewareManager.js +75 -0
- package/dist/managers/MiddlewareManager.js.map +1 -0
- package/dist/managers/ShutdownManager.d.ts +22 -0
- package/dist/managers/ShutdownManager.d.ts.map +1 -0
- package/dist/managers/ShutdownManager.js +151 -0
- package/dist/managers/ShutdownManager.js.map +1 -0
- package/dist/managers/TranslatorManager.d.ts +19 -0
- package/dist/managers/TranslatorManager.d.ts.map +1 -0
- package/dist/managers/TranslatorManager.js +118 -0
- package/dist/managers/TranslatorManager.js.map +1 -0
- package/dist/middlewares/botPermissions.d.ts +4 -0
- package/dist/middlewares/botPermissions.d.ts.map +1 -0
- package/dist/middlewares/botPermissions.js +28 -0
- package/dist/middlewares/botPermissions.js.map +1 -0
- package/dist/middlewares/cooldown.d.ts +4 -0
- package/dist/middlewares/cooldown.d.ts.map +1 -0
- package/dist/middlewares/cooldown.js +42 -0
- package/dist/middlewares/cooldown.js.map +1 -0
- package/dist/middlewares/isInMainGuild.d.ts +4 -0
- package/dist/middlewares/isInMainGuild.d.ts.map +1 -0
- package/dist/middlewares/isInMainGuild.js +52 -0
- package/dist/middlewares/isInMainGuild.js.map +1 -0
- package/dist/middlewares/ownerOnly.d.ts +4 -0
- package/dist/middlewares/ownerOnly.d.ts.map +1 -0
- package/dist/middlewares/ownerOnly.js +24 -0
- package/dist/middlewares/ownerOnly.js.map +1 -0
- package/dist/middlewares/teamOnly.d.ts +4 -0
- package/dist/middlewares/teamOnly.d.ts.map +1 -0
- package/dist/middlewares/teamOnly.js +26 -0
- package/dist/middlewares/teamOnly.js.map +1 -0
- package/dist/middlewares/userPermissions.d.ts +4 -0
- package/dist/middlewares/userPermissions.d.ts.map +1 -0
- package/dist/middlewares/userPermissions.js +28 -0
- package/dist/middlewares/userPermissions.js.map +1 -0
- package/dist/middlewares/voteLocked.d.ts +4 -0
- package/dist/middlewares/voteLocked.d.ts.map +1 -0
- package/dist/middlewares/voteLocked.js +50 -0
- package/dist/middlewares/voteLocked.js.map +1 -0
- package/dist/structures/BaseCommand.d.ts +23 -0
- package/dist/structures/BaseCommand.d.ts.map +1 -0
- package/dist/structures/BaseCommand.js +42 -0
- package/dist/structures/BaseCommand.js.map +1 -0
- package/dist/types/AddonManager.d.ts +58 -0
- package/dist/types/AddonManager.d.ts.map +1 -0
- package/dist/types/AddonManager.js +3 -0
- package/dist/types/AddonManager.js.map +1 -0
- package/dist/types/DiscordHelpers.d.ts +7 -0
- package/dist/types/DiscordHelpers.d.ts.map +1 -0
- package/dist/types/DiscordHelpers.js +3 -0
- package/dist/types/DiscordHelpers.js.map +1 -0
- package/dist/types/EventManager.d.ts +10 -0
- package/dist/types/EventManager.d.ts.map +1 -0
- package/dist/types/EventManager.js +3 -0
- package/dist/types/EventManager.js.map +1 -0
- package/dist/types/InteractionManager.d.ts +35 -0
- package/dist/types/InteractionManager.d.ts.map +1 -0
- package/dist/types/InteractionManager.js +3 -0
- package/dist/types/InteractionManager.js.map +1 -0
- package/dist/types/KythiaClient.d.ts +9 -0
- package/dist/types/KythiaClient.d.ts.map +1 -0
- package/dist/types/KythiaClient.js +3 -0
- package/dist/types/KythiaClient.js.map +1 -0
- package/dist/types/KythiaConfig.d.ts +291 -0
- package/dist/types/KythiaConfig.d.ts.map +1 -0
- package/dist/types/KythiaConfig.js +3 -0
- package/dist/types/KythiaConfig.js.map +1 -0
- package/dist/types/KythiaContainer.d.ts +38 -0
- package/dist/types/KythiaContainer.d.ts.map +1 -0
- package/dist/types/KythiaContainer.js +3 -0
- package/dist/types/KythiaContainer.js.map +1 -0
- package/dist/types/KythiaLogger.d.ts +5 -0
- package/dist/types/KythiaLogger.d.ts.map +1 -0
- package/dist/types/KythiaLogger.js +3 -0
- package/dist/types/KythiaLogger.js.map +1 -0
- package/dist/types/KythiaMigrator.d.ts +9 -0
- package/dist/types/KythiaMigrator.d.ts.map +1 -0
- package/dist/types/KythiaMigrator.js +3 -0
- package/dist/types/KythiaMigrator.js.map +1 -0
- package/dist/types/KythiaModel.d.ts +31 -0
- package/dist/types/KythiaModel.d.ts.map +1 -0
- package/dist/types/KythiaModel.js +3 -0
- package/dist/types/KythiaModel.js.map +1 -0
- package/dist/types/KythiaOptions.d.ts +13 -0
- package/dist/types/KythiaOptions.d.ts.map +1 -0
- package/dist/types/KythiaOptions.js +3 -0
- package/dist/types/KythiaOptions.js.map +1 -0
- package/dist/types/KythiaSequelize.d.ts +13 -0
- package/dist/types/KythiaSequelize.d.ts.map +1 -0
- package/dist/types/KythiaSequelize.js +3 -0
- package/dist/types/KythiaSequelize.js.map +1 -0
- package/dist/types/KythiaStorage.d.ts +22 -0
- package/dist/types/KythiaStorage.d.ts.map +1 -0
- package/dist/types/KythiaStorage.js +3 -0
- package/dist/types/KythiaStorage.js.map +1 -0
- package/dist/types/MiddlewareManager.d.ts +14 -0
- package/dist/types/MiddlewareManager.d.ts.map +1 -0
- package/dist/types/MiddlewareManager.js +3 -0
- package/dist/types/MiddlewareManager.js.map +1 -0
- package/dist/types/ModelLoader.d.ts +8 -0
- package/dist/types/ModelLoader.d.ts.map +1 -0
- package/dist/types/ModelLoader.js +3 -0
- package/dist/types/ModelLoader.js.map +1 -0
- package/dist/types/ShutdownManager.d.ts +15 -0
- package/dist/types/ShutdownManager.d.ts.map +1 -0
- package/dist/types/ShutdownManager.js +3 -0
- package/dist/types/ShutdownManager.js.map +1 -0
- package/dist/types/TranslatorManager.d.ts +16 -0
- package/dist/types/TranslatorManager.d.ts.map +1 -0
- package/dist/types/TranslatorManager.js +3 -0
- package/dist/types/TranslatorManager.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +29 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/color.d.ts +15 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +156 -0
- package/dist/utils/color.js.map +1 -0
- package/dist/utils/discord.d.ts +8 -0
- package/dist/utils/discord.d.ts.map +1 -0
- package/dist/utils/discord.js +53 -0
- package/dist/utils/discord.js.map +1 -0
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +89 -0
- package/dist/utils/formatter.js.map +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +54 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +150 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +28 -6
- package/src/lang/en.json +85 -0
- package/changelog.md +0 -53
- package/index.js +0 -15
- package/src/Kythia.js +0 -556
- package/src/KythiaClient.js +0 -94
- package/src/cli/Command.js +0 -68
- package/src/cli/commands/CacheClearCommand.js +0 -136
- package/src/cli/commands/LangCheckCommand.js +0 -367
- package/src/cli/commands/LangTranslateCommand.js +0 -336
- package/src/cli/commands/MakeMigrationCommand.js +0 -82
- package/src/cli/commands/MakeModelCommand.js +0 -81
- package/src/cli/commands/MigrateCommand.js +0 -259
- package/src/cli/commands/NamespaceCommand.js +0 -112
- package/src/cli/commands/StructureCommand.js +0 -70
- package/src/cli/commands/UpversionCommand.js +0 -94
- package/src/cli/index.js +0 -69
- package/src/cli/utils/db.js +0 -117
- package/src/database/KythiaMigrator.js +0 -116
- package/src/database/KythiaModel.js +0 -1557
- package/src/database/KythiaSequelize.js +0 -128
- package/src/database/KythiaStorage.js +0 -117
- package/src/database/ModelLoader.js +0 -79
- package/src/managers/AddonManager.js +0 -1219
- package/src/managers/EventManager.js +0 -104
- package/src/managers/InteractionManager.js +0 -815
- package/src/managers/ShutdownManager.js +0 -218
- package/src/structures/BaseCommand.js +0 -53
- package/src/utils/color.js +0 -180
- package/src/utils/formatter.js +0 -99
- package/src/utils/index.js +0 -4
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🌐 AI Localization Assistant
|
|
3
|
-
*
|
|
4
|
-
* @file src/cli/commands/LangTranslateCommand.js
|
|
5
|
-
* @copyright © 2025 kenndeclouv
|
|
6
|
-
* @assistant chaa & graa
|
|
7
|
-
* @version 0.11.0-beta
|
|
8
|
-
*
|
|
9
|
-
* @description
|
|
10
|
-
* Automates the translation of the core language file (`en.json`) to a target language
|
|
11
|
-
* using Google's Gemini AI. Handles JSON flattening, batch processing, and placeholder preservation.
|
|
12
|
-
*
|
|
13
|
-
* ✨ Core Features:
|
|
14
|
-
* - AI-Powered: Uses Gemini 2.5 Flash for natural translations.
|
|
15
|
-
* - Smart Batching: Splits large files to avoid token limits.
|
|
16
|
-
* - Context Aware: Preserves keys and complex placeholders.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const Command = require('../Command');
|
|
20
|
-
const pc = require('picocolors');
|
|
21
|
-
|
|
22
|
-
class LangTranslateCommand extends Command {
|
|
23
|
-
signature = 'lang:translate <target>';
|
|
24
|
-
description = 'Translate en.json to target language using Gemini AI';
|
|
25
|
-
|
|
26
|
-
async handle(_options, target) {
|
|
27
|
-
require('@dotenvx/dotenvx/config');
|
|
28
|
-
const fs = require('node:fs');
|
|
29
|
-
const path = require('node:path');
|
|
30
|
-
const { GoogleGenAI } = require('@google/genai');
|
|
31
|
-
|
|
32
|
-
const API_KEYS = (process.env.GEMINI_API_KEYS || '')
|
|
33
|
-
.split(',')
|
|
34
|
-
.filter(Boolean);
|
|
35
|
-
|
|
36
|
-
const targetLang = target || 'ja';
|
|
37
|
-
|
|
38
|
-
const TARGET_LANGUAGE =
|
|
39
|
-
targetLang === 'ja' ? 'Japan (ja)' : `${targetLang}`;
|
|
40
|
-
|
|
41
|
-
const rootDir = process.cwd();
|
|
42
|
-
const INPUT_FILE_SAFE = path.join(
|
|
43
|
-
rootDir,
|
|
44
|
-
'addons',
|
|
45
|
-
'core',
|
|
46
|
-
'lang',
|
|
47
|
-
'en.json',
|
|
48
|
-
);
|
|
49
|
-
const OUTPUT_FILE_SAFE = path.join(
|
|
50
|
-
rootDir,
|
|
51
|
-
'addons',
|
|
52
|
-
'core',
|
|
53
|
-
'lang',
|
|
54
|
-
`${targetLang}.json`,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const BATCH_SIZE = 80;
|
|
58
|
-
const GEMINI_MODEL = 'gemini-2.5-flash';
|
|
59
|
-
const DELAY_BETWEEN_BATCHES_MS = 5000;
|
|
60
|
-
const DELAY_ON_ERROR_MS = 5000;
|
|
61
|
-
|
|
62
|
-
if (API_KEYS.length === 0) {
|
|
63
|
-
console.error(pc.red('❌ FATAL: GEMINI_API_KEYS not found in .env!'));
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let keyIndex = 0;
|
|
68
|
-
function getNextGenAI(nextIndex = null) {
|
|
69
|
-
if (typeof nextIndex === 'number') {
|
|
70
|
-
keyIndex = nextIndex % API_KEYS.length;
|
|
71
|
-
}
|
|
72
|
-
const apiKey = API_KEYS[keyIndex];
|
|
73
|
-
keyIndex = (keyIndex + 1) % API_KEYS.length;
|
|
74
|
-
console.log(
|
|
75
|
-
`[Key Rotator] Using API Key #${keyIndex === 0 ? API_KEYS.length : keyIndex}`,
|
|
76
|
-
);
|
|
77
|
-
return new GoogleGenAI({ apiKey });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function flattenObject(obj, parentKey = '', result = {}) {
|
|
81
|
-
for (const key in obj) {
|
|
82
|
-
const newKey = parentKey ? `${parentKey}.${key}` : key;
|
|
83
|
-
if (
|
|
84
|
-
typeof obj[key] === 'object' &&
|
|
85
|
-
obj[key] !== null &&
|
|
86
|
-
!Array.isArray(obj[key])
|
|
87
|
-
) {
|
|
88
|
-
flattenObject(obj[key], newKey, result);
|
|
89
|
-
} else {
|
|
90
|
-
result[newKey] = obj[key];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function unflattenObject(obj) {
|
|
97
|
-
const result = {};
|
|
98
|
-
for (const key in obj) {
|
|
99
|
-
const keys = key.split('.');
|
|
100
|
-
keys.reduce((acc, cur, i) => {
|
|
101
|
-
if (i === keys.length - 1) {
|
|
102
|
-
acc[cur] = obj[key];
|
|
103
|
-
} else {
|
|
104
|
-
acc[cur] = acc[cur] || {};
|
|
105
|
-
}
|
|
106
|
-
return acc[cur];
|
|
107
|
-
}, result);
|
|
108
|
-
}
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async function translateBatch(batch) {
|
|
113
|
-
const placeholderMap = new Map();
|
|
114
|
-
let placeholderCounter = 0;
|
|
115
|
-
|
|
116
|
-
const processedBatch = JSON.parse(
|
|
117
|
-
JSON.stringify(batch),
|
|
118
|
-
(_key, value) => {
|
|
119
|
-
if (typeof value !== 'string') return value;
|
|
120
|
-
return value.replace(/{([^{}]*)}/g, (match) => {
|
|
121
|
-
if (!placeholderMap.has(match)) {
|
|
122
|
-
placeholderMap.set(`__P_${placeholderCounter}__`, match);
|
|
123
|
-
placeholderCounter++;
|
|
124
|
-
}
|
|
125
|
-
for (const [token, ph] of placeholderMap.entries()) {
|
|
126
|
-
if (ph === match) return token;
|
|
127
|
-
}
|
|
128
|
-
return match;
|
|
129
|
-
});
|
|
130
|
-
},
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
const prompt = `
|
|
134
|
-
You are a professional localization expert. Translate the JSON values from english to ${TARGET_LANGUAGE}.
|
|
135
|
-
|
|
136
|
-
- **Target Locale:** ${targetLang} (choose naturally)
|
|
137
|
-
- **DO NOT** translate the JSON keys.
|
|
138
|
-
- **DO NOT** translate any placeholder tokens that look like \`__P_N__\`. Keep them exactly as they are.
|
|
139
|
-
- **KEEP** all original markdown (\`##\`, \`*\`, \`\\\`\`, \`\n\`).
|
|
140
|
-
- Respond ONLY with the translated JSON object, in a VALID JSON format.
|
|
141
|
-
|
|
142
|
-
Input:
|
|
143
|
-
${JSON.stringify(processedBatch, null, 2)}
|
|
144
|
-
|
|
145
|
-
Output:
|
|
146
|
-
`;
|
|
147
|
-
|
|
148
|
-
let attempt = 1;
|
|
149
|
-
let usedKeyIndex = keyIndex;
|
|
150
|
-
|
|
151
|
-
while (true) {
|
|
152
|
-
let genAI = getNextGenAI();
|
|
153
|
-
const GEMINI_API_CLIENT = genAI;
|
|
154
|
-
try {
|
|
155
|
-
console.log(`[Batch] Attempt #${attempt}...`);
|
|
156
|
-
|
|
157
|
-
const response = await GEMINI_API_CLIENT.models.generateContent({
|
|
158
|
-
model: GEMINI_MODEL,
|
|
159
|
-
contents: [{ role: 'user', parts: [{ text: prompt }] }],
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
let text;
|
|
163
|
-
if (response && typeof response.text === 'function') {
|
|
164
|
-
text = response.text();
|
|
165
|
-
} else if (response && typeof response.text === 'string') {
|
|
166
|
-
text = response.text;
|
|
167
|
-
}
|
|
168
|
-
text = typeof text === 'string' ? text.trim() : '';
|
|
169
|
-
|
|
170
|
-
if (text.startsWith('```json')) {
|
|
171
|
-
text = text.substring(7, text.length - 3).trim();
|
|
172
|
-
} else if (text.startsWith('```')) {
|
|
173
|
-
text = text
|
|
174
|
-
.replace(/^```[a-z]*\n?/, '')
|
|
175
|
-
.replace(/```$/, '')
|
|
176
|
-
.trim();
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
let translatedBatch = JSON.parse(text);
|
|
180
|
-
translatedBatch = JSON.parse(
|
|
181
|
-
JSON.stringify(translatedBatch),
|
|
182
|
-
(_key, value) => {
|
|
183
|
-
if (typeof value !== 'string') return value;
|
|
184
|
-
return value.replace(
|
|
185
|
-
/__P_(\d+)__/g,
|
|
186
|
-
(match) => placeholderMap.get(match) || match,
|
|
187
|
-
);
|
|
188
|
-
},
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
return translatedBatch;
|
|
192
|
-
} catch (e) {
|
|
193
|
-
const errorMessage = e.message || '';
|
|
194
|
-
console.error(
|
|
195
|
-
pc.red(`❌ Error in batch (Attempt ${attempt})...`),
|
|
196
|
-
errorMessage,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
errorMessage.includes('429') ||
|
|
201
|
-
errorMessage.includes('RESOURCE_EXHAUSTED')
|
|
202
|
-
) {
|
|
203
|
-
usedKeyIndex = (usedKeyIndex + 1) % API_KEYS.length;
|
|
204
|
-
console.warn(
|
|
205
|
-
pc.yellow(
|
|
206
|
-
`[RATE LIMIT] Got 429! Rotating to next API key [#${usedKeyIndex + 1}] and retrying.`,
|
|
207
|
-
),
|
|
208
|
-
);
|
|
209
|
-
genAI = getNextGenAI(usedKeyIndex);
|
|
210
|
-
} else {
|
|
211
|
-
console.warn(
|
|
212
|
-
pc.yellow(
|
|
213
|
-
`[OTHER ERROR] Waiting ${DELAY_ON_ERROR_MS / 1000} seconds...`,
|
|
214
|
-
),
|
|
215
|
-
);
|
|
216
|
-
await new Promise((resolve) =>
|
|
217
|
-
setTimeout(resolve, DELAY_ON_ERROR_MS),
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
attempt++;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
console.log(
|
|
226
|
-
pc.cyan(`🚀 Starting translation process (to ${targetLang})...`),
|
|
227
|
-
);
|
|
228
|
-
console.log(pc.dim(` Input: ${INPUT_FILE_SAFE}`));
|
|
229
|
-
console.log(pc.dim(` Output: ${OUTPUT_FILE_SAFE}`));
|
|
230
|
-
|
|
231
|
-
if (!fs.existsSync(INPUT_FILE_SAFE)) {
|
|
232
|
-
console.error(pc.red(`❌ Input file not found: ${INPUT_FILE_SAFE}`));
|
|
233
|
-
process.exit(1);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const idJsonString = fs.readFileSync(INPUT_FILE_SAFE, 'utf8');
|
|
237
|
-
const idJson = JSON.parse(idJsonString);
|
|
238
|
-
|
|
239
|
-
console.log(pc.dim('Flattening JSON...'));
|
|
240
|
-
const flatIdJson = flattenObject(idJson);
|
|
241
|
-
const flatLangJson = {};
|
|
242
|
-
const allKeys = Object.keys(flatIdJson);
|
|
243
|
-
|
|
244
|
-
let existingLangJson = {};
|
|
245
|
-
if (fs.existsSync(OUTPUT_FILE_SAFE)) {
|
|
246
|
-
console.log(
|
|
247
|
-
pc.yellow(`[INFO] File ${OUTPUT_FILE_SAFE} exists, continuing work...`),
|
|
248
|
-
);
|
|
249
|
-
try {
|
|
250
|
-
existingLangJson = flattenObject(
|
|
251
|
-
JSON.parse(fs.readFileSync(OUTPUT_FILE_SAFE, 'utf8')),
|
|
252
|
-
);
|
|
253
|
-
} catch (_e) {
|
|
254
|
-
console.warn(
|
|
255
|
-
pc.yellow(
|
|
256
|
-
`[WARN] File ${OUTPUT_FILE_SAFE} is corrupted, will be overwritten.`,
|
|
257
|
-
),
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const keysToTranslate = allKeys.filter(
|
|
263
|
-
(key) =>
|
|
264
|
-
typeof flatIdJson[key] === 'string' &&
|
|
265
|
-
(!existingLangJson[key] || existingLangJson[key] === flatIdJson[key]),
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
allKeys.forEach((key) => {
|
|
269
|
-
if (!keysToTranslate.includes(key)) {
|
|
270
|
-
flatLangJson[key] = existingLangJson[key] || flatIdJson[key];
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
const totalBatches = Math.ceil(keysToTranslate.length / BATCH_SIZE);
|
|
275
|
-
|
|
276
|
-
console.log(pc.green(`✅ Total of ${allKeys.length} keys.`));
|
|
277
|
-
console.log(
|
|
278
|
-
pc.green(
|
|
279
|
-
`✅ Found ${keysToTranslate.length} keys that need translation.`,
|
|
280
|
-
),
|
|
281
|
-
);
|
|
282
|
-
console.log(
|
|
283
|
-
pc.green(
|
|
284
|
-
`✅ Divided into ${totalBatches} batches (up to ${BATCH_SIZE} keys per batch).`,
|
|
285
|
-
),
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
for (let i = 0; i < totalBatches; i++) {
|
|
289
|
-
console.log(
|
|
290
|
-
pc.cyan(`--- 🏃 Working on Batch ${i + 1} / ${totalBatches} ---`),
|
|
291
|
-
);
|
|
292
|
-
const batchKeys = keysToTranslate.slice(
|
|
293
|
-
i * BATCH_SIZE,
|
|
294
|
-
(i + 1) * BATCH_SIZE,
|
|
295
|
-
);
|
|
296
|
-
const batchToTranslate = {};
|
|
297
|
-
batchKeys.forEach((key) => {
|
|
298
|
-
batchToTranslate[key] = flatIdJson[key];
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
if (Object.keys(batchToTranslate).length > 0) {
|
|
302
|
-
const translatedBatch = await translateBatch(batchToTranslate);
|
|
303
|
-
if (translatedBatch) {
|
|
304
|
-
Object.assign(flatLangJson, translatedBatch);
|
|
305
|
-
} else {
|
|
306
|
-
Object.assign(flatLangJson, batchToTranslate);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (i < totalBatches - 1) {
|
|
311
|
-
console.log(
|
|
312
|
-
pc.yellow(
|
|
313
|
-
`--- 😴 Waiting ${DELAY_BETWEEN_BATCHES_MS / 1000} seconds between batches ---`,
|
|
314
|
-
),
|
|
315
|
-
);
|
|
316
|
-
await new Promise((resolve) =>
|
|
317
|
-
setTimeout(resolve, DELAY_BETWEEN_BATCHES_MS),
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
console.log(pc.dim('Unflattening JSON...'));
|
|
323
|
-
const langJson = unflattenObject(flatLangJson);
|
|
324
|
-
|
|
325
|
-
console.log(pc.green(`Saving to file: ${OUTPUT_FILE_SAFE}`));
|
|
326
|
-
fs.writeFileSync(
|
|
327
|
-
OUTPUT_FILE_SAFE,
|
|
328
|
-
JSON.stringify(langJson, null, 2),
|
|
329
|
-
'utf8',
|
|
330
|
-
);
|
|
331
|
-
|
|
332
|
-
console.log(pc.green('🎉 Done! Translation file generated successfully.'));
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
module.exports = LangTranslateCommand;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 📐 Migration File Generator
|
|
3
|
-
*
|
|
4
|
-
* @file src/cli/commands/MakeMigrationCommand.js
|
|
5
|
-
* @copyright © 2025 kenndeclouv
|
|
6
|
-
* @assistant chaa & graa
|
|
7
|
-
* @version 0.11.0-beta
|
|
8
|
-
*
|
|
9
|
-
* @description
|
|
10
|
-
* Scaffolds a new database migration file with a precise YYYYMMDD_HHMMSS timestamp prefix.
|
|
11
|
-
* Places the file in the specified addon's migration directory.
|
|
12
|
-
*
|
|
13
|
-
* ✨ Core Features:
|
|
14
|
-
* - Timestamped Ordering: Ensures migrations run in creation order.
|
|
15
|
-
* - Addon Aware: Targets the correct module folder automatically.
|
|
16
|
-
* - Template Injection: Provides standard up/down methods via `queryInterface`.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const Command = require('../Command');
|
|
20
|
-
const fs = require('node:fs');
|
|
21
|
-
const path = require('node:path');
|
|
22
|
-
const pc = require('picocolors');
|
|
23
|
-
|
|
24
|
-
class MakeMigrationCommand extends Command {
|
|
25
|
-
signature = 'make:migration <name> <addon>';
|
|
26
|
-
description = 'Create a new migration file for an addon';
|
|
27
|
-
|
|
28
|
-
async handle(_options, name, addon) {
|
|
29
|
-
const rootDir = process.cwd();
|
|
30
|
-
const targetDir = path.join(
|
|
31
|
-
rootDir,
|
|
32
|
-
'addons',
|
|
33
|
-
addon,
|
|
34
|
-
'database',
|
|
35
|
-
'migrations',
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
if (!fs.existsSync(path.join(rootDir, 'addons', addon))) {
|
|
39
|
-
console.error(pc.red(`❌ Addon '${addon}' not found!`));
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!fs.existsSync(targetDir)) {
|
|
44
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const now = new Date();
|
|
48
|
-
const timestamp = now
|
|
49
|
-
.toISOString()
|
|
50
|
-
.replace(/T/, '_')
|
|
51
|
-
.replace(/[-:]/g, '')
|
|
52
|
-
.split('.')[0];
|
|
53
|
-
const fileName = `${timestamp}_${name}.js`;
|
|
54
|
-
const filePath = path.join(targetDir, fileName);
|
|
55
|
-
|
|
56
|
-
const template = `/**
|
|
57
|
-
* @namespace: addons/${addon}/database/migrations/${fileName}
|
|
58
|
-
* @type: Database Migration
|
|
59
|
-
* @copyright © 2025 kenndeclouv
|
|
60
|
-
* @assistant chaa & graa
|
|
61
|
-
* @version 0.9.12-beta
|
|
62
|
-
*/
|
|
63
|
-
module.exports = {
|
|
64
|
-
async up(queryInterface, DataTypes) {
|
|
65
|
-
// await queryInterface.createTable('table_name', {
|
|
66
|
-
// id: DataTypes.INTEGER
|
|
67
|
-
// });
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
async down(queryInterface, DataTypes) {
|
|
71
|
-
// await queryInterface.dropTable('table_name');
|
|
72
|
-
}
|
|
73
|
-
};`;
|
|
74
|
-
|
|
75
|
-
fs.writeFileSync(filePath, template);
|
|
76
|
-
|
|
77
|
-
console.log(pc.green('✅ Created migration:'));
|
|
78
|
-
console.log(pc.dim(` addons/${addon}/database/migrations/${fileName}`));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
module.exports = MakeMigrationCommand;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 📦 Model Scaffolding Tool
|
|
3
|
-
*
|
|
4
|
-
* @file src/cli/commands/MakeModelCommand.js
|
|
5
|
-
* @copyright © 2025 kenndeclouv
|
|
6
|
-
* @assistant chaa & graa
|
|
7
|
-
* @version 0.11.0-beta
|
|
8
|
-
*
|
|
9
|
-
* @description
|
|
10
|
-
* Generates new Sequelize model files extending `KythiaModel`.
|
|
11
|
-
* Automatically creates the directory structure and populates standard boilerplate.
|
|
12
|
-
*
|
|
13
|
-
* ✨ Core Features:
|
|
14
|
-
* - Smart Scaffolding: Creates models in `addons/{addon}/database/models`.
|
|
15
|
-
* - Duplicate Protection: Prevents overwriting existing models.
|
|
16
|
-
* - Standard Boilerplate: Includes `guarded` and `structure` properties by default.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const Command = require('../Command');
|
|
20
|
-
const fs = require('node:fs');
|
|
21
|
-
const path = require('node:path');
|
|
22
|
-
const pc = require('picocolors');
|
|
23
|
-
|
|
24
|
-
class MakeModelCommand extends Command {
|
|
25
|
-
signature = 'make:model <name> <addon>';
|
|
26
|
-
description = 'Create a new KythiaModel file';
|
|
27
|
-
|
|
28
|
-
async handle(_options, name, addon) {
|
|
29
|
-
//
|
|
30
|
-
const rootDir = process.cwd();
|
|
31
|
-
const targetDir = path.join(rootDir, 'addons', addon, 'database', 'models');
|
|
32
|
-
|
|
33
|
-
if (!fs.existsSync(path.join(rootDir, 'addons', addon))) {
|
|
34
|
-
console.error(pc.red(`❌ Addon '${addon}' not found!`));
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (!fs.existsSync(targetDir)) {
|
|
39
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const fileName = `${name}.js`;
|
|
43
|
-
const filePath = path.join(targetDir, fileName);
|
|
44
|
-
|
|
45
|
-
if (fs.existsSync(filePath)) {
|
|
46
|
-
console.error(
|
|
47
|
-
pc.red(`❌ Model '${fileName}' already exists in ${addon}!`),
|
|
48
|
-
);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const template = `/**
|
|
53
|
-
* @namespace: addons/${addon}/database/models/${fileName}
|
|
54
|
-
* @type: Database Model
|
|
55
|
-
* @copyright © ${new Date().getFullYear()} kenndeclouv
|
|
56
|
-
* @assistant chaa & graa
|
|
57
|
-
* @version 0.9.12-beta
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
const { KythiaModel } = require("kythia-core");
|
|
61
|
-
|
|
62
|
-
class ${name} extends KythiaModel {
|
|
63
|
-
static guarded = ["id"];
|
|
64
|
-
|
|
65
|
-
static get structure() {
|
|
66
|
-
return {
|
|
67
|
-
options: { timestamps: true },
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
module.exports = ${name};`;
|
|
73
|
-
|
|
74
|
-
fs.writeFileSync(filePath, template);
|
|
75
|
-
|
|
76
|
-
console.log(pc.green('✅ Created Model:'));
|
|
77
|
-
console.log(pc.dim(` addons/${addon}/database/models/${fileName}`));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
module.exports = MakeModelCommand;
|