n8n-nodes-fasttext-language-detector 0.1.1 → 0.1.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.
@@ -195,9 +195,40 @@ class FastTextLanguageDetector {
195
195
  }
196
196
  // Динамически загружаем fasttext.js только когда он нужен
197
197
  // Это предотвращает загрузку WASM при старте n8n
198
- const fastText = await Promise.resolve().then(() => __importStar(require('fasttext.js')));
199
- model = new fastText.Classifier(modelPath);
200
- FastTextLanguageDetector.modelCache.set(modelPath, model);
198
+ // Используем require для CommonJS модуля, обернутый в Promise
199
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires
200
+ const fastTextModule = await new Promise((resolve, reject) => {
201
+ try {
202
+ // Используем require для загрузки CommonJS модуля
203
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
204
+ const FastText = require('fasttext.js');
205
+ resolve(FastText);
206
+ }
207
+ catch (error) {
208
+ reject(error);
209
+ }
210
+ });
211
+ // fasttext.js экспортирует класс FastText напрямую
212
+ const FastTextClass = fastTextModule ||
213
+ fastTextModule.default ||
214
+ (fastTextModule.default && fastTextModule.default.default);
215
+ if (!FastTextClass || typeof FastTextClass !== 'function') {
216
+ const availableExports = Object.keys(fastTextModule).join(', ');
217
+ throw new n8n_workflow_1.ApplicationError(`Failed to load fastText module: FastText class not found. Available exports: ${availableExports}`, { level: 'error' });
218
+ }
219
+ // Создаем экземпляр FastText с путем к модели
220
+ const fastTextInstance = new FastTextClass({
221
+ loadModel: modelPath,
222
+ predict: {
223
+ mostlikely: topK,
224
+ verbosity: 0,
225
+ normalize: false
226
+ }
227
+ });
228
+ // Загружаем модель
229
+ await fastTextInstance.load();
230
+ model = fastTextInstance;
231
+ FastTextLanguageDetector.modelCache.set(modelPath, fastTextInstance);
201
232
  }
202
233
  }
203
234
  catch (error) {
@@ -243,19 +274,48 @@ class FastTextLanguageDetector {
243
274
  throw new n8n_workflow_1.ApplicationError('Model not initialized', { level: 'error' });
244
275
  }
245
276
  // Определяем язык
246
- const predictions = await model.predict(processedText, topK);
277
+ // fasttext.js возвращает массив массивов [label, probability] или массив объектов
278
+ const predictionsRaw = await model.predict(processedText);
279
+ if (!Array.isArray(predictionsRaw) || predictionsRaw.length === 0) {
280
+ throw new n8n_workflow_1.ApplicationError('No predictions returned from fastText model', { level: 'error' });
281
+ }
282
+ // Преобразуем формат ответа fasttext.js в наш формат
283
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
284
+ const predictions = predictionsRaw.map((pred) => {
285
+ // fasttext.js возвращает либо [label, value], либо объект
286
+ let label;
287
+ let probability;
288
+ if (Array.isArray(pred)) {
289
+ label = String(pred[0] || '');
290
+ probability = Number(pred[1] || 0);
291
+ }
292
+ else if (pred && typeof pred === 'object') {
293
+ label = String(pred.label || pred[0] || '');
294
+ probability = Number(pred.value || pred.probability || pred[1] || 0);
295
+ }
296
+ else {
297
+ label = String(pred || '');
298
+ probability = 0;
299
+ }
300
+ // Убираем префикс __label__ если есть
301
+ const cleanLabel = label.replace(/^__label__/, '');
302
+ return {
303
+ label: cleanLabel,
304
+ probability: probability
305
+ };
306
+ });
247
307
  // Фильтруем по порогу уверенности
248
308
  const filteredPredictions = predictions.filter((pred) => pred.probability >= confidenceThreshold);
249
309
  if (filteredPredictions.length === 0) {
250
310
  // Если нет предсказаний выше порога, возвращаем лучшее
251
311
  const result = {
252
312
  ...json,
253
- [outputField]: predictions[0]?.label?.replace('__label__', '') || 'unknown',
313
+ [outputField]: predictions[0]?.label || 'unknown',
254
314
  };
255
315
  if (includeConfidence) {
256
316
  result[`${outputField}Confidence`] = predictions[0]?.probability || 0;
257
317
  result[`${outputField}All`] = predictions.map((p) => ({
258
- language: p.label?.replace('__label__', '') || 'unknown',
318
+ language: p.label || 'unknown',
259
319
  confidence: p.probability || 0,
260
320
  }));
261
321
  }
@@ -266,7 +326,7 @@ class FastTextLanguageDetector {
266
326
  const topPrediction = filteredPredictions[0];
267
327
  const result = {
268
328
  ...json,
269
- [outputField]: topPrediction.label?.replace('__label__', '') || 'unknown',
329
+ [outputField]: topPrediction.label || 'unknown',
270
330
  };
271
331
  if (includeConfidence) {
272
332
  result[`${outputField}Confidence`] = topPrediction.probability || 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-fasttext-language-detector",
3
- "version": "0.1.1",
3
+ "version": "0.1.5",
4
4
  "description": "n8n node for language detection using fastText",
5
5
  "author": {
6
6
  "name": "Your Name",