@ollang-dev/sdk 0.3.4 → 0.3.5
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/browser/index.js +29 -16
- package/dist/browser/ollang-browser.min.js +1 -1
- package/dist/browser/script-loader.js +1 -7
- package/dist/index.js +3 -2
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +30 -0
- package/dist/tms/config.js +5 -4
- package/dist/tms/multi-content-tms.js +5 -4
- package/dist/tms/server/index.js +71 -77
- package/dist/tms/tms.js +37 -42
- package/dist/tms/ui-dist/assets/{index-HvrqZV5Z.js → index-BPh6OEAp.js} +5 -5
- package/dist/tms/ui-dist/index.html +1 -1
- package/package.json +1 -1
package/dist/tms/server/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const tms_js_1 = require("../tms.js");
|
|
|
9
9
|
const auto_detect_js_1 = require("../detector/auto-detect.js");
|
|
10
10
|
const strapi_pusher_js_1 = require("./strapi-pusher.js");
|
|
11
11
|
const strapi_schema_js_1 = require("./strapi-schema.js");
|
|
12
|
+
const logger_js_1 = require("../../logger.js");
|
|
12
13
|
const app = (0, express_1.default)();
|
|
13
14
|
const strapiSchemaCache = new Map();
|
|
14
15
|
const PORT = process.env.TMS_PORT || 5972;
|
|
@@ -88,13 +89,13 @@ async function updateCurrentScan(folderName) {
|
|
|
88
89
|
const state = getOrCreateFolderState(folderName);
|
|
89
90
|
const { currentScanId, texts, videos, images, audios } = state;
|
|
90
91
|
if (!tms) {
|
|
91
|
-
|
|
92
|
+
logger_js_1.logger.warn('Cannot update scan: Ollang not initialized');
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
95
|
try {
|
|
95
96
|
const sdk = tms.getSDK();
|
|
96
97
|
if (!sdk) {
|
|
97
|
-
|
|
98
|
+
logger_js_1.logger.warn('SDK not available');
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
if (!currentScanId) {
|
|
@@ -104,7 +105,7 @@ async function updateCurrentScan(folderName) {
|
|
|
104
105
|
state.currentScanId = previousScans[0].id;
|
|
105
106
|
}
|
|
106
107
|
else {
|
|
107
|
-
|
|
108
|
+
logger_js_1.logger.warn('No existing scan found, cannot update');
|
|
108
109
|
return;
|
|
109
110
|
}
|
|
110
111
|
}
|
|
@@ -117,7 +118,7 @@ async function updateCurrentScan(folderName) {
|
|
|
117
118
|
: existingScan.scanData || {};
|
|
118
119
|
}
|
|
119
120
|
catch (error) {
|
|
120
|
-
|
|
121
|
+
logger_js_1.logger.warn('Could not load existing scan data while updating scan');
|
|
121
122
|
existingScanData = {};
|
|
122
123
|
}
|
|
123
124
|
const i18nSetup = tms.getI18nSetup();
|
|
@@ -136,8 +137,7 @@ async function updateCurrentScan(folderName) {
|
|
|
136
137
|
});
|
|
137
138
|
}
|
|
138
139
|
catch (error) {
|
|
139
|
-
|
|
140
|
-
console.error('❌ Error stack:', error.stack);
|
|
140
|
+
logger_js_1.logger.error('Failed to update scan', error);
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
async function initTMS() {
|
|
@@ -176,7 +176,7 @@ async function initTMS() {
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
catch (e) {
|
|
179
|
-
|
|
179
|
+
logger_js_1.logger.warn('Failed to read ollang.config.ts, falling back to env/defaults');
|
|
180
180
|
}
|
|
181
181
|
const sourceLanguage = fileConfig.sourceLanguage || process.env.TMS_SOURCE_LANGUAGE || 'en';
|
|
182
182
|
const targetLanguages = fileConfig.targetLanguages ||
|
|
@@ -213,7 +213,7 @@ async function initTMS() {
|
|
|
213
213
|
},
|
|
214
214
|
});
|
|
215
215
|
if (!apiKey) {
|
|
216
|
-
|
|
216
|
+
logger_js_1.logger.warn('OLLANG_API_KEY not set. Translation features will not work.');
|
|
217
217
|
}
|
|
218
218
|
return tms;
|
|
219
219
|
}
|
|
@@ -260,7 +260,7 @@ app.get('/api/projects', async (req, res) => {
|
|
|
260
260
|
});
|
|
261
261
|
}
|
|
262
262
|
catch (error) {
|
|
263
|
-
|
|
263
|
+
logger_js_1.logger.error('Failed to load projects', error);
|
|
264
264
|
res.status(500).json({
|
|
265
265
|
success: false,
|
|
266
266
|
error: error.message,
|
|
@@ -288,7 +288,7 @@ app.post('/api/config/apikey', async (req, res) => {
|
|
|
288
288
|
if (!baseUrl) {
|
|
289
289
|
throw new Error('Base URL is not configured');
|
|
290
290
|
}
|
|
291
|
-
|
|
291
|
+
logger_js_1.logger.debug('Validating API key with base URL:', baseUrl);
|
|
292
292
|
const response = await fetch(`${baseUrl}/scans/folders`, {
|
|
293
293
|
method: 'GET',
|
|
294
294
|
headers: {
|
|
@@ -304,14 +304,14 @@ app.post('/api/config/apikey', async (req, res) => {
|
|
|
304
304
|
if (!folders || !Array.isArray(folders)) {
|
|
305
305
|
throw new Error('Invalid response from server while validating API key');
|
|
306
306
|
}
|
|
307
|
-
|
|
307
|
+
logger_js_1.logger.debug(`API key validated successfully. Accessible folders: ${folders.length}`);
|
|
308
308
|
res.json({
|
|
309
309
|
success: true,
|
|
310
310
|
message: 'API key validated and updated successfully',
|
|
311
311
|
});
|
|
312
312
|
}
|
|
313
313
|
catch (validationError) {
|
|
314
|
-
|
|
314
|
+
logger_js_1.logger.error('Test API key validation failed', validationError);
|
|
315
315
|
process.env.OLLANG_API_KEY = previousApiKey;
|
|
316
316
|
tms = await initTMS();
|
|
317
317
|
return res.status(401).json({
|
|
@@ -321,7 +321,7 @@ app.post('/api/config/apikey', async (req, res) => {
|
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
catch (error) {
|
|
324
|
-
|
|
324
|
+
logger_js_1.logger.error('Failed to update API key', error);
|
|
325
325
|
res.status(500).json({
|
|
326
326
|
success: false,
|
|
327
327
|
error: error.message,
|
|
@@ -376,7 +376,7 @@ app.post('/api/config/update', async (req, res) => {
|
|
|
376
376
|
});
|
|
377
377
|
}
|
|
378
378
|
catch (error) {
|
|
379
|
-
|
|
379
|
+
logger_js_1.logger.error('Failed to update config', error);
|
|
380
380
|
res.status(500).json({
|
|
381
381
|
success: false,
|
|
382
382
|
error: error.message,
|
|
@@ -491,7 +491,7 @@ app.post('/api/scan', async (req, res) => {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
catch (e) {
|
|
494
|
-
|
|
494
|
+
logger_js_1.logger.error('Could not load previous scans via listScans', e);
|
|
495
495
|
}
|
|
496
496
|
if (latestScanData && latestScanData.texts && folderState.currentScanId) {
|
|
497
497
|
const previousTextsMap = new Map(latestScanData.texts.map((t) => [t.id, t]));
|
|
@@ -558,7 +558,7 @@ app.post('/api/scan', async (req, res) => {
|
|
|
558
558
|
}
|
|
559
559
|
}
|
|
560
560
|
catch (saveError) {
|
|
561
|
-
|
|
561
|
+
logger_js_1.logger.error('Failed to save scan results', saveError);
|
|
562
562
|
}
|
|
563
563
|
const scanTime = new Date().toISOString();
|
|
564
564
|
res.json({
|
|
@@ -576,7 +576,7 @@ app.post('/api/scan', async (req, res) => {
|
|
|
576
576
|
});
|
|
577
577
|
}
|
|
578
578
|
catch (error) {
|
|
579
|
-
|
|
579
|
+
logger_js_1.logger.error('Scan error', error);
|
|
580
580
|
res.status(500).json({
|
|
581
581
|
success: false,
|
|
582
582
|
error: error.message,
|
|
@@ -615,7 +615,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
615
615
|
const sdk = tms.getSDK();
|
|
616
616
|
if (sdk && folderName) {
|
|
617
617
|
try {
|
|
618
|
-
|
|
618
|
+
logger_js_1.logger.debug(`Loading latest scan for folder: ${folderName}`);
|
|
619
619
|
// Get folderId from Ollang server's /api/folders endpoint
|
|
620
620
|
try {
|
|
621
621
|
const axios = require('axios');
|
|
@@ -624,11 +624,11 @@ app.post('/api/translate', async (req, res) => {
|
|
|
624
624
|
const targetFolder = folders.find((f) => f.name === folderName);
|
|
625
625
|
if (targetFolder && targetFolder.id) {
|
|
626
626
|
folderId = targetFolder.id;
|
|
627
|
-
|
|
627
|
+
logger_js_1.logger.debug(`Found folderId: ${folderId} for folder: ${folderName}`);
|
|
628
628
|
}
|
|
629
629
|
}
|
|
630
630
|
catch (folderError) {
|
|
631
|
-
|
|
631
|
+
logger_js_1.logger.warn('Could not get folders');
|
|
632
632
|
}
|
|
633
633
|
const scans = await sdk.scans.listScans();
|
|
634
634
|
// Find the latest scan for this folder
|
|
@@ -644,12 +644,12 @@ app.post('/api/translate', async (req, res) => {
|
|
|
644
644
|
: latestScan.scanData;
|
|
645
645
|
if (scanData.texts) {
|
|
646
646
|
folderState.texts = scanData.texts;
|
|
647
|
-
|
|
647
|
+
logger_js_1.logger.debug(`Loaded ${folderState.texts.length} items from folder ${folderName}`);
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
}
|
|
651
651
|
catch (error) {
|
|
652
|
-
|
|
652
|
+
logger_js_1.logger.warn('Could not load folder scan');
|
|
653
653
|
}
|
|
654
654
|
}
|
|
655
655
|
else if (sdk && folderState.currentScanId) {
|
|
@@ -659,19 +659,19 @@ app.post('/api/translate', async (req, res) => {
|
|
|
659
659
|
const scanData = typeof scan.scanData === 'string' ? JSON.parse(scan.scanData) : scan.scanData;
|
|
660
660
|
if (scanData.texts) {
|
|
661
661
|
folderState.texts = scanData.texts;
|
|
662
|
-
|
|
662
|
+
logger_js_1.logger.debug(`Reloaded ${folderState.texts.length} items from scan ${folderState.currentScanId}`);
|
|
663
663
|
}
|
|
664
664
|
}
|
|
665
665
|
catch (error) {
|
|
666
|
-
|
|
666
|
+
logger_js_1.logger.warn('Could not reload scan data, using cached currentTexts');
|
|
667
667
|
}
|
|
668
668
|
}
|
|
669
669
|
// Items are already grouped by entry (each entry = one item with cmsFields).
|
|
670
670
|
// Direct lookup by textIds is sufficient.
|
|
671
671
|
const selectedItems = folderState.texts.filter((t) => textIds.includes(t.id));
|
|
672
672
|
if (selectedItems.length === 0) {
|
|
673
|
-
|
|
674
|
-
|
|
673
|
+
logger_js_1.logger.debug(`No items found. Requested IDs: ${textIds.slice(0, 3).join(', ')}...`);
|
|
674
|
+
logger_js_1.logger.debug(`Available IDs: ${folderState.texts
|
|
675
675
|
.slice(0, 3)
|
|
676
676
|
.map((t) => t.id)
|
|
677
677
|
.join(', ')}...`);
|
|
@@ -685,15 +685,11 @@ app.post('/api/translate', async (req, res) => {
|
|
|
685
685
|
const videoItems = selectedItems.filter((item) => item.category === 'video');
|
|
686
686
|
const imageItems = selectedItems.filter((item) => item.category === 'image');
|
|
687
687
|
const audioItems = selectedItems.filter((item) => item.category === 'audio');
|
|
688
|
-
|
|
689
|
-
console.log(` - i18n texts: ${i18nItems.length}`);
|
|
690
|
-
console.log(` - Videos: ${videoItems.length}`);
|
|
691
|
-
console.log(` - Images: ${imageItems.length}`);
|
|
692
|
-
console.log(` - Audios: ${audioItems.length}`);
|
|
688
|
+
logger_js_1.logger.debug(`Translation breakdown: i18n=${i18nItems.length}, videos=${videoItems.length}, images=${imageItems.length}, audios=${audioItems.length}`);
|
|
693
689
|
// Log cmsFields info for entry-based items
|
|
694
690
|
for (const item of i18nItems) {
|
|
695
691
|
if (item.cmsFields) {
|
|
696
|
-
|
|
692
|
+
logger_js_1.logger.debug(`Entry ${item.id}: ${Object.keys(item.cmsFields).length} fields [${Object.keys(item.cmsFields).join(', ')}]`);
|
|
697
693
|
}
|
|
698
694
|
}
|
|
699
695
|
// Update all items to 'translating' status immediately (per language)
|
|
@@ -717,7 +713,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
717
713
|
await updateCurrentScan(folderName);
|
|
718
714
|
}
|
|
719
715
|
catch (saveError) {
|
|
720
|
-
|
|
716
|
+
logger_js_1.logger.error('Failed to save translating status', saveError);
|
|
721
717
|
}
|
|
722
718
|
// Return immediately with translating status
|
|
723
719
|
res.json({
|
|
@@ -737,7 +733,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
737
733
|
const primaryLang = languages[0];
|
|
738
734
|
if (i18nItems.length > 0) {
|
|
739
735
|
for (const lang of languages) {
|
|
740
|
-
|
|
736
|
+
logger_js_1.logger.debug(`Translating ${i18nItems.length} i18n texts to ${lang}...`);
|
|
741
737
|
try {
|
|
742
738
|
const order = await tms.translate(i18nItems, lang, level || 0, folderName, folderId);
|
|
743
739
|
const translations = tms.getTranslations();
|
|
@@ -793,18 +789,18 @@ app.post('/api/translate', async (req, res) => {
|
|
|
793
789
|
});
|
|
794
790
|
}
|
|
795
791
|
catch (error) {
|
|
796
|
-
|
|
792
|
+
logger_js_1.logger.error(`i18n translation error for lang ${lang}`, error);
|
|
797
793
|
}
|
|
798
794
|
}
|
|
799
795
|
}
|
|
800
796
|
if (videoItems.length > 0) {
|
|
801
|
-
|
|
797
|
+
logger_js_1.logger.debug(`Translating ${videoItems.length} videos to ${primaryLang}...`);
|
|
802
798
|
for (const item of videoItems) {
|
|
803
799
|
try {
|
|
804
800
|
const videoData = item._videoData;
|
|
805
801
|
if (videoData) {
|
|
806
802
|
const orderId = await tms.translateVideo(videoData, primaryLang, level || 0);
|
|
807
|
-
|
|
803
|
+
logger_js_1.logger.debug(`Video translation order created: ${orderId}`);
|
|
808
804
|
const textIndex = folderState.texts.findIndex((t) => t.id === item.id);
|
|
809
805
|
if (textIndex !== -1) {
|
|
810
806
|
folderState.texts[textIndex] = {
|
|
@@ -816,7 +812,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
816
812
|
}
|
|
817
813
|
}
|
|
818
814
|
catch (error) {
|
|
819
|
-
|
|
815
|
+
logger_js_1.logger.error(`Video translation error for ${item.id}`, error);
|
|
820
816
|
const textIndex = folderState.texts.findIndex((t) => t.id === item.id);
|
|
821
817
|
if (textIndex !== -1) {
|
|
822
818
|
folderState.texts[textIndex] = {
|
|
@@ -828,14 +824,14 @@ app.post('/api/translate', async (req, res) => {
|
|
|
828
824
|
}
|
|
829
825
|
}
|
|
830
826
|
if (imageItems.length > 0) {
|
|
831
|
-
|
|
827
|
+
logger_js_1.logger.debug(`Translating ${imageItems.length} images to ${primaryLang}...`);
|
|
832
828
|
for (const item of imageItems) {
|
|
833
829
|
try {
|
|
834
830
|
const imageData = item._imageData;
|
|
835
831
|
if (imageData) {
|
|
836
832
|
imageData.textItemId = item.id;
|
|
837
833
|
const orderId = await tms.translateImage(imageData, primaryLang, level || 0);
|
|
838
|
-
|
|
834
|
+
logger_js_1.logger.debug(`Image translation order created: ${orderId}`);
|
|
839
835
|
const textIndex = folderState.texts.findIndex((t) => t.id === item.id);
|
|
840
836
|
if (textIndex !== -1) {
|
|
841
837
|
folderState.texts[textIndex] = {
|
|
@@ -847,7 +843,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
847
843
|
}
|
|
848
844
|
}
|
|
849
845
|
catch (error) {
|
|
850
|
-
|
|
846
|
+
logger_js_1.logger.error(`Image translation error for ${item.id}`, error);
|
|
851
847
|
const textIndex = folderState.texts.findIndex((t) => t.id === item.id);
|
|
852
848
|
if (textIndex !== -1) {
|
|
853
849
|
folderState.texts[textIndex] = {
|
|
@@ -859,7 +855,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
859
855
|
}
|
|
860
856
|
}
|
|
861
857
|
if (audioItems.length > 0) {
|
|
862
|
-
|
|
858
|
+
logger_js_1.logger.debug(`Translating ${audioItems.length} audios to ${primaryLang}...`);
|
|
863
859
|
for (const item of audioItems) {
|
|
864
860
|
try {
|
|
865
861
|
const audioData = item._audioData;
|
|
@@ -876,7 +872,7 @@ app.post('/api/translate', async (req, res) => {
|
|
|
876
872
|
}
|
|
877
873
|
}
|
|
878
874
|
catch (error) {
|
|
879
|
-
|
|
875
|
+
logger_js_1.logger.error(`Audio translation error for ${item.id}`, error);
|
|
880
876
|
const textIndex = folderState.texts.findIndex((t) => t.id === item.id);
|
|
881
877
|
if (textIndex !== -1) {
|
|
882
878
|
folderState.texts[textIndex] = {
|
|
@@ -889,19 +885,19 @@ app.post('/api/translate', async (req, res) => {
|
|
|
889
885
|
}
|
|
890
886
|
try {
|
|
891
887
|
await updateCurrentScan(folderName);
|
|
892
|
-
|
|
888
|
+
logger_js_1.logger.debug('All translations completed and saved');
|
|
893
889
|
}
|
|
894
890
|
catch (saveError) {
|
|
895
|
-
|
|
891
|
+
logger_js_1.logger.warn('Failed to save translation statuses');
|
|
896
892
|
}
|
|
897
893
|
}
|
|
898
894
|
catch (error) {
|
|
899
|
-
|
|
895
|
+
logger_js_1.logger.error('Translation error', error);
|
|
900
896
|
}
|
|
901
897
|
})();
|
|
902
898
|
}
|
|
903
899
|
catch (error) {
|
|
904
|
-
|
|
900
|
+
logger_js_1.logger.error('Translation error', error);
|
|
905
901
|
res.status(500).json({
|
|
906
902
|
success: false,
|
|
907
903
|
error: error.message,
|
|
@@ -945,7 +941,7 @@ app.post('/api/apply', async (req, res) => {
|
|
|
945
941
|
}
|
|
946
942
|
}
|
|
947
943
|
catch (error) {
|
|
948
|
-
|
|
944
|
+
logger_js_1.logger.error('Could not load folder scan', error);
|
|
949
945
|
}
|
|
950
946
|
}
|
|
951
947
|
let translations = tms.getTranslations();
|
|
@@ -995,20 +991,19 @@ app.post('/api/apply', async (req, res) => {
|
|
|
995
991
|
let updatedFiles = 0;
|
|
996
992
|
let strapiResults = { pushed: 0, failed: 0 };
|
|
997
993
|
if (fileItems.length > 0) {
|
|
998
|
-
|
|
994
|
+
logger_js_1.logger.debug(`Applying ${fileItems.length} file-based translations...`);
|
|
999
995
|
tms['state'].texts = folderState.texts;
|
|
1000
996
|
updatedFiles = await tms.applyTranslations(targetLanguage, fileItems);
|
|
1001
|
-
|
|
997
|
+
logger_js_1.logger.debug(`Updated ${updatedFiles} files`);
|
|
1002
998
|
}
|
|
1003
999
|
if (cmsEntryItems.length > 0) {
|
|
1004
1000
|
const strapiUrl = reqStrapiUrl || process.env.STRAPI_URL || process.env.STRAPI_BASE_URL || '';
|
|
1005
1001
|
const strapiToken = effectiveStrapiToken || process.env.STRAPI_TOKEN || process.env.STRAPI_API_TOKEN || '';
|
|
1006
1002
|
if (!strapiUrl || !strapiToken) {
|
|
1007
|
-
|
|
1008
|
-
console.warn(' Set: STRAPI_URL=https://cms.ollang.com STRAPI_TOKEN=your-token');
|
|
1003
|
+
logger_js_1.logger.warn('STRAPI_URL and STRAPI_TOKEN env vars required for CMS push. Skipping Strapi push.');
|
|
1009
1004
|
}
|
|
1010
1005
|
else {
|
|
1011
|
-
|
|
1006
|
+
logger_js_1.logger.debug(`Pushing ${cmsEntryItems.length} CMS entries to Strapi (${strapiUrl})...`);
|
|
1012
1007
|
const pusher = new strapi_pusher_js_1.StrapiPusher({ strapiUrl, strapiToken });
|
|
1013
1008
|
const strapiTranslations = [];
|
|
1014
1009
|
for (const item of cmsEntryItems) {
|
|
@@ -1051,7 +1046,7 @@ app.post('/api/apply', async (req, res) => {
|
|
|
1051
1046
|
errors: result.errors,
|
|
1052
1047
|
};
|
|
1053
1048
|
if (result.errors.length > 0) {
|
|
1054
|
-
|
|
1049
|
+
logger_js_1.logger.error('Strapi push errors encountered');
|
|
1055
1050
|
}
|
|
1056
1051
|
}
|
|
1057
1052
|
}
|
|
@@ -1080,7 +1075,7 @@ app.post('/api/apply', async (req, res) => {
|
|
|
1080
1075
|
await updateCurrentScan(folderName);
|
|
1081
1076
|
}
|
|
1082
1077
|
catch (saveError) {
|
|
1083
|
-
|
|
1078
|
+
logger_js_1.logger.error('Failed to save apply statuses', saveError);
|
|
1084
1079
|
}
|
|
1085
1080
|
const appliedCount = appliedTextIds.length;
|
|
1086
1081
|
res.json({
|
|
@@ -1094,7 +1089,7 @@ app.post('/api/apply', async (req, res) => {
|
|
|
1094
1089
|
});
|
|
1095
1090
|
}
|
|
1096
1091
|
catch (error) {
|
|
1097
|
-
|
|
1092
|
+
logger_js_1.logger.error('Apply error', error);
|
|
1098
1093
|
res.status(500).json({
|
|
1099
1094
|
success: false,
|
|
1100
1095
|
error: error.message,
|
|
@@ -1120,7 +1115,7 @@ function getOllangBackendBase() {
|
|
|
1120
1115
|
backendBase = tms.getConfig().ollang.baseUrl || '';
|
|
1121
1116
|
}
|
|
1122
1117
|
if (!backendBase) {
|
|
1123
|
-
backendBase = '
|
|
1118
|
+
backendBase = 'https://api-integration.ollang.com';
|
|
1124
1119
|
}
|
|
1125
1120
|
backendBase = backendBase.replace(/\/$/, '');
|
|
1126
1121
|
try {
|
|
@@ -1129,13 +1124,13 @@ function getOllangBackendBase() {
|
|
|
1129
1124
|
const extraHosts = (process.env.OLLANG_ALLOWED_HOSTS || '').split(',').filter(Boolean);
|
|
1130
1125
|
extraHosts.forEach((h) => allowedHosts.add(h.trim()));
|
|
1131
1126
|
if (!allowedHosts.has(parsed.hostname)) {
|
|
1132
|
-
|
|
1133
|
-
return '
|
|
1127
|
+
logger_js_1.logger.warn(`Backend URL hostname "${parsed.hostname}" not in allowlist, using default`);
|
|
1128
|
+
return 'https://api-integration.ollang.com';
|
|
1134
1129
|
}
|
|
1135
1130
|
}
|
|
1136
1131
|
catch {
|
|
1137
|
-
|
|
1138
|
-
return '
|
|
1132
|
+
logger_js_1.logger.warn('Invalid backend URL format, using default');
|
|
1133
|
+
return 'https://api-integration.ollang.com';
|
|
1139
1134
|
}
|
|
1140
1135
|
return backendBase;
|
|
1141
1136
|
}
|
|
@@ -1154,7 +1149,7 @@ app.get('/scans/folders', async (req, res) => {
|
|
|
1154
1149
|
res.status(response.status).json(data);
|
|
1155
1150
|
}
|
|
1156
1151
|
catch (error) {
|
|
1157
|
-
|
|
1152
|
+
logger_js_1.logger.error('/scans/folders proxy error', error);
|
|
1158
1153
|
res.status(500).json({
|
|
1159
1154
|
success: false,
|
|
1160
1155
|
error: error?.message || 'Failed to reach Ollang API',
|
|
@@ -1178,7 +1173,7 @@ app.get('/scans', async (req, res) => {
|
|
|
1178
1173
|
res.status(response.status).json(data);
|
|
1179
1174
|
}
|
|
1180
1175
|
catch (error) {
|
|
1181
|
-
|
|
1176
|
+
logger_js_1.logger.error('GET /scans proxy error', error);
|
|
1182
1177
|
res.status(500).json({
|
|
1183
1178
|
success: false,
|
|
1184
1179
|
error: error?.message || 'Failed to reach Ollang API',
|
|
@@ -1201,7 +1196,7 @@ app.post('/scans', async (req, res) => {
|
|
|
1201
1196
|
res.status(response.status).json(data);
|
|
1202
1197
|
}
|
|
1203
1198
|
catch (error) {
|
|
1204
|
-
|
|
1199
|
+
logger_js_1.logger.error('POST /scans proxy error', error);
|
|
1205
1200
|
res.status(500).json({
|
|
1206
1201
|
success: false,
|
|
1207
1202
|
error: error?.message || 'Failed to reach Ollang API',
|
|
@@ -1231,7 +1226,7 @@ app.patch('/scans/:id', async (req, res) => {
|
|
|
1231
1226
|
res.status(response.status).json(data);
|
|
1232
1227
|
}
|
|
1233
1228
|
catch (error) {
|
|
1234
|
-
|
|
1229
|
+
logger_js_1.logger.error('PATCH /scans/:id proxy error', error);
|
|
1235
1230
|
res.status(500).json({
|
|
1236
1231
|
success: false,
|
|
1237
1232
|
error: error?.message || 'Failed to reach Ollang API',
|
|
@@ -1270,8 +1265,7 @@ app.get('/api/folders', async (req, res) => {
|
|
|
1270
1265
|
});
|
|
1271
1266
|
}
|
|
1272
1267
|
catch (error) {
|
|
1273
|
-
|
|
1274
|
-
console.error('❌ Error details:', error.response?.data);
|
|
1268
|
+
logger_js_1.logger.error('Failed to load folders', error);
|
|
1275
1269
|
res.status(500).json({
|
|
1276
1270
|
success: false,
|
|
1277
1271
|
error: error.message,
|
|
@@ -1299,7 +1293,7 @@ app.get('/api/scans', async (req, res) => {
|
|
|
1299
1293
|
});
|
|
1300
1294
|
}
|
|
1301
1295
|
catch (error) {
|
|
1302
|
-
|
|
1296
|
+
logger_js_1.logger.warn('Could not load folders for mapping');
|
|
1303
1297
|
}
|
|
1304
1298
|
const scansWithFolderName = scans.map((scan) => {
|
|
1305
1299
|
const scanData = typeof scan.scanData === 'string' ? JSON.parse(scan.scanData) : scan.scanData;
|
|
@@ -1333,7 +1327,7 @@ app.get('/api/scans', async (req, res) => {
|
|
|
1333
1327
|
});
|
|
1334
1328
|
}
|
|
1335
1329
|
catch (error) {
|
|
1336
|
-
|
|
1330
|
+
logger_js_1.logger.error('Failed to load scans', error);
|
|
1337
1331
|
res.status(500).json({
|
|
1338
1332
|
success: false,
|
|
1339
1333
|
error: error.message,
|
|
@@ -1374,7 +1368,7 @@ app.get('/api/scans/:scanId', async (req, res) => {
|
|
|
1374
1368
|
});
|
|
1375
1369
|
}
|
|
1376
1370
|
catch (error) {
|
|
1377
|
-
|
|
1371
|
+
logger_js_1.logger.error('Failed to load scan', error);
|
|
1378
1372
|
res.status(500).json({
|
|
1379
1373
|
success: false,
|
|
1380
1374
|
error: error.message,
|
|
@@ -1428,7 +1422,7 @@ app.post('/api/strapi-schema', async (req, res) => {
|
|
|
1428
1422
|
});
|
|
1429
1423
|
}
|
|
1430
1424
|
catch (error) {
|
|
1431
|
-
|
|
1425
|
+
logger_js_1.logger.error('Strapi schema fetch failed', error);
|
|
1432
1426
|
return res.status(500).json({
|
|
1433
1427
|
success: false,
|
|
1434
1428
|
error: error?.message || 'Failed to fetch Strapi schema',
|
|
@@ -1462,12 +1456,12 @@ app.get('*', (_req, res) => {
|
|
|
1462
1456
|
res.sendFile(path_1.default.join(__dirname, '../ui-dist/index.html'));
|
|
1463
1457
|
});
|
|
1464
1458
|
app.listen(PORT, () => {
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1459
|
+
logger_js_1.logger.info('🚀 Translation Management System starting...');
|
|
1460
|
+
logger_js_1.logger.info(`📦 Project: ${PROJECT_ROOT}`);
|
|
1461
|
+
logger_js_1.logger.info(`🌐 Control panel: http://localhost:${PORT}`);
|
|
1462
|
+
logger_js_1.logger.info(`💡 Opening in your browser...`);
|
|
1463
|
+
logger_js_1.logger.info(` If not opened: http://localhost:${PORT}`);
|
|
1464
|
+
logger_js_1.logger.info(`⌨️ To stop: Ctrl+C\n`);
|
|
1471
1465
|
const open = require('open');
|
|
1472
1466
|
open(`http://localhost:${PORT}`).catch(() => { });
|
|
1473
1467
|
});
|