lingo.dev 0.117.5 → 0.117.7

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
@@ -2732,16 +2732,9 @@ function appendResourceNode(document, resourceNode) {
2732
2732
  function setTextualNodeContent(node, value, useCdata) {
2733
2733
  const escapedValue = useCdata ? escapeApostrophesOnly(value) : escapeAndroidString(value);
2734
2734
  node._ = escapedValue;
2735
- node.$$ = _nullishCoalesce(node.$$, () => ( []));
2736
- let textNode = node.$$.find(
2737
- (child) => child["#name"] === "__text__" || child["#name"] === "__cdata"
2738
- );
2739
- if (!textNode) {
2740
- textNode = {};
2741
- node.$$.push(textNode);
2742
- }
2743
- textNode["#name"] = useCdata ? "__cdata" : "__text__";
2744
- textNode._ = escapedValue;
2735
+ node.$$ = [
2736
+ { "#name": useCdata ? "__cdata" : "__text__", _: escapedValue }
2737
+ ];
2745
2738
  }
2746
2739
  function buildResourceNameMap(document) {
2747
2740
  const map = /* @__PURE__ */ new Map();
@@ -3504,7 +3497,7 @@ function createPullOutputCleaner() {
3504
3497
  }
3505
3498
 
3506
3499
  // src/cli/loaders/html.ts
3507
- var _htmlparser2 = require('htmlparser2'); var htmlparser2 = _interopRequireWildcard(_htmlparser2);
3500
+ var _htmlparser2 = require('htmlparser2'); var htmlparser2 = _interopRequireWildcard(_htmlparser2); var htmlparser22 = _interopRequireWildcard(_htmlparser2);
3508
3501
  var _domhandler = require('domhandler');
3509
3502
  var _domutils = require('domutils'); var domutils = _interopRequireWildcard(_domutils);
3510
3503
  var _domserializer = require('dom-serializer'); var DomSerializer = _interopRequireWildcard(_domserializer);
@@ -3609,7 +3602,7 @@ function createHtmlLoader() {
3609
3602
  // <title> should be treated as a block element for translation
3610
3603
  ]);
3611
3604
  const UNLOCALIZABLE_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
3612
- const LOCALIZABLE_ATTRIBUTES = {
3605
+ const LOCALIZABLE_ATTRIBUTES2 = {
3613
3606
  meta: ["content"],
3614
3607
  img: ["alt", "title"],
3615
3608
  input: ["placeholder", "title"],
@@ -3655,12 +3648,12 @@ function createHtmlLoader() {
3655
3648
  }
3656
3649
  return hasTranslatableContent(element);
3657
3650
  }
3658
- function getInnerHTML(element) {
3651
+ function getInnerHTML2(element) {
3659
3652
  return element.children.map((child) => DomSerializer.default(child, { encodeEntities: false })).join("");
3660
3653
  }
3661
3654
  function extractAttributes(element, path19) {
3662
3655
  const tagName = element.name.toLowerCase();
3663
- const attrs = LOCALIZABLE_ATTRIBUTES[tagName];
3656
+ const attrs = LOCALIZABLE_ATTRIBUTES2[tagName];
3664
3657
  if (!attrs) return;
3665
3658
  for (const attr of attrs) {
3666
3659
  const value = _optionalChain([element, 'access', _143 => _143.attribs, 'optionalAccess', _144 => _144[attr]]);
@@ -3677,14 +3670,14 @@ function createHtmlLoader() {
3677
3670
  extractAttributes(element, path19);
3678
3671
  const tagName = element.name.toLowerCase();
3679
3672
  if (BLOCK_ELEMENTS.has(tagName) && isLeafBlock(element)) {
3680
- const content = getInnerHTML(element).trim();
3673
+ const content = getInnerHTML2(element).trim();
3681
3674
  if (content) {
3682
3675
  result[path19] = content;
3683
3676
  }
3684
3677
  return;
3685
3678
  }
3686
3679
  if (PHRASING_ELEMENTS.has(tagName) && hasTranslatableContent(element)) {
3687
- const content = getInnerHTML(element).trim();
3680
+ const content = getInnerHTML2(element).trim();
3688
3681
  if (content) {
3689
3682
  result[path19] = content;
3690
3683
  }
@@ -4015,6 +4008,264 @@ function applyTranslations(node, path19, data, pathMap) {
4015
4008
  }
4016
4009
  }
4017
4010
 
4011
+ // src/cli/loaders/mjml.ts
4012
+
4013
+
4014
+
4015
+ var LOCALIZABLE_COMPONENTS = [
4016
+ "mj-text",
4017
+ "mj-button",
4018
+ "mj-title",
4019
+ "mj-preview",
4020
+ "mj-navbar-link",
4021
+ "mj-accordion-title",
4022
+ "mj-accordion-text",
4023
+ "p",
4024
+ "h1",
4025
+ "h2",
4026
+ "h3",
4027
+ "h4",
4028
+ "h5",
4029
+ "h6",
4030
+ "li"
4031
+ ];
4032
+ var LOCALIZABLE_ATTRIBUTES = {
4033
+ "mj-image": ["alt", "title"],
4034
+ "mj-button": ["title", "aria-label"],
4035
+ "mj-social-element": ["title", "alt"],
4036
+ "img": ["alt", "title"],
4037
+ "a": ["title", "aria-label"]
4038
+ };
4039
+ function createMjmlLoader() {
4040
+ return createLoader({
4041
+ async pull(locale, input2) {
4042
+ const result = {};
4043
+ try {
4044
+ const parsed = await _xml2js.parseStringPromise.call(void 0, input2, {
4045
+ explicitArray: true,
4046
+ explicitChildren: true,
4047
+ preserveChildrenOrder: true,
4048
+ charsAsChildren: true,
4049
+ includeWhiteChars: true,
4050
+ mergeAttrs: false,
4051
+ trim: false,
4052
+ attrkey: "$",
4053
+ charkey: "_",
4054
+ childkey: "$$"
4055
+ });
4056
+ if (!parsed || typeof parsed !== "object") {
4057
+ console.error("Failed to parse MJML: invalid parsed structure");
4058
+ return result;
4059
+ }
4060
+ const rootKey = Object.keys(parsed).find((key) => !key.startsWith("_") && !key.startsWith("$"));
4061
+ const rootNode = rootKey ? parsed[rootKey] : parsed;
4062
+ const rootPath = rootNode["#name"] || rootKey || "";
4063
+ traverse(rootNode, (node, path19, componentName) => {
4064
+ if (typeof node !== "object") return;
4065
+ const localizableAttrs = LOCALIZABLE_ATTRIBUTES[componentName];
4066
+ if (localizableAttrs && node.$) {
4067
+ localizableAttrs.forEach((attr) => {
4068
+ const attrValue = node.$[attr];
4069
+ if (attrValue) {
4070
+ result[`${path19}#${attr}`] = attrValue;
4071
+ }
4072
+ });
4073
+ }
4074
+ if (LOCALIZABLE_COMPONENTS.includes(componentName)) {
4075
+ const innerHTML = getInnerHTML(node);
4076
+ if (innerHTML) {
4077
+ result[path19] = innerHTML;
4078
+ return "SKIP_CHILDREN";
4079
+ }
4080
+ }
4081
+ return void 0;
4082
+ }, rootPath);
4083
+ } catch (error) {
4084
+ console.error("Failed to parse MJML:", error);
4085
+ }
4086
+ return result;
4087
+ },
4088
+ async push(locale, data, originalInput) {
4089
+ try {
4090
+ const parsed = await _xml2js.parseStringPromise.call(void 0, originalInput || "", {
4091
+ explicitArray: true,
4092
+ explicitChildren: true,
4093
+ preserveChildrenOrder: true,
4094
+ charsAsChildren: true,
4095
+ includeWhiteChars: true,
4096
+ mergeAttrs: false,
4097
+ trim: false,
4098
+ attrkey: "$",
4099
+ charkey: "_",
4100
+ childkey: "$$"
4101
+ });
4102
+ if (!parsed || typeof parsed !== "object") {
4103
+ console.error("Failed to parse MJML for push: invalid parsed structure");
4104
+ return originalInput || "";
4105
+ }
4106
+ const rootKey = Object.keys(parsed).find((key) => !key.startsWith("_") && !key.startsWith("$"));
4107
+ const rootNode = rootKey ? parsed[rootKey] : parsed;
4108
+ const rootPath = rootNode["#name"] || rootKey || "";
4109
+ traverse(rootNode, (node, path19, componentName) => {
4110
+ if (typeof node !== "object") return;
4111
+ const localizableAttrs = LOCALIZABLE_ATTRIBUTES[componentName];
4112
+ if (localizableAttrs && node.$) {
4113
+ localizableAttrs.forEach((attr) => {
4114
+ const attrKey = `${path19}#${attr}`;
4115
+ if (data[attrKey] !== void 0) {
4116
+ node.$[attr] = data[attrKey];
4117
+ }
4118
+ });
4119
+ }
4120
+ if (LOCALIZABLE_COMPONENTS.includes(componentName) && data[path19]) {
4121
+ setInnerHTML(node, data[path19]);
4122
+ return "SKIP_CHILDREN";
4123
+ }
4124
+ return void 0;
4125
+ }, rootPath);
4126
+ return serializeMjml(parsed);
4127
+ } catch (error) {
4128
+ console.error("Failed to build MJML:", error);
4129
+ return "";
4130
+ }
4131
+ }
4132
+ });
4133
+ }
4134
+ function traverse(node, visitor, path19 = "") {
4135
+ if (!node || typeof node !== "object") {
4136
+ return;
4137
+ }
4138
+ const children = node.$$;
4139
+ if (!Array.isArray(children)) {
4140
+ return;
4141
+ }
4142
+ const elementCounts = /* @__PURE__ */ new Map();
4143
+ children.forEach((child) => {
4144
+ const elementName = child["#name"];
4145
+ if (!elementName || elementName.startsWith("__")) {
4146
+ return;
4147
+ }
4148
+ const currentIndex = elementCounts.get(elementName) || 0;
4149
+ elementCounts.set(elementName, currentIndex + 1);
4150
+ const currentPath = path19 ? `${path19}/${elementName}/${currentIndex}` : `${elementName}/${currentIndex}`;
4151
+ const result = visitor(child, currentPath, elementName);
4152
+ if (result !== "SKIP_CHILDREN") {
4153
+ traverse(child, visitor, currentPath);
4154
+ }
4155
+ });
4156
+ }
4157
+ function getInnerHTML(node) {
4158
+ if (!node.$$ || !Array.isArray(node.$$)) {
4159
+ return null;
4160
+ }
4161
+ let html = "";
4162
+ node.$$.forEach((child) => {
4163
+ html += serializeXmlNode(child);
4164
+ });
4165
+ return html.trim() || null;
4166
+ }
4167
+ function setInnerHTML(node, htmlContent) {
4168
+ const handler = new (0, _domhandler.DomHandler)();
4169
+ const parser = new htmlparser22.Parser(handler);
4170
+ parser.write(htmlContent);
4171
+ parser.end();
4172
+ const newChildren = [];
4173
+ for (const domNode of handler.dom) {
4174
+ const xmlNode = convertDomToXmlNode(domNode);
4175
+ if (xmlNode) {
4176
+ newChildren.push(xmlNode);
4177
+ }
4178
+ }
4179
+ node.$$ = newChildren;
4180
+ node._ = htmlContent;
4181
+ }
4182
+ function serializeXmlNode(node) {
4183
+ const name = node["#name"];
4184
+ if (name === "__text__") {
4185
+ return node._ || "";
4186
+ }
4187
+ if (name === "__cdata") {
4188
+ return `<![CDATA[${node._ || ""}]]>`;
4189
+ }
4190
+ if (!name || name.startsWith("__")) {
4191
+ return "";
4192
+ }
4193
+ const attrs = node.$ || {};
4194
+ const attrString = Object.entries(attrs).map(([key, value]) => ` ${key}="${escapeAttributeValue2(String(value))}"`).join("");
4195
+ const children = node.$$ || [];
4196
+ if (children.length === 0) {
4197
+ const textContent2 = node._ || "";
4198
+ if (textContent2) {
4199
+ return `<${name}${attrString}>${textContent2}</${name}>`;
4200
+ }
4201
+ return `<${name}${attrString} />`;
4202
+ }
4203
+ const childContent = children.map(serializeXmlNode).join("");
4204
+ return `<${name}${attrString}>${childContent}</${name}>`;
4205
+ }
4206
+ function convertDomToXmlNode(domNode) {
4207
+ if (domNode.type === "text") {
4208
+ return {
4209
+ "#name": "__text__",
4210
+ "_": domNode.data
4211
+ };
4212
+ }
4213
+ if (domNode.type === "tag") {
4214
+ const xmlNode = {
4215
+ "#name": domNode.name,
4216
+ "$": domNode.attribs || {},
4217
+ "$$": []
4218
+ };
4219
+ if (domNode.children && domNode.children.length > 0) {
4220
+ for (const child of domNode.children) {
4221
+ const xmlChild = convertDomToXmlNode(child);
4222
+ if (xmlChild) {
4223
+ xmlNode.$$.push(xmlChild);
4224
+ }
4225
+ }
4226
+ }
4227
+ return xmlNode;
4228
+ }
4229
+ return null;
4230
+ }
4231
+ function serializeMjml(parsed) {
4232
+ const xmlDec = '<?xml version="1.0" encoding="UTF-8"?>\n';
4233
+ const rootKey = Object.keys(parsed).find((key) => !key.startsWith("_") && !key.startsWith("$"));
4234
+ const rootNode = rootKey ? parsed[rootKey] : parsed;
4235
+ const body = serializeElement2(rootNode);
4236
+ return xmlDec + body;
4237
+ }
4238
+ function serializeElement2(node, indent2 = "") {
4239
+ if (!node) {
4240
+ return "";
4241
+ }
4242
+ const name = _nullishCoalesce(node["#name"], () => ( "mjml"));
4243
+ if (name === "__text__") {
4244
+ return _nullishCoalesce(node._, () => ( ""));
4245
+ }
4246
+ if (name === "__cdata") {
4247
+ return `<![CDATA[${_nullishCoalesce(node._, () => ( ""))}]]>`;
4248
+ }
4249
+ if (name === "__comment__") {
4250
+ return `<!--${_nullishCoalesce(node._, () => ( ""))}-->`;
4251
+ }
4252
+ const attributes = _nullishCoalesce(node.$, () => ( {}));
4253
+ const attrString = Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttributeValue2(String(value))}"`).join("");
4254
+ const children = Array.isArray(node.$$) ? node.$$ : [];
4255
+ if (children.length === 0) {
4256
+ const textContent2 = _nullishCoalesce(node._, () => ( ""));
4257
+ if (textContent2) {
4258
+ return `${indent2}<${name}${attrString}>${textContent2}</${name}>`;
4259
+ }
4260
+ return `${indent2}<${name}${attrString} />`;
4261
+ }
4262
+ const childContent = children.map((child) => serializeElement2(child, indent2)).join("");
4263
+ return `${indent2}<${name}${attrString}>${childContent}</${name}>`;
4264
+ }
4265
+ function escapeAttributeValue2(value) {
4266
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&apos;");
4267
+ }
4268
+
4018
4269
  // src/cli/loaders/properties.ts
4019
4270
  function createPropertiesLoader() {
4020
4271
  return createLoader({
@@ -4278,7 +4529,7 @@ function escapeString(str) {
4278
4529
  }
4279
4530
 
4280
4531
  // src/cli/loaders/xcode-strings/parser.ts
4281
- var Parser2 = class {
4532
+ var Parser3 = class {
4282
4533
 
4283
4534
 
4284
4535
  constructor(tokens) {
@@ -4351,7 +4602,7 @@ function createXcodeStringsLoader() {
4351
4602
  async pull(locale, input2) {
4352
4603
  const tokenizer = new Tokenizer(input2);
4353
4604
  const tokens = tokenizer.tokenize();
4354
- const parser = new Parser2(tokens);
4605
+ const parser = new Parser3(tokens);
4355
4606
  const result = parser.parse();
4356
4607
  return result;
4357
4608
  },
@@ -6738,7 +6989,7 @@ function resolveCjsExport(mod, name = "module") {
6738
6989
  }
6739
6990
 
6740
6991
  // src/cli/loaders/typescript/index.ts
6741
- var traverse = resolveCjsExport(_traverse2.default, "@babel/traverse");
6992
+ var traverse2 = resolveCjsExport(_traverse2.default, "@babel/traverse");
6742
6993
  var generate = resolveCjsExport(_generator2.default, "@babel/generator");
6743
6994
  function createTypescriptLoader() {
6744
6995
  return createLoader({
@@ -6771,7 +7022,7 @@ function parseTypeScript(input2) {
6771
7022
  }
6772
7023
  function extractStringsFromDefaultExport(ast) {
6773
7024
  let extracted = {};
6774
- traverse(ast, {
7025
+ traverse2(ast, {
6775
7026
  ExportDefaultDeclaration(path19) {
6776
7027
  const { declaration } = path19.node;
6777
7028
  const decl = unwrapTSAsExpression(declaration);
@@ -6844,7 +7095,7 @@ function arrayExpressionToArray(arrayExpression) {
6844
7095
  }
6845
7096
  function updateStringsInDefaultExport(ast, data) {
6846
7097
  let modified = false;
6847
- traverse(ast, {
7098
+ traverse2(ast, {
6848
7099
  ExportDefaultDeclaration(path19) {
6849
7100
  const { declaration } = path19.node;
6850
7101
  const decl = unwrapTSAsExpression(declaration);
@@ -9261,6 +9512,17 @@ function createBucketLoader(bucketType, bucketPathPattern, options, lockedKeys,
9261
9512
  createSyncLoader(),
9262
9513
  createUnlocalizableLoader(options.returnUnlocalizedKeys)
9263
9514
  );
9515
+ case "mjml":
9516
+ return composeLoaders(
9517
+ createTextFileLoader(bucketPathPattern),
9518
+ createFormatterLoader(options.formatter, "html", bucketPathPattern),
9519
+ createLockedPatternsLoader(lockedPatterns),
9520
+ createMjmlLoader(),
9521
+ createLockedKeysLoader(lockedKeys || []),
9522
+ createIgnoredKeysLoader(ignoredKeys || []),
9523
+ createSyncLoader(),
9524
+ createUnlocalizableLoader(options.returnUnlocalizedKeys)
9525
+ );
9264
9526
  case "po":
9265
9527
  return composeLoaders(
9266
9528
  createTextFileLoader(bucketPathPattern),
@@ -13843,7 +14105,7 @@ async function renderHero2() {
13843
14105
  // package.json
13844
14106
  var package_default = {
13845
14107
  name: "lingo.dev",
13846
- version: "0.117.5",
14108
+ version: "0.117.7",
13847
14109
  description: "Lingo.dev CLI",
13848
14110
  private: false,
13849
14111
  publishConfig: {