@l10nmonster/helpers-lqaboss 3.0.0-alpha.8 → 3.1.0
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/.releaserc.json +1 -1
- package/CHANGELOG.md +20 -0
- package/flowCapture.js +3 -6
- package/index.js +1 -0
- package/lqabossProvider.js +31 -19
- package/lqabossRoutes.js +28 -0
- package/lqabossTmStore.js +7 -3
- package/package.json +2 -2
package/.releaserc.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
# @l10nmonster/helpers-lqaboss [3.1.0](https://public-github/l10nmonster/l10nmonster/compare/@l10nmonster/helpers-lqaboss@3.0.0...@l10nmonster/helpers-lqaboss@3.1.0) (2025-12-20)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Calibrate log severities ([2b3350a](https://public-github/l10nmonster/l10nmonster/commit/2b3350a3123abb91e7f91a9c1864daeb6275c3ad))
|
|
7
|
+
* **helpers-lqaboss:** Fix typo ([209dd07](https://public-github/l10nmonster/l10nmonster/commit/209dd071724c6f15464a1be0ebf140f23efc3f56))
|
|
8
|
+
* **helpers-lqaboss:** Move lqaboss ingestion to tm syncdown ([ebda63f](https://public-github/l10nmonster/l10nmonster/commit/ebda63f3b1651b44265ba62ce0f4ff876e9c97ed))
|
|
9
|
+
* **helpers-lqaboss:** Relax LQABossTmStore glob to allow for custom flow names ([5568c81](https://public-github/l10nmonster/l10nmonster/commit/5568c81d55f07c95d4af337904bc0367f5f71d68))
|
|
10
|
+
* **helpers-lqaboss:** Support old jobs without updatedAt property ([7c8cf75](https://public-github/l10nmonster/l10nmonster/commit/7c8cf759dfe9df379f537ef8a278b76949c19783))
|
|
11
|
+
* **lqaboss:** Support new response type ([ecaec02](https://public-github/l10nmonster/l10nmonster/commit/ecaec029b509d88267ac66374c5993c1537737c0))
|
|
12
|
+
* **server:** Fix cart cleanup ([9bbcab9](https://public-github/l10nmonster/l10nmonster/commit/9bbcab93e1fd20aeb09f59c828665159f091f37c))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **core:** Major refactor ([6992ee4](https://public-github/l10nmonster/l10nmonster/commit/6992ee4d74ad2e25afef6220f92f2e72dfd02457))
|
|
18
|
+
* Improve LQA Boss ([fcb0818](https://public-github/l10nmonster/l10nmonster/commit/fcb0818181f1a7bd46764596c9d2b8d8f362375c))
|
|
19
|
+
* **lqaboss:** Support for new Chrome extension ([dc6f86f](https://public-github/l10nmonster/l10nmonster/commit/dc6f86f417dde5e5942bdad2c81c0fbbac59fb80))
|
|
20
|
+
|
|
1
21
|
# Changelog
|
|
2
22
|
|
|
3
23
|
All notable changes to this project will be documented in this file.
|
package/flowCapture.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable complexity */
|
|
1
2
|
import JSZip from 'jszip';
|
|
2
3
|
import puppeteer from 'puppeteer';
|
|
3
4
|
import { logInfo, logVerbose } from '@l10nmonster/core';
|
|
@@ -24,7 +25,7 @@ async function extractTextAndMetadataInPageContext() {
|
|
|
24
25
|
|
|
25
26
|
const textElements = [];
|
|
26
27
|
const START_MARKER_REGEX = /(?<![''<])\u200B([\uFE00-\uFE0F]+)/g;
|
|
27
|
-
const END_MARKER = '\
|
|
28
|
+
const END_MARKER = '\u200C';
|
|
28
29
|
|
|
29
30
|
if (!document.body) {
|
|
30
31
|
return { error: 'Document body not found.' };
|
|
@@ -221,12 +222,8 @@ export class FlowSnapshotter {
|
|
|
221
222
|
const job = {
|
|
222
223
|
sourceLang: tm.sourceLang,
|
|
223
224
|
targetLang: tm.targetLang,
|
|
224
|
-
tus:
|
|
225
|
+
tus: Object.values(await tm.getEntries(Array.from(guids))),
|
|
225
226
|
};
|
|
226
|
-
guids.forEach(guid => {
|
|
227
|
-
const tu = tm.getEntryByGuid(guid);
|
|
228
|
-
tu && job.tus.push(tu);
|
|
229
|
-
});
|
|
230
227
|
if (job.tus.length > 0) {
|
|
231
228
|
zip.file('job.json', JSON.stringify(job, null, 2));
|
|
232
229
|
}
|
package/index.js
CHANGED
package/lqabossProvider.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import JSZip from 'jszip';
|
|
2
|
-
import
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { providers, logVerbose, styleString, opsManager, getBaseDir } from '@l10nmonster/core';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* @typedef {object} LQABossProviderOptions
|
|
6
8
|
* @extends BaseTranslationProvider
|
|
7
9
|
* @property {Object} delegate - Required file store delegate implementing file operations
|
|
10
|
+
* @property {string} [urlPrefix] - Prefix for the LQA Boss URL
|
|
11
|
+
* @property {string} [qualityFile] - Path to a quality model JSON file
|
|
8
12
|
*/
|
|
9
13
|
|
|
10
14
|
/**
|
|
@@ -12,15 +16,19 @@ import { providers, logVerbose, styleString, opsManager } from '@l10nmonster/cor
|
|
|
12
16
|
*/
|
|
13
17
|
export class LQABossProvider extends providers.BaseTranslationProvider {
|
|
14
18
|
#storageDelegate;
|
|
19
|
+
urlPrefix;
|
|
20
|
+
#qualityFilePath;
|
|
15
21
|
#opNames = {};
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* Initializes a new instance of the LQABossProvider class.
|
|
19
25
|
* @param {LQABossProviderOptions} options - Configuration options for the provider.
|
|
20
26
|
*/
|
|
21
|
-
constructor({ delegate, ...options }) {
|
|
27
|
+
constructor({ delegate, urlPrefix, qualityFile, ...options }) {
|
|
22
28
|
super(options);
|
|
23
29
|
this.#storageDelegate = delegate;
|
|
30
|
+
this.urlPrefix = urlPrefix;
|
|
31
|
+
qualityFile && (this.#qualityFilePath = path.resolve(getBaseDir(), qualityFile));
|
|
24
32
|
this.#opNames.startReviewOp = `${this.id}.startReviewOp`;
|
|
25
33
|
opsManager.registerOp(this.startReviewOp.bind(this), { opName: this.#opNames.startReviewOp, idempotent: false });
|
|
26
34
|
}
|
|
@@ -31,26 +39,30 @@ export class LQABossProvider extends providers.BaseTranslationProvider {
|
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
async startReviewOp(op) {
|
|
34
|
-
const
|
|
42
|
+
const filename = op.args.job.jobName ?
|
|
43
|
+
`${op.args.job.jobName.replace(/\s+/g, '_')}-${op.args.job.jobGuid.substring(0, 5)}.lqaboss` :
|
|
44
|
+
`${op.args.job.jobGuid}.lqaboss`;
|
|
45
|
+
const jobRequest = {
|
|
46
|
+
...op.args.job,
|
|
47
|
+
statusDescription: `Created LQA Boss file ${this.urlPrefix ? `at ${this.urlPrefix}/${filename}` : `: ${filename}`}`,
|
|
48
|
+
providerData: { quality: this.quality },
|
|
49
|
+
};
|
|
35
50
|
const zip = new JSZip();
|
|
36
|
-
zip.file('job.json', JSON.stringify(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
ntgt: tu.ntgt,
|
|
45
|
-
q: this.quality,
|
|
46
|
-
})),
|
|
47
|
-
}, null, 2));
|
|
51
|
+
zip.file('job.json', JSON.stringify(jobRequest, null, 2));
|
|
52
|
+
|
|
53
|
+
// Add quality model if configured
|
|
54
|
+
if (this.#qualityFilePath) {
|
|
55
|
+
const qualityModel = JSON.parse(readFileSync(this.#qualityFilePath, 'utf-8'));
|
|
56
|
+
zip.file('quality.json', JSON.stringify(qualityModel, null, 2));
|
|
57
|
+
}
|
|
58
|
+
|
|
48
59
|
const buffer = await zip.generateAsync({ type: 'nodebuffer', compression: 'DEFLATE', compressionOptions: { level: 6 } });
|
|
49
|
-
const filename = `${jobResponse.jobGuid}.lqaboss`;
|
|
50
60
|
await this.#storageDelegate.saveFile(filename, buffer);
|
|
51
|
-
logVerbose`Saved LQABoss file ${filename} with ${tus.length} guids and ${buffer.length} bytes`;
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
logVerbose`Saved LQABoss file ${filename} with ${jobRequest.tus.length} guids and ${buffer.length} bytes`;
|
|
62
|
+
return {
|
|
63
|
+
...jobRequest,
|
|
64
|
+
tus: [], // remove tus so that job is cancelled and won't be stored
|
|
65
|
+
};
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
async info() {
|
package/lqabossRoutes.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { logInfo, logVerbose, logWarn } from '@l10nmonster/core';
|
|
2
|
+
|
|
3
|
+
export function createLQABossRoutes(mm) {
|
|
4
|
+
return [
|
|
5
|
+
['post', '/lookup', async (req, res) => {
|
|
6
|
+
logInfo`LQABossRoute:/lookup`;
|
|
7
|
+
try {
|
|
8
|
+
const { sourceLang, targetLang, segments } = req.body;
|
|
9
|
+
const tm = mm.tmm.getTM(sourceLang, targetLang);
|
|
10
|
+
const guids = new Set(segments.map(segment => segment.g));
|
|
11
|
+
let tus = [];
|
|
12
|
+
if (guids.size > 0) {
|
|
13
|
+
tus = await tm.queryByGuids(Array.from(guids));
|
|
14
|
+
}
|
|
15
|
+
const guidMap = new Map(tus.map(tu => [ tu.guid, tu ]));
|
|
16
|
+
const results = segments.map(segment => guidMap.get(segment.g) ?? {});
|
|
17
|
+
logVerbose`Matched ${tus.length} segments out of ${guids.size}`;
|
|
18
|
+
res.json({ results });
|
|
19
|
+
} catch (error) {
|
|
20
|
+
logWarn`Error in LQABossRoute:/lookup: ${error.message}`;
|
|
21
|
+
res.status(500).json({
|
|
22
|
+
error: 'Failed to lookup translation memory',
|
|
23
|
+
message: error.message
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}]
|
|
27
|
+
]
|
|
28
|
+
}
|
package/lqabossTmStore.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { utils } from '@l10nmonster/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapter class to expose LQABoss completion files as a TM store.
|
|
@@ -39,9 +39,13 @@ export class LQABossTmStore {
|
|
|
39
39
|
this.#tm = {};
|
|
40
40
|
const files = await this.#storageDelegate.listAllFiles();
|
|
41
41
|
for (const [ fileName ] of files) {
|
|
42
|
-
if (fileName.
|
|
42
|
+
if (fileName.endsWith('.json')) {
|
|
43
43
|
const job = JSON.parse(await this.#storageDelegate.getFile(fileName));
|
|
44
|
-
|
|
44
|
+
if (!job.sourceLang || !job.targetLang || !job.jobGuid) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
!job.updatedAt && (job.updatedAt = '2025-08-29T21:29:36.269Z'); // workaround for old jobs that don't have an updatedAt
|
|
48
|
+
const ts = new Date(job.updatedAt).getTime();
|
|
45
49
|
job.tus = job.tus.map(tu => ({ ...tu, ts }));
|
|
46
50
|
this.#tm[job.sourceLang] ??= {};
|
|
47
51
|
this.#tm[job.sourceLang][job.targetLang] ??= {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@l10nmonster/helpers-lqaboss",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "LQA Boss helper for L10n Monster",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
"puppeteer": "^24"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@l10nmonster/core": "
|
|
16
|
+
"@l10nmonster/core": "3.1.0"
|
|
17
17
|
}
|
|
18
18
|
}
|