lingo.dev 0.116.3 → 0.116.4

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/build/cli.mjs CHANGED
@@ -1615,8 +1615,8 @@ function createLoader(lDefinition) {
1615
1615
  state.defaultLocale = locale;
1616
1616
  return this;
1617
1617
  },
1618
- async pullHints() {
1619
- return lDefinition.pullHints?.(state.originalInput);
1618
+ async pullHints(originalInput) {
1619
+ return lDefinition.pullHints?.(originalInput || state.originalInput);
1620
1620
  },
1621
1621
  async pull(locale, input2) {
1622
1622
  if (!state.defaultLocale) {
@@ -4188,19 +4188,44 @@ function _removeLocale(input2, locale) {
4188
4188
 
4189
4189
  // src/cli/loaders/xcode-xcstrings-v2.ts
4190
4190
  import _10 from "lodash";
4191
- function buildIcuPluralString(forms) {
4192
- const parts = Object.entries(forms).map(
4193
- ([form, text]) => `${form} {${text}}`
4194
- );
4191
+ function getRequiredPluralCategories(locale) {
4192
+ try {
4193
+ const pluralRules = new Intl.PluralRules(locale);
4194
+ const categories = pluralRules.resolvedOptions().pluralCategories;
4195
+ if (!categories || categories.length === 0) {
4196
+ return ["other"];
4197
+ }
4198
+ return categories;
4199
+ } catch (error) {
4200
+ return ["other"];
4201
+ }
4202
+ }
4203
+ function isValidPluralForm(form, locale) {
4204
+ if (form.startsWith("=")) return true;
4205
+ const requiredCategories = getRequiredPluralCategories(locale);
4206
+ return requiredCategories.includes(form);
4207
+ }
4208
+ function buildIcuPluralString(forms, sourceLocale) {
4209
+ const requiredCategories = new Set(getRequiredPluralCategories(sourceLocale));
4210
+ const parts = Object.entries(forms).map(([form, text]) => {
4211
+ let normalizedForm = form;
4212
+ if (!requiredCategories.has(form)) {
4213
+ if (form === "zero") normalizedForm = "=0";
4214
+ else if (form === "one") normalizedForm = "=1";
4215
+ else if (form === "two") normalizedForm = "=2";
4216
+ }
4217
+ return `${normalizedForm} {${text}}`;
4218
+ });
4195
4219
  return `{count, plural, ${parts.join(" ")}}`;
4196
4220
  }
4197
- function parseIcuPluralString(icuString) {
4221
+ function parseIcuPluralString(icuString, locale) {
4198
4222
  const pluralMatch = icuString.match(/\{[\w]+,\s*plural,\s*(.+)\}$/);
4199
4223
  if (!pluralMatch) {
4200
4224
  throw new Error(`Invalid ICU plural format: ${icuString}`);
4201
4225
  }
4202
4226
  const formsText = pluralMatch[1];
4203
4227
  const forms = {};
4228
+ const exactMatches = /* @__PURE__ */ new Set();
4204
4229
  let i = 0;
4205
4230
  while (i < formsText.length) {
4206
4231
  while (i < formsText.length && /\s/.test(formsText[i])) {
@@ -4222,6 +4247,16 @@ function parseIcuPluralString(icuString) {
4222
4247
  }
4223
4248
  }
4224
4249
  if (!formName) break;
4250
+ if (formName === "=0") {
4251
+ formName = "zero";
4252
+ exactMatches.add("zero");
4253
+ } else if (formName === "=1") {
4254
+ formName = "one";
4255
+ exactMatches.add("one");
4256
+ } else if (formName === "=2") {
4257
+ formName = "two";
4258
+ exactMatches.add("two");
4259
+ }
4225
4260
  while (i < formsText.length && /\s/.test(formsText[i])) {
4226
4261
  i++;
4227
4262
  }
@@ -4252,7 +4287,13 @@ function parseIcuPluralString(icuString) {
4252
4287
  }
4253
4288
  forms[formName] = formText;
4254
4289
  }
4255
- return forms;
4290
+ const filteredForms = {};
4291
+ for (const [form, text] of Object.entries(forms)) {
4292
+ if (exactMatches.has(form) || isValidPluralForm(form, locale)) {
4293
+ filteredForms[form] = text;
4294
+ }
4295
+ }
4296
+ return filteredForms;
4256
4297
  }
4257
4298
  function isIcuPluralString(value) {
4258
4299
  return typeof value === "string" && /^\{[\w]+,\s*plural,\s*.+\}$/.test(value);
@@ -4287,7 +4328,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4287
4328
  for (const [form, formData] of Object.entries(pluralForms)) {
4288
4329
  forms[form] = formData.stringUnit.value;
4289
4330
  }
4290
- const icuString = buildIcuPluralString(forms);
4331
+ const icuString = buildIcuPluralString(forms, locale);
4291
4332
  resultData[translationKey].substitutions[subName] = {
4292
4333
  variations: {
4293
4334
  plural: icuString
@@ -4310,7 +4351,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4310
4351
  forms[form] = formData.stringUnit.value;
4311
4352
  }
4312
4353
  }
4313
- const icuString = buildIcuPluralString(forms);
4354
+ const icuString = buildIcuPluralString(forms, locale);
4314
4355
  resultData[translationKey].variations = {
4315
4356
  plural: icuString
4316
4357
  };
@@ -4352,7 +4393,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4352
4393
  const pluralValue = subData?.variations?.plural;
4353
4394
  if (pluralValue && isIcuPluralString(pluralValue)) {
4354
4395
  try {
4355
- const pluralForms = parseIcuPluralString(pluralValue);
4396
+ const pluralForms = parseIcuPluralString(pluralValue, locale);
4356
4397
  const pluralOut = {};
4357
4398
  for (const [form, text] of Object.entries(pluralForms)) {
4358
4399
  pluralOut[form] = {
@@ -4392,7 +4433,7 @@ ${error instanceof Error ? error.message : String(error)}`
4392
4433
  const pluralValue = keyData.variations.plural;
4393
4434
  if (isIcuPluralString(pluralValue)) {
4394
4435
  try {
4395
- const pluralForms = parseIcuPluralString(pluralValue);
4436
+ const pluralForms = parseIcuPluralString(pluralValue, locale);
4396
4437
  const pluralOut = {};
4397
4438
  for (const [form, text] of Object.entries(pluralForms)) {
4398
4439
  pluralOut[form] = {
@@ -9797,35 +9838,6 @@ function createDeltaProcessor(fileKey) {
9797
9838
  };
9798
9839
  }
9799
9840
 
9800
- // src/cli/loaders/xcode-xcstrings-icu.ts
9801
- var ICU_TYPE_MARKER = Symbol.for("@lingo.dev/icu-plural-object");
9802
- function isICUPluralObject(value) {
9803
- if (!value || typeof value !== "object" || Array.isArray(value)) {
9804
- return false;
9805
- }
9806
- if (ICU_TYPE_MARKER in value) {
9807
- return true;
9808
- }
9809
- if (!("icu" in value) || typeof value.icu !== "string") {
9810
- return false;
9811
- }
9812
- const icuPluralPattern = /^\{[\w]+,\s*plural,\s*.+\}$/;
9813
- if (!icuPluralPattern.test(value.icu)) {
9814
- return false;
9815
- }
9816
- if (value._meta !== void 0) {
9817
- if (typeof value._meta !== "object" || !value._meta.variables || typeof value._meta.variables !== "object") {
9818
- return false;
9819
- }
9820
- for (const [varName, varMeta] of Object.entries(value._meta.variables)) {
9821
- if (!varMeta || typeof varMeta !== "object" || typeof varMeta.format !== "string" || varMeta.role !== "plural" && varMeta.role !== "other") {
9822
- return false;
9823
- }
9824
- }
9825
- }
9826
- return true;
9827
- }
9828
-
9829
9841
  // src/cli/cmd/i18n.ts
9830
9842
  var i18n_default = new Command14().command("i18n").description(
9831
9843
  "DEPRECATED: Run localization pipeline (prefer `run` command instead)"
@@ -10190,11 +10202,8 @@ var i18n_default = new Command14().command("i18n").description(
10190
10202
  }
10191
10203
  const finalDiffSize = _32.chain(finalTargetData).omitBy((value, key) => {
10192
10204
  const targetValue = targetData[key];
10193
- if (isICUPluralObject(value) && isICUPluralObject(targetValue)) {
10194
- return _32.isEqual(
10195
- { icu: value.icu, _meta: value._meta },
10196
- { icu: targetValue.icu, _meta: targetValue._meta }
10197
- );
10205
+ if (typeof value === "object" && value !== null) {
10206
+ return _32.isEqual(value, targetValue);
10198
10207
  }
10199
10208
  return value === targetValue;
10200
10209
  }).size().value();
@@ -13452,7 +13461,7 @@ async function renderHero2() {
13452
13461
  // package.json
13453
13462
  var package_default = {
13454
13463
  name: "lingo.dev",
13455
- version: "0.116.3",
13464
+ version: "0.116.4",
13456
13465
  description: "Lingo.dev CLI",
13457
13466
  private: false,
13458
13467
  publishConfig: {