langsys-js-typescript 0.4.1 → 0.4.2
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/CHANGELOG.md +7 -0
- package/README.md +10 -0
- package/dist/index.d.mts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +55 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +55 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -266,6 +266,25 @@ var ICU_PATTERN = /\{[^{}]+,\s*(plural|select|selectordinal|number|date|time)\s*
|
|
|
266
266
|
function normalizeMarkupPlaceholders(text) {
|
|
267
267
|
return text.replace(/%([A-Za-z_][A-Za-z0-9_]*)%/g, "{$1}");
|
|
268
268
|
}
|
|
269
|
+
function escapeForRegExp(key) {
|
|
270
|
+
return key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
271
|
+
}
|
|
272
|
+
function findUnusedParamKeys(texts, params) {
|
|
273
|
+
if (!params) return [];
|
|
274
|
+
const keys = Object.keys(params);
|
|
275
|
+
if (!keys.length || !texts.length) return keys;
|
|
276
|
+
const haystack = texts.join("\0");
|
|
277
|
+
return keys.filter((key) => !new RegExp(`\\{\\s*${escapeForRegExp(key)}\\s*[,}]`).test(haystack));
|
|
278
|
+
}
|
|
279
|
+
function warnUnmatchedParams(source, texts, params, context) {
|
|
280
|
+
if (!logger.debugEnabled) return;
|
|
281
|
+
const unused = findUnusedParamKeys(texts, params);
|
|
282
|
+
if (!unused.length) return;
|
|
283
|
+
const keyList = unused.map((key) => `%${key}%`).join(", ");
|
|
284
|
+
logger.warn(
|
|
285
|
+
`${source} received params with no matching placeholder in its content: ${keyList}. If you wrote {${unused[0]}} in markup, the framework compiler (Svelte/JSX) substituted it before Langsys saw the text \u2014 write %${unused[0]}% instead.` + (context ? ` [${context}]` : "")
|
|
286
|
+
);
|
|
287
|
+
}
|
|
269
288
|
function interpolate(template, params, locale) {
|
|
270
289
|
if (isICU(template)) {
|
|
271
290
|
try {
|
|
@@ -1246,6 +1265,8 @@ var Translate = class {
|
|
|
1246
1265
|
this.isTokenizing = false;
|
|
1247
1266
|
this.lastTranslatedLocale = "";
|
|
1248
1267
|
this.unsubscribeLocale = null;
|
|
1268
|
+
/** Sorted params key-set already checked, so value-only updates don't re-warn. */
|
|
1269
|
+
this.checkedParamKeys = null;
|
|
1249
1270
|
this.element = element;
|
|
1250
1271
|
this.options = { ...options };
|
|
1251
1272
|
this.custom_id = options.custom_id || "";
|
|
@@ -1257,6 +1278,7 @@ var Translate = class {
|
|
|
1257
1278
|
/** Update interpolation params (e.g. a changed count) and re-render. Mirrors `Phrase.setParams`. */
|
|
1258
1279
|
setParams(params) {
|
|
1259
1280
|
this.options.params = params;
|
|
1281
|
+
this.checkParams();
|
|
1260
1282
|
if (!this.parseComplete) return;
|
|
1261
1283
|
this.lastTranslatedLocale = "";
|
|
1262
1284
|
const locale = currentlyLoadedLocale.get();
|
|
@@ -1290,6 +1312,7 @@ var Translate = class {
|
|
|
1290
1312
|
this.isTokenizing = true;
|
|
1291
1313
|
const { tokens, content } = tokenizeElement(this.element);
|
|
1292
1314
|
this.tokens = tokens;
|
|
1315
|
+
this.checkParams();
|
|
1293
1316
|
const { category = "" } = this.options;
|
|
1294
1317
|
if (this.tokens.length === 1) {
|
|
1295
1318
|
this.element.innerText = this.applyParams(LangsysApp.Translations.t(this.tokens[0], category));
|
|
@@ -1363,6 +1386,19 @@ var Translate = class {
|
|
|
1363
1386
|
const { category = "" } = this.options;
|
|
1364
1387
|
return LangsysApp.Translations.lookupContent(category, this.custom_id, token);
|
|
1365
1388
|
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Debug-time check that every supplied param has a placeholder to land in.
|
|
1391
|
+
* Re-runs only when the key SET changes — a changing `count` value must not
|
|
1392
|
+
* re-warn on every render.
|
|
1393
|
+
*/
|
|
1394
|
+
checkParams() {
|
|
1395
|
+
if (!this.tokens.length) return;
|
|
1396
|
+
const { params, category = "" } = this.options;
|
|
1397
|
+
const signature = params ? Object.keys(params).sort().join(",") : "";
|
|
1398
|
+
if (signature === this.checkedParamKeys) return;
|
|
1399
|
+
this.checkedParamKeys = signature;
|
|
1400
|
+
warnUnmatchedParams("<Translate>", this.tokens, params, category || void 0);
|
|
1401
|
+
}
|
|
1366
1402
|
/**
|
|
1367
1403
|
* Interpolate `{name}`-style params into a resolved text, matching `t()`:
|
|
1368
1404
|
* unknown keys fall through untouched, and the untranslated fallback is
|
|
@@ -1497,6 +1533,8 @@ var Phrase = class {
|
|
|
1497
1533
|
this.slots = [];
|
|
1498
1534
|
this.unsubscribers = [];
|
|
1499
1535
|
this.ready = false;
|
|
1536
|
+
/** Sorted params key-set already checked, so value-only updates don't re-warn. */
|
|
1537
|
+
this.checkedParamKeys = null;
|
|
1500
1538
|
this.host = host;
|
|
1501
1539
|
this.category = options.category ?? "";
|
|
1502
1540
|
this.params = options.params ?? {};
|
|
@@ -1510,7 +1548,9 @@ var Phrase = class {
|
|
|
1510
1548
|
/** Update interpolation params (e.g. a changed count) and re-render. */
|
|
1511
1549
|
setParams(params) {
|
|
1512
1550
|
this.params = params ?? {};
|
|
1513
|
-
|
|
1551
|
+
this._checkParams();
|
|
1552
|
+
if (!this.ready) return;
|
|
1553
|
+
this._render();
|
|
1514
1554
|
}
|
|
1515
1555
|
/** Stop reacting to locale/translation changes. Safe to call multiple times. */
|
|
1516
1556
|
destroy() {
|
|
@@ -1525,11 +1565,24 @@ var Phrase = class {
|
|
|
1525
1565
|
const { phrase, slots } = encodeRichText(this.host);
|
|
1526
1566
|
this.phrase = phrase;
|
|
1527
1567
|
this.slots = slots;
|
|
1568
|
+
this._checkParams();
|
|
1528
1569
|
await LangsysApp.Translations.ready();
|
|
1529
1570
|
LangsysApp.Translations.t(this.phrase, this.category);
|
|
1530
1571
|
this.ready = true;
|
|
1531
1572
|
this._render();
|
|
1532
1573
|
}
|
|
1574
|
+
/**
|
|
1575
|
+
* Debug-time check that every supplied param has a placeholder to land in.
|
|
1576
|
+
* Re-runs only when the key SET changes — a changing `n` value must not
|
|
1577
|
+
* re-warn on every render.
|
|
1578
|
+
*/
|
|
1579
|
+
_checkParams() {
|
|
1580
|
+
if (!this.phrase) return;
|
|
1581
|
+
const signature = Object.keys(this.params).sort().join(",");
|
|
1582
|
+
if (signature === this.checkedParamKeys) return;
|
|
1583
|
+
this.checkedParamKeys = signature;
|
|
1584
|
+
warnUnmatchedParams("<Phrase>", [this.phrase], this.params, this.category || void 0);
|
|
1585
|
+
}
|
|
1533
1586
|
_render() {
|
|
1534
1587
|
if (!this.phrase) return;
|
|
1535
1588
|
const raw = LangsysApp.Translations.lookup(this.phrase, this.category) ?? this.phrase;
|
|
@@ -1546,6 +1599,6 @@ var t = ((phrase, ...rest) => {
|
|
|
1546
1599
|
});
|
|
1547
1600
|
var tSignal = LangsysApp.Translations.tSignal;
|
|
1548
1601
|
|
|
1549
|
-
export { LangsysApp, LangsysAppAPI, Logger, PHRASE_MARKER_ATTR, Phrase, Translate, Translations, canonicalizeLocale, createSignal, currentlyLoadedLocale, encodeRichText, generateCustomId, getValue, interpolate, isContentBlockKnown, isEmpty, isICU, logger, markupTokenValues, md5, normalizeMarkupPlaceholders, persist, reconstitute, registerContentBlock, sTranslations, stripSentinels, t, tSignal, tokenizeElement };
|
|
1602
|
+
export { LangsysApp, LangsysAppAPI, Logger, PHRASE_MARKER_ATTR, Phrase, Translate, Translations, canonicalizeLocale, createSignal, currentlyLoadedLocale, encodeRichText, findUnusedParamKeys, generateCustomId, getValue, interpolate, isContentBlockKnown, isEmpty, isICU, logger, markupTokenValues, md5, normalizeMarkupPlaceholders, persist, reconstitute, registerContentBlock, sTranslations, stripSentinels, t, tSignal, tokenizeElement };
|
|
1550
1603
|
//# sourceMappingURL=index.mjs.map
|
|
1551
1604
|
//# sourceMappingURL=index.mjs.map
|