lingo.dev 0.116.3 → 0.116.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/build/cli.cjs CHANGED
@@ -1619,8 +1619,8 @@ function createLoader(lDefinition) {
1619
1619
  state.defaultLocale = locale;
1620
1620
  return this;
1621
1621
  },
1622
- async pullHints() {
1623
- return _optionalChain([lDefinition, 'access', _101 => _101.pullHints, 'optionalCall', _102 => _102(state.originalInput)]);
1622
+ async pullHints(originalInput) {
1623
+ return _optionalChain([lDefinition, 'access', _101 => _101.pullHints, 'optionalCall', _102 => _102(originalInput || state.originalInput)]);
1624
1624
  },
1625
1625
  async pull(locale, input2) {
1626
1626
  if (!state.defaultLocale) {
@@ -2111,6 +2111,13 @@ function getKeyType(yamlString) {
2111
2111
  function getStringType(yamlString) {
2112
2112
  if (yamlString) {
2113
2113
  const lines = yamlString.split("\n");
2114
+ const hasLiteralBlockScalar = lines.find((line) => {
2115
+ const trimmedLine = line.trim();
2116
+ return trimmedLine.match(/:\s*\|[-+]?\s*$/);
2117
+ });
2118
+ if (hasLiteralBlockScalar) {
2119
+ return "PLAIN";
2120
+ }
2114
2121
  const hasDoubleQuotes = lines.find((line) => {
2115
2122
  const trimmedLine = line.trim();
2116
2123
  return (trimmedLine.startsWith('"') || trimmedLine.match(/:\s*"/)) && (trimmedLine.endsWith('"') || trimmedLine.endsWith('",'));
@@ -4192,19 +4199,44 @@ function _removeLocale(input2, locale) {
4192
4199
 
4193
4200
  // src/cli/loaders/xcode-xcstrings-v2.ts
4194
4201
 
4195
- function buildIcuPluralString(forms) {
4196
- const parts = Object.entries(forms).map(
4197
- ([form, text]) => `${form} {${text}}`
4198
- );
4202
+ function getRequiredPluralCategories(locale) {
4203
+ try {
4204
+ const pluralRules = new Intl.PluralRules(locale);
4205
+ const categories = pluralRules.resolvedOptions().pluralCategories;
4206
+ if (!categories || categories.length === 0) {
4207
+ return ["other"];
4208
+ }
4209
+ return categories;
4210
+ } catch (error) {
4211
+ return ["other"];
4212
+ }
4213
+ }
4214
+ function isValidPluralForm(form, locale) {
4215
+ if (form.startsWith("=")) return true;
4216
+ const requiredCategories = getRequiredPluralCategories(locale);
4217
+ return requiredCategories.includes(form);
4218
+ }
4219
+ function buildIcuPluralString(forms, sourceLocale) {
4220
+ const requiredCategories = new Set(getRequiredPluralCategories(sourceLocale));
4221
+ const parts = Object.entries(forms).map(([form, text]) => {
4222
+ let normalizedForm = form;
4223
+ if (!requiredCategories.has(form)) {
4224
+ if (form === "zero") normalizedForm = "=0";
4225
+ else if (form === "one") normalizedForm = "=1";
4226
+ else if (form === "two") normalizedForm = "=2";
4227
+ }
4228
+ return `${normalizedForm} {${text}}`;
4229
+ });
4199
4230
  return `{count, plural, ${parts.join(" ")}}`;
4200
4231
  }
4201
- function parseIcuPluralString(icuString) {
4232
+ function parseIcuPluralString(icuString, locale) {
4202
4233
  const pluralMatch = icuString.match(/\{[\w]+,\s*plural,\s*(.+)\}$/);
4203
4234
  if (!pluralMatch) {
4204
4235
  throw new Error(`Invalid ICU plural format: ${icuString}`);
4205
4236
  }
4206
4237
  const formsText = pluralMatch[1];
4207
4238
  const forms = {};
4239
+ const exactMatches = /* @__PURE__ */ new Set();
4208
4240
  let i = 0;
4209
4241
  while (i < formsText.length) {
4210
4242
  while (i < formsText.length && /\s/.test(formsText[i])) {
@@ -4226,6 +4258,16 @@ function parseIcuPluralString(icuString) {
4226
4258
  }
4227
4259
  }
4228
4260
  if (!formName) break;
4261
+ if (formName === "=0") {
4262
+ formName = "zero";
4263
+ exactMatches.add("zero");
4264
+ } else if (formName === "=1") {
4265
+ formName = "one";
4266
+ exactMatches.add("one");
4267
+ } else if (formName === "=2") {
4268
+ formName = "two";
4269
+ exactMatches.add("two");
4270
+ }
4229
4271
  while (i < formsText.length && /\s/.test(formsText[i])) {
4230
4272
  i++;
4231
4273
  }
@@ -4256,7 +4298,13 @@ function parseIcuPluralString(icuString) {
4256
4298
  }
4257
4299
  forms[formName] = formText;
4258
4300
  }
4259
- return forms;
4301
+ const filteredForms = {};
4302
+ for (const [form, text] of Object.entries(forms)) {
4303
+ if (exactMatches.has(form) || isValidPluralForm(form, locale)) {
4304
+ filteredForms[form] = text;
4305
+ }
4306
+ }
4307
+ return filteredForms;
4260
4308
  }
4261
4309
  function isIcuPluralString(value) {
4262
4310
  return typeof value === "string" && /^\{[\w]+,\s*plural,\s*.+\}$/.test(value);
@@ -4291,7 +4339,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4291
4339
  for (const [form, formData] of Object.entries(pluralForms)) {
4292
4340
  forms[form] = formData.stringUnit.value;
4293
4341
  }
4294
- const icuString = buildIcuPluralString(forms);
4342
+ const icuString = buildIcuPluralString(forms, locale);
4295
4343
  resultData[translationKey].substitutions[subName] = {
4296
4344
  variations: {
4297
4345
  plural: icuString
@@ -4314,7 +4362,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4314
4362
  forms[form] = formData.stringUnit.value;
4315
4363
  }
4316
4364
  }
4317
- const icuString = buildIcuPluralString(forms);
4365
+ const icuString = buildIcuPluralString(forms, locale);
4318
4366
  resultData[translationKey].variations = {
4319
4367
  plural: icuString
4320
4368
  };
@@ -4356,7 +4404,7 @@ function createXcodeXcstringsV2Loader(defaultLocale) {
4356
4404
  const pluralValue = _optionalChain([subData, 'optionalAccess', _196 => _196.variations, 'optionalAccess', _197 => _197.plural]);
4357
4405
  if (pluralValue && isIcuPluralString(pluralValue)) {
4358
4406
  try {
4359
- const pluralForms = parseIcuPluralString(pluralValue);
4407
+ const pluralForms = parseIcuPluralString(pluralValue, locale);
4360
4408
  const pluralOut = {};
4361
4409
  for (const [form, text] of Object.entries(pluralForms)) {
4362
4410
  pluralOut[form] = {
@@ -4396,7 +4444,7 @@ ${error instanceof Error ? error.message : String(error)}`
4396
4444
  const pluralValue = keyData.variations.plural;
4397
4445
  if (isIcuPluralString(pluralValue)) {
4398
4446
  try {
4399
- const pluralForms = parseIcuPluralString(pluralValue);
4447
+ const pluralForms = parseIcuPluralString(pluralValue, locale);
4400
4448
  const pluralOut = {};
4401
4449
  for (const [form, text] of Object.entries(pluralForms)) {
4402
4450
  pluralOut[form] = {
@@ -9801,35 +9849,6 @@ function createDeltaProcessor(fileKey) {
9801
9849
  };
9802
9850
  }
9803
9851
 
9804
- // src/cli/loaders/xcode-xcstrings-icu.ts
9805
- var ICU_TYPE_MARKER = Symbol.for("@lingo.dev/icu-plural-object");
9806
- function isICUPluralObject(value) {
9807
- if (!value || typeof value !== "object" || Array.isArray(value)) {
9808
- return false;
9809
- }
9810
- if (ICU_TYPE_MARKER in value) {
9811
- return true;
9812
- }
9813
- if (!("icu" in value) || typeof value.icu !== "string") {
9814
- return false;
9815
- }
9816
- const icuPluralPattern = /^\{[\w]+,\s*plural,\s*.+\}$/;
9817
- if (!icuPluralPattern.test(value.icu)) {
9818
- return false;
9819
- }
9820
- if (value._meta !== void 0) {
9821
- if (typeof value._meta !== "object" || !value._meta.variables || typeof value._meta.variables !== "object") {
9822
- return false;
9823
- }
9824
- for (const [varName, varMeta] of Object.entries(value._meta.variables)) {
9825
- if (!varMeta || typeof varMeta !== "object" || typeof varMeta.format !== "string" || varMeta.role !== "plural" && varMeta.role !== "other") {
9826
- return false;
9827
- }
9828
- }
9829
- }
9830
- return true;
9831
- }
9832
-
9833
9852
  // src/cli/cmd/i18n.ts
9834
9853
  var i18n_default = new (0, _interactivecommander.Command)().command("i18n").description(
9835
9854
  "DEPRECATED: Run localization pipeline (prefer `run` command instead)"
@@ -10194,11 +10213,8 @@ var i18n_default = new (0, _interactivecommander.Command)().command("i18n").desc
10194
10213
  }
10195
10214
  const finalDiffSize = _lodash2.default.chain(finalTargetData).omitBy((value, key) => {
10196
10215
  const targetValue = targetData[key];
10197
- if (isICUPluralObject(value) && isICUPluralObject(targetValue)) {
10198
- return _lodash2.default.isEqual(
10199
- { icu: value.icu, _meta: value._meta },
10200
- { icu: targetValue.icu, _meta: targetValue._meta }
10201
- );
10216
+ if (typeof value === "object" && value !== null) {
10217
+ return _lodash2.default.isEqual(value, targetValue);
10202
10218
  }
10203
10219
  return value === targetValue;
10204
10220
  }).size().value();
@@ -13456,7 +13472,7 @@ async function renderHero2() {
13456
13472
  // package.json
13457
13473
  var package_default = {
13458
13474
  name: "lingo.dev",
13459
- version: "0.116.3",
13475
+ version: "0.116.5",
13460
13476
  description: "Lingo.dev CLI",
13461
13477
  private: false,
13462
13478
  publishConfig: {