lingo.dev 0.117.3 → 0.117.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.mjs CHANGED
@@ -2229,22 +2229,13 @@ function walkAndApply(node, path19, metadata) {
2229
2229
  }
2230
2230
  }
2231
2231
  function isScalar(node) {
2232
- if (node?.constructor?.name === "Scalar") {
2233
- return true;
2234
- }
2235
- return node && typeof node === "object" && "value" in node && ("type" in node || "format" in node);
2232
+ return YAML.isScalar(node);
2236
2233
  }
2237
2234
  function isYAMLMap(node) {
2238
- if (node?.constructor?.name === "YAMLMap") {
2239
- return true;
2240
- }
2241
- return node && typeof node === "object" && "items" in node && Array.isArray(node.items) && !("value" in node);
2235
+ return YAML.isMap(node);
2242
2236
  }
2243
2237
  function isYAMLSeq(node) {
2244
- if (node?.constructor?.name === "YAMLSeq") {
2245
- return true;
2246
- }
2247
- return node && typeof node === "object" && "items" in node && Array.isArray(node.items) && !("type" in node) && !("value" in node);
2238
+ return YAML.isSeq(node);
2248
2239
  }
2249
2240
  function getKeyValue(key) {
2250
2241
  if (key === null || key === void 0) {
@@ -3419,8 +3410,8 @@ function serializeElement(node) {
3419
3410
  const attrString = Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttributeValue(String(value))}"`).join("");
3420
3411
  const children = Array.isArray(node.$$) ? node.$$ : [];
3421
3412
  if (children.length === 0) {
3422
- const textContent = node._ ?? "";
3423
- return `<${name}${attrString}>${textContent}</${name}>`;
3413
+ const textContent2 = node._ ?? "";
3414
+ return `<${name}${attrString}>${textContent2}</${name}>`;
3424
3415
  }
3425
3416
  const childContent = children.map(serializeElement).join("");
3426
3417
  return `<${name}${attrString}>${childContent}</${name}>`;
@@ -3509,135 +3500,335 @@ function createPullOutputCleaner() {
3509
3500
  }
3510
3501
 
3511
3502
  // src/cli/loaders/html.ts
3512
- import { JSDOM } from "jsdom";
3513
- function normalizeTextContent(text, isStandalone) {
3514
- const trimmed = text.trim();
3515
- if (!trimmed) return "";
3516
- return trimmed;
3517
- }
3503
+ import * as htmlparser2 from "htmlparser2";
3504
+ import { DomHandler } from "domhandler";
3505
+ import * as domutils from "domutils";
3506
+ import * as DomSerializer from "dom-serializer";
3518
3507
  function createHtmlLoader() {
3508
+ const PHRASING_ELEMENTS = /* @__PURE__ */ new Set([
3509
+ // Text-level semantics
3510
+ "a",
3511
+ "abbr",
3512
+ "b",
3513
+ "bdi",
3514
+ "bdo",
3515
+ "br",
3516
+ "cite",
3517
+ "code",
3518
+ "data",
3519
+ "dfn",
3520
+ "em",
3521
+ "i",
3522
+ "kbd",
3523
+ "mark",
3524
+ "q",
3525
+ "ruby",
3526
+ "s",
3527
+ "samp",
3528
+ "small",
3529
+ "span",
3530
+ "strong",
3531
+ "sub",
3532
+ "sup",
3533
+ "time",
3534
+ "u",
3535
+ "var",
3536
+ "wbr",
3537
+ // Media
3538
+ "audio",
3539
+ "img",
3540
+ "video",
3541
+ "picture",
3542
+ // Interactive
3543
+ "button",
3544
+ "input",
3545
+ "label",
3546
+ "select",
3547
+ "textarea",
3548
+ // Embedded
3549
+ "canvas",
3550
+ "iframe",
3551
+ "object",
3552
+ "svg",
3553
+ "math",
3554
+ // Other
3555
+ "del",
3556
+ "ins",
3557
+ "map",
3558
+ "area"
3559
+ ]);
3560
+ const BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
3561
+ "div",
3562
+ "p",
3563
+ "h1",
3564
+ "h2",
3565
+ "h3",
3566
+ "h4",
3567
+ "h5",
3568
+ "h6",
3569
+ "ul",
3570
+ "ol",
3571
+ "li",
3572
+ "dl",
3573
+ "dt",
3574
+ "dd",
3575
+ "blockquote",
3576
+ "pre",
3577
+ "article",
3578
+ "aside",
3579
+ "nav",
3580
+ "section",
3581
+ "header",
3582
+ "footer",
3583
+ "main",
3584
+ "figure",
3585
+ "figcaption",
3586
+ "table",
3587
+ "thead",
3588
+ "tbody",
3589
+ "tfoot",
3590
+ "tr",
3591
+ "td",
3592
+ "th",
3593
+ "caption",
3594
+ "form",
3595
+ "fieldset",
3596
+ "legend",
3597
+ "details",
3598
+ "summary",
3599
+ "address",
3600
+ "hr",
3601
+ "search",
3602
+ "dialog",
3603
+ "noscript",
3604
+ "title"
3605
+ // <title> should be treated as a block element for translation
3606
+ ]);
3607
+ const UNLOCALIZABLE_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
3519
3608
  const LOCALIZABLE_ATTRIBUTES = {
3520
3609
  meta: ["content"],
3521
- img: ["alt"],
3522
- input: ["placeholder"],
3523
- a: ["title"]
3610
+ img: ["alt", "title"],
3611
+ input: ["placeholder", "title"],
3612
+ textarea: ["placeholder", "title"],
3613
+ a: ["title"],
3614
+ abbr: ["title"],
3615
+ button: ["title"],
3616
+ link: ["title"]
3524
3617
  };
3525
- const UNLOCALIZABLE_TAGS = ["script", "style"];
3526
3618
  return createLoader({
3527
3619
  async pull(locale, input2) {
3528
3620
  const result = {};
3529
- const dom = new JSDOM(input2);
3530
- const document = dom.window.document;
3531
- const getPath = (node, attribute) => {
3532
- const indices = [];
3533
- let current = node;
3534
- let rootParent = "";
3535
- while (current) {
3536
- const parent = current.parentElement;
3537
- if (!parent) break;
3538
- if (parent === document.documentElement) {
3539
- rootParent = current.nodeName.toLowerCase();
3540
- break;
3621
+ const handler = new DomHandler();
3622
+ const parser = new htmlparser2.Parser(handler, {
3623
+ lowerCaseTags: false,
3624
+ lowerCaseAttributeNames: false
3625
+ });
3626
+ parser.write(input2);
3627
+ parser.end();
3628
+ const dom = handler.dom;
3629
+ function isInsideUnlocalizableTag(element) {
3630
+ let current = element.parent;
3631
+ while (current && current.type === "tag") {
3632
+ if (UNLOCALIZABLE_TAGS.has(current.name.toLowerCase())) {
3633
+ return true;
3541
3634
  }
3542
- const siblings = Array.from(parent.childNodes).filter(
3543
- (n) => n.nodeType === 1 || n.nodeType === 3 && n.textContent?.trim()
3544
- );
3545
- const index = siblings.indexOf(current);
3546
- if (index !== -1) {
3547
- indices.unshift(index);
3635
+ current = current.parent;
3636
+ }
3637
+ return false;
3638
+ }
3639
+ function hasTranslatableContent(element) {
3640
+ const text = domutils.textContent(element);
3641
+ return text.trim().length > 0;
3642
+ }
3643
+ function isLeafBlock(element) {
3644
+ const childElements = element.children.filter(
3645
+ (child) => child.type === "tag"
3646
+ );
3647
+ for (const child of childElements) {
3648
+ if (BLOCK_ELEMENTS.has(child.name.toLowerCase())) {
3649
+ return false;
3548
3650
  }
3549
- current = parent;
3550
3651
  }
3551
- const basePath = rootParent ? `${rootParent}/${indices.join("/")}` : indices.join("/");
3552
- return attribute ? `${basePath}#${attribute}` : basePath;
3553
- };
3554
- const processNode = (node) => {
3555
- let parent = node.parentElement;
3556
- while (parent) {
3557
- if (UNLOCALIZABLE_TAGS.includes(parent.tagName.toLowerCase())) {
3558
- return;
3652
+ return hasTranslatableContent(element);
3653
+ }
3654
+ function getInnerHTML(element) {
3655
+ return element.children.map((child) => DomSerializer.default(child, { encodeEntities: false })).join("");
3656
+ }
3657
+ function extractAttributes(element, path19) {
3658
+ const tagName = element.name.toLowerCase();
3659
+ const attrs = LOCALIZABLE_ATTRIBUTES[tagName];
3660
+ if (!attrs) return;
3661
+ for (const attr of attrs) {
3662
+ const value = element.attribs?.[attr];
3663
+ if (value && value.trim()) {
3664
+ result[`${path19}#${attr}`] = value.trim();
3559
3665
  }
3560
- parent = parent.parentElement;
3561
3666
  }
3562
- if (node.nodeType === 3) {
3563
- const text = node.textContent || "";
3564
- const normalizedText = normalizeTextContent(text, true);
3565
- if (normalizedText) {
3566
- result[getPath(node)] = normalizedText;
3667
+ }
3668
+ function extractFromElement(element, pathParts) {
3669
+ const path19 = pathParts.join("/");
3670
+ if (isInsideUnlocalizableTag(element)) {
3671
+ return;
3672
+ }
3673
+ extractAttributes(element, path19);
3674
+ const tagName = element.name.toLowerCase();
3675
+ if (BLOCK_ELEMENTS.has(tagName) && isLeafBlock(element)) {
3676
+ const content = getInnerHTML(element).trim();
3677
+ if (content) {
3678
+ result[path19] = content;
3567
3679
  }
3568
- } else if (node.nodeType === 1) {
3569
- const element = node;
3570
- const tagName = element.tagName.toLowerCase();
3571
- const attributes = LOCALIZABLE_ATTRIBUTES[tagName] || [];
3572
- attributes.forEach((attr) => {
3573
- const value = element.getAttribute(attr);
3574
- if (value) {
3575
- result[getPath(element, attr)] = value;
3576
- }
3577
- });
3578
- Array.from(element.childNodes).filter(
3579
- (n) => n.nodeType === 1 || n.nodeType === 3 && n.textContent?.trim()
3580
- ).forEach(processNode);
3680
+ return;
3581
3681
  }
3582
- };
3583
- Array.from(document.head.childNodes).filter(
3584
- (n) => n.nodeType === 1 || n.nodeType === 3 && n.textContent?.trim()
3585
- ).forEach(processNode);
3586
- Array.from(document.body.childNodes).filter(
3587
- (n) => n.nodeType === 1 || n.nodeType === 3 && n.textContent?.trim()
3588
- ).forEach(processNode);
3682
+ if (PHRASING_ELEMENTS.has(tagName) && hasTranslatableContent(element)) {
3683
+ const content = getInnerHTML(element).trim();
3684
+ if (content) {
3685
+ result[path19] = content;
3686
+ }
3687
+ return;
3688
+ }
3689
+ let childIndex = 0;
3690
+ const childElements = element.children.filter(
3691
+ (child) => child.type === "tag"
3692
+ );
3693
+ for (const child of childElements) {
3694
+ extractFromElement(child, [...pathParts, childIndex++]);
3695
+ }
3696
+ }
3697
+ const html = domutils.findOne(
3698
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
3699
+ dom,
3700
+ true
3701
+ );
3702
+ if (html) {
3703
+ const head = domutils.findOne(
3704
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
3705
+ html.children,
3706
+ true
3707
+ );
3708
+ const body = domutils.findOne(
3709
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
3710
+ html.children,
3711
+ true
3712
+ );
3713
+ if (head) {
3714
+ let headIndex = 0;
3715
+ const headChildren = head.children.filter(
3716
+ (child) => child.type === "tag"
3717
+ );
3718
+ for (const child of headChildren) {
3719
+ extractFromElement(child, ["head", headIndex++]);
3720
+ }
3721
+ }
3722
+ if (body) {
3723
+ let bodyIndex = 0;
3724
+ const bodyChildren = body.children.filter(
3725
+ (child) => child.type === "tag"
3726
+ );
3727
+ for (const child of bodyChildren) {
3728
+ extractFromElement(child, ["body", bodyIndex++]);
3729
+ }
3730
+ }
3731
+ } else {
3732
+ let rootIndex = 0;
3733
+ const rootElements = dom.filter(
3734
+ (child) => child.type === "tag"
3735
+ );
3736
+ for (const child of rootElements) {
3737
+ extractFromElement(child, [rootIndex++]);
3738
+ }
3739
+ }
3589
3740
  return result;
3590
3741
  },
3591
3742
  async push(locale, data, originalInput) {
3592
- const dom = new JSDOM(
3743
+ const handler = new DomHandler();
3744
+ const parser = new htmlparser2.Parser(handler, {
3745
+ lowerCaseTags: false,
3746
+ lowerCaseAttributeNames: false
3747
+ });
3748
+ parser.write(
3593
3749
  originalInput ?? "<!DOCTYPE html><html><head></head><body></body></html>"
3594
3750
  );
3595
- const document = dom.window.document;
3596
- const htmlElement = document.documentElement;
3597
- htmlElement.setAttribute("lang", locale);
3598
- const paths = Object.keys(data).sort((a, b) => {
3599
- const aDepth = a.split("/").length;
3600
- const bDepth = b.split("/").length;
3601
- return aDepth - bDepth;
3602
- });
3603
- paths.forEach((path19) => {
3604
- const value = data[path19];
3605
- const [nodePath, attribute] = path19.split("#");
3606
- const [rootTag, ...indices] = nodePath.split("/");
3607
- let parent = rootTag === "head" ? document.head : document.body;
3608
- let current = parent;
3609
- for (let i = 0; i < indices.length; i++) {
3610
- const index = parseInt(indices[i]);
3611
- const siblings = Array.from(parent.childNodes).filter(
3612
- (n) => n.nodeType === 1 || n.nodeType === 3 && n.textContent?.trim()
3751
+ parser.end();
3752
+ const dom = handler.dom;
3753
+ const html = domutils.findOne(
3754
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
3755
+ dom,
3756
+ true
3757
+ );
3758
+ if (html) {
3759
+ html.attribs = html.attribs || {};
3760
+ html.attribs.lang = locale;
3761
+ }
3762
+ function traverseByIndices(element, indices) {
3763
+ let current = element;
3764
+ for (const indexStr of indices) {
3765
+ if (!current) return null;
3766
+ const index = parseInt(indexStr, 10);
3767
+ const children = current.children.filter(
3768
+ (child) => child.type === "tag"
3613
3769
  );
3614
- if (index >= siblings.length) {
3615
- if (i === indices.length - 1) {
3616
- const textNode = document.createTextNode("");
3617
- parent.appendChild(textNode);
3618
- current = textNode;
3619
- } else {
3620
- const element = document.createElement("div");
3621
- parent.appendChild(element);
3622
- current = element;
3623
- parent = element;
3624
- }
3625
- } else {
3626
- current = siblings[index];
3627
- if (current.nodeType === 1) {
3628
- parent = current;
3629
- }
3770
+ if (index >= children.length) {
3771
+ return null;
3772
+ }
3773
+ current = children[index];
3774
+ }
3775
+ return current;
3776
+ }
3777
+ function resolvePathToElement(path19) {
3778
+ const parts = path19.split("/");
3779
+ const [rootTag, ...indices] = parts;
3780
+ let current = null;
3781
+ if (html) {
3782
+ if (rootTag === "head") {
3783
+ current = domutils.findOne(
3784
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
3785
+ html.children,
3786
+ true
3787
+ );
3788
+ } else if (rootTag === "body") {
3789
+ current = domutils.findOne(
3790
+ (elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
3791
+ html.children,
3792
+ true
3793
+ );
3794
+ }
3795
+ if (!current) return null;
3796
+ return traverseByIndices(current, indices);
3797
+ } else {
3798
+ const rootElements = dom.filter(
3799
+ (child) => child.type === "tag"
3800
+ );
3801
+ const rootIndex = parseInt(rootTag, 10);
3802
+ if (rootIndex >= rootElements.length) {
3803
+ return null;
3630
3804
  }
3805
+ current = rootElements[rootIndex];
3806
+ return traverseByIndices(current, indices);
3807
+ }
3808
+ }
3809
+ for (const [path19, value] of Object.entries(data)) {
3810
+ const [nodePath, attribute] = path19.split("#");
3811
+ const element = resolvePathToElement(nodePath);
3812
+ if (!element) {
3813
+ console.warn(`Path not found in original HTML: ${nodePath}`);
3814
+ continue;
3631
3815
  }
3632
- if (current) {
3633
- if (attribute) {
3634
- current.setAttribute(attribute, value);
3816
+ if (attribute) {
3817
+ element.attribs = element.attribs || {};
3818
+ element.attribs[attribute] = value;
3819
+ } else {
3820
+ if (value) {
3821
+ const valueHandler = new DomHandler();
3822
+ const valueParser = new htmlparser2.Parser(valueHandler);
3823
+ valueParser.write(value);
3824
+ valueParser.end();
3825
+ element.children = valueHandler.dom;
3635
3826
  } else {
3636
- current.textContent = value;
3827
+ element.children = [];
3637
3828
  }
3638
3829
  }
3639
- });
3640
- return dom.serialize();
3830
+ }
3831
+ return DomSerializer.default(dom, { encodeEntities: false });
3641
3832
  }
3642
3833
  });
3643
3834
  }
@@ -4083,7 +4274,7 @@ function escapeString(str) {
4083
4274
  }
4084
4275
 
4085
4276
  // src/cli/loaders/xcode-strings/parser.ts
4086
- var Parser = class {
4277
+ var Parser2 = class {
4087
4278
  tokens;
4088
4279
  pos;
4089
4280
  constructor(tokens) {
@@ -4156,7 +4347,7 @@ function createXcodeStringsLoader() {
4156
4347
  async pull(locale, input2) {
4157
4348
  const tokenizer = new Tokenizer(input2);
4158
4349
  const tokens = tokenizer.tokenize();
4159
- const parser = new Parser(tokens);
4350
+ const parser = new Parser2(tokens);
4160
4351
  const result = parser.parse();
4161
4352
  return result;
4162
4353
  },
@@ -5020,7 +5211,7 @@ function preserveCommentOrder(section, originalSection) {
5020
5211
  }
5021
5212
 
5022
5213
  // src/cli/loaders/xliff.ts
5023
- import { JSDOM as JSDOM2 } from "jsdom";
5214
+ import { JSDOM } from "jsdom";
5024
5215
  function createXliffLoader() {
5025
5216
  return createLoader({
5026
5217
  async pull(locale, input2, _ctx, originalLocale) {
@@ -5029,7 +5220,7 @@ function createXliffLoader() {
5029
5220
  return createEmptyResult(originalLocale, locale);
5030
5221
  }
5031
5222
  try {
5032
- const dom = new JSDOM2(trimmedInput, { contentType: "text/xml" });
5223
+ const dom = new JSDOM(trimmedInput, { contentType: "text/xml" });
5033
5224
  const document = dom.window.document;
5034
5225
  const parserError = document.querySelector("parsererror");
5035
5226
  if (parserError) {
@@ -5055,7 +5246,7 @@ function createXliffLoader() {
5055
5246
  return pushNewFile(locale, translations, originalLocale);
5056
5247
  }
5057
5248
  try {
5058
- const dom = new JSDOM2(originalInput, { contentType: "text/xml" });
5249
+ const dom = new JSDOM(originalInput, { contentType: "text/xml" });
5059
5250
  const document = dom.window.document;
5060
5251
  const xliffElement = document.documentElement;
5061
5252
  const version = xliffElement.getAttribute("version") || "1.2";
@@ -5355,7 +5546,7 @@ ${serialized}`;
5355
5546
  return serialized;
5356
5547
  }
5357
5548
  function formatXml(xml) {
5358
- const dom = new JSDOM2(xml, { contentType: "text/xml" });
5549
+ const dom = new JSDOM(xml, { contentType: "text/xml" });
5359
5550
  const doc = dom.window.document;
5360
5551
  function formatElement(element, depth = 0) {
5361
5552
  const indent2 = " ".repeat(depth);
@@ -5368,10 +5559,10 @@ function formatXml(xml) {
5368
5559
  if (cdataNode) {
5369
5560
  return `${indent2}${openTag}<![CDATA[${cdataNode.nodeValue}]]></${tagName}>`;
5370
5561
  }
5371
- const textContent = element.textContent?.trim() || "";
5562
+ const textContent2 = element.textContent?.trim() || "";
5372
5563
  const hasOnlyText = element.childNodes.length === 1 && element.childNodes[0].nodeType === 3;
5373
- if (hasOnlyText && textContent) {
5374
- return `${indent2}${openTag}${textContent}</${tagName}>`;
5564
+ if (hasOnlyText && textContent2) {
5565
+ return `${indent2}${openTag}${textContent2}</${tagName}>`;
5375
5566
  }
5376
5567
  const children = Array.from(element.children);
5377
5568
  if (children.length === 0) {
@@ -5398,7 +5589,7 @@ function pushNewFile(locale, translations, originalLocale) {
5398
5589
  <body></body>
5399
5590
  </file>
5400
5591
  </xliff>`;
5401
- const dom = new JSDOM2(skeleton, { contentType: "text/xml" });
5592
+ const dom = new JSDOM(skeleton, { contentType: "text/xml" });
5402
5593
  const document = dom.window.document;
5403
5594
  const bodyElement = document.querySelector("body");
5404
5595
  Object.entries(translations).forEach(([key, value]) => {
@@ -8691,14 +8882,14 @@ function parseEjsForTranslation(input2) {
8691
8882
  if (part.type === "ejs") {
8692
8883
  template += part.content;
8693
8884
  } else {
8694
- const textContent = part.content;
8885
+ const textContent2 = part.content;
8695
8886
  const htmlTagRegex = /<[^>]+>/g;
8696
8887
  const textParts = [];
8697
8888
  let lastTextIndex = 0;
8698
8889
  let htmlMatch;
8699
- while ((htmlMatch = htmlTagRegex.exec(textContent)) !== null) {
8890
+ while ((htmlMatch = htmlTagRegex.exec(textContent2)) !== null) {
8700
8891
  if (htmlMatch.index > lastTextIndex) {
8701
- const textBefore = textContent.slice(lastTextIndex, htmlMatch.index);
8892
+ const textBefore = textContent2.slice(lastTextIndex, htmlMatch.index);
8702
8893
  if (textBefore.trim()) {
8703
8894
  textParts.push({ type: "text", content: textBefore });
8704
8895
  } else {
@@ -8708,8 +8899,8 @@ function parseEjsForTranslation(input2) {
8708
8899
  textParts.push({ type: "html", content: htmlMatch[0] });
8709
8900
  lastTextIndex = htmlMatch.index + htmlMatch[0].length;
8710
8901
  }
8711
- if (lastTextIndex < textContent.length) {
8712
- const remainingText = textContent.slice(lastTextIndex);
8902
+ if (lastTextIndex < textContent2.length) {
8903
+ const remainingText = textContent2.slice(lastTextIndex);
8713
8904
  if (remainingText.trim()) {
8714
8905
  textParts.push({ type: "text", content: remainingText });
8715
8906
  } else {
@@ -8717,11 +8908,11 @@ function parseEjsForTranslation(input2) {
8717
8908
  }
8718
8909
  }
8719
8910
  if (textParts.length === 0) {
8720
- const trimmedContent = textContent.trim();
8911
+ const trimmedContent = textContent2.trim();
8721
8912
  if (trimmedContent) {
8722
- textParts.push({ type: "text", content: textContent });
8913
+ textParts.push({ type: "text", content: textContent2 });
8723
8914
  } else {
8724
- textParts.push({ type: "html", content: textContent });
8915
+ textParts.push({ type: "html", content: textContent2 });
8725
8916
  }
8726
8917
  }
8727
8918
  for (const textPart of textParts) {
@@ -13648,7 +13839,7 @@ async function renderHero2() {
13648
13839
  // package.json
13649
13840
  var package_default = {
13650
13841
  name: "lingo.dev",
13651
- version: "0.117.3",
13842
+ version: "0.117.5",
13652
13843
  description: "Lingo.dev CLI",
13653
13844
  private: false,
13654
13845
  publishConfig: {
@@ -13806,6 +13997,9 @@ var package_default = {
13806
13997
  "date-fns": "4.1.0",
13807
13998
  dedent: "1.7.0",
13808
13999
  diff: "7.0.0",
14000
+ "dom-serializer": "2.0.0",
14001
+ domhandler: "5.0.3",
14002
+ domutils: "3.2.2",
13809
14003
  dotenv: "16.4.7",
13810
14004
  ejs: "3.1.10",
13811
14005
  express: "5.1.0",
@@ -13816,6 +14010,7 @@ var package_default = {
13816
14010
  glob: "11.1.0",
13817
14011
  "gradient-string": "3.0.0",
13818
14012
  "gray-matter": "4.0.3",
14013
+ htmlparser2: "10.0.0",
13819
14014
  ini: "5.0.0",
13820
14015
  ink: "4.2.0",
13821
14016
  "ink-progress-bar": "3.0.0",