potatejs 0.13.0 → 0.14.0

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.
@@ -12993,65 +12993,103 @@ function generate(node, options) {
12993
12993
 
12994
12994
  // src/plugin/babel-compat.js
12995
12995
  var t = {
12996
- // Type Checkers
12997
- isJSXElement: (node) => (node == null ? void 0 : node.type) === "JSXElement",
12998
- isJSXText: (node) => (node == null ? void 0 : node.type) === "JSXText",
12999
- isJSXExpressionContainer: (node) => (node == null ? void 0 : node.type) === "JSXExpressionContainer",
13000
- isJSXFragment: (node) => (node == null ? void 0 : node.type) === "JSXFragment",
13001
- isJSXEmptyExpression: (node) => (node == null ? void 0 : node.type) === "JSXEmptyExpression",
13002
- isJSXSpreadAttribute: (node) => (node == null ? void 0 : node.type) === "JSXSpreadAttribute",
13003
- isJSXAttribute: (node) => (node == null ? void 0 : node.type) === "JSXAttribute",
13004
- isObjectExpression: (node) => (node == null ? void 0 : node.type) === "ObjectExpression",
13005
- isJSXIdentifier: (node) => (node == null ? void 0 : node.type) === "JSXIdentifier",
13006
- isJSXMemberExpression: (node) => (node == null ? void 0 : node.type) === "JSXMemberExpression",
13007
- // Node Creators
13008
- identifier: (name) => ({ type: "Identifier", name }),
13009
- stringLiteral: (value) => ({ type: "Literal", value, raw: `'${value}'` }),
13010
- nullLiteral: () => ({ type: "Literal", value: null, raw: "null" }),
13011
- booleanLiteral: (value) => ({ type: "Literal", value, raw: String(value) }),
13012
- objectExpression: (properties) => ({ type: "ObjectExpression", properties }),
13013
- objectProperty: (key, value, computed = false, shorthand = false) => ({
13014
- type: "Property",
13015
- key,
13016
- value,
13017
- computed,
13018
- shorthand,
13019
- kind: "init"
13020
- }),
13021
- spreadElement: (argument) => ({ type: "SpreadElement", argument }),
13022
- callExpression: (callee, args) => ({ type: "CallExpression", callee, arguments: args }),
13023
- memberExpression: (object, property) => ({ type: "MemberExpression", object, property }),
13024
- taggedTemplateExpression: (tag, quasi) => ({ type: "TaggedTemplateExpression", tag, quasi }),
13025
- templateLiteral: (quasis, expressions) => ({ type: "TemplateLiteral", quasis, expressions }),
13026
- templateElement: (value, tail) => ({ type: "TemplateElement", value, tail })
13027
- };
13028
- var pathCache = /* @__PURE__ */ new WeakMap();
13029
- var createPath = (node, parentPath = null) => {
13030
- if (!node || typeof node !== "object") return null;
13031
- if (pathCache.has(node)) {
13032
- const cachedPath = pathCache.get(node);
13033
- if (parentPath && cachedPath.parentPath !== parentPath) {
13034
- cachedPath.parentPath = parentPath;
13035
- }
13036
- return cachedPath;
13037
- }
13038
- const path = {
12996
+ // Matches physical TemplateLiteral structure
12997
+ templateLiteral(strings, expressions) {
12998
+ return {
12999
+ type: "TemplateLiteral",
13000
+ strings,
13001
+ expressions
13002
+ };
13003
+ },
13004
+ // Matches physical TemplateElement structure
13005
+ templateElement(value, tail) {
13006
+ return {
13007
+ type: "TemplateElement",
13008
+ value: {
13009
+ raw: value.raw,
13010
+ cooked: value.cooked
13011
+ },
13012
+ tail
13013
+ };
13014
+ },
13015
+ // Matches physical TaggedTemplateExpression structure
13016
+ taggedTemplateExpression(tag, template) {
13017
+ return {
13018
+ type: "TaggedTemplateExpression",
13019
+ tag,
13020
+ template
13021
+ };
13022
+ },
13023
+ identifier(name) {
13024
+ return { type: "Identifier", name };
13025
+ },
13026
+ // In Potate engine, these are just "Literal"
13027
+ stringLiteral(value) {
13028
+ return { type: "Literal", value };
13029
+ },
13030
+ booleanLiteral(value) {
13031
+ return { type: "Literal", value };
13032
+ },
13033
+ importSpecifier(local, imported) {
13034
+ return { type: "ImportSpecifier", local, imported };
13035
+ },
13036
+ importDeclaration(specifiers, source) {
13037
+ return { type: "ImportDeclaration", specifiers, source };
13038
+ },
13039
+ callExpression(callee, args) {
13040
+ return { type: "CallExpression", callee, arguments: args };
13041
+ },
13042
+ memberExpression(object, property) {
13043
+ return { type: "MemberExpression", object, property, computed: false };
13044
+ },
13045
+ objectExpression(properties) {
13046
+ return { type: "ObjectExpression", properties };
13047
+ },
13048
+ objectProperty(key, value, computed = false, shorthand = false) {
13049
+ return { type: "Property", key, value, kind: "init", computed, shorthand };
13050
+ },
13051
+ spreadElement(argument) {
13052
+ return { type: "SpreadElement", argument };
13053
+ },
13054
+ arrayExpression(elements) {
13055
+ return { type: "ArrayExpression", elements };
13056
+ },
13057
+ // Type checkers (Physical check)
13058
+ isJSXElement(node) {
13059
+ return node && node.type === "JSXElement";
13060
+ },
13061
+ isJSXFragment(node) {
13062
+ return node && node.type === "JSXFragment";
13063
+ },
13064
+ isJSXText(node) {
13065
+ return node && node.type === "JSXText";
13066
+ },
13067
+ isJSXExpressionContainer(node) {
13068
+ return node && node.type === "JSXExpressionContainer";
13069
+ },
13070
+ isJSXEmptyExpression(node) {
13071
+ return node && node.type === "JSXEmptyExpression";
13072
+ },
13073
+ isJSXAttribute(node) {
13074
+ return node && node.type === "JSXAttribute";
13075
+ },
13076
+ isJSXSpreadAttribute(node) {
13077
+ return node && node.type === "JSXSpreadAttribute";
13078
+ }
13079
+ };
13080
+ function createPath(node, parentPath = null) {
13081
+ return {
13039
13082
  node,
13040
13083
  parentPath,
13041
- get parent() {
13042
- return this.parentPath ? this.parentPath.node : null;
13043
- },
13044
13084
  get(key) {
13045
- const val = this.node[key];
13046
- if (Array.isArray(val)) {
13047
- return val.map((child) => createPath(child, this));
13085
+ const value = this.node[key];
13086
+ if (Array.isArray(value)) {
13087
+ return value.map((v) => createPath(v, this));
13048
13088
  }
13049
- return createPath(val, this);
13089
+ return value ? createPath(value, this) : null;
13050
13090
  }
13051
13091
  };
13052
- pathCache.set(node, path);
13053
- return path;
13054
- };
13092
+ }
13055
13093
 
13056
13094
  // src/plugin/svgAttributeMap.js
13057
13095
  var svgAttributeMap_default = {
@@ -13143,6 +13181,7 @@ var svgAttributeMap_default = {
13143
13181
  };
13144
13182
 
13145
13183
  // src/plugin/constants.js
13184
+ var BRAHMOS_PLACEHOLDER = "{{brahmos}}";
13146
13185
  var RESERVED_ATTRIBUTES = {
13147
13186
  key: 1,
13148
13187
  ref: 1
@@ -13176,9 +13215,7 @@ function cleanStringForHtml(rawStr) {
13176
13215
  const lines = rawStr.split(/\r\n|\n|\r/);
13177
13216
  let lastNonEmptyLine = 0;
13178
13217
  for (let i = 0; i < lines.length; i++) {
13179
- if (lines[i].match(/[^ \t]/)) {
13180
- lastNonEmptyLine = i;
13181
- }
13218
+ if (lines[i].match(/[^ \t]/)) lastNonEmptyLine = i;
13182
13219
  }
13183
13220
  let str = "";
13184
13221
  for (let i = 0; i < lines.length; i++) {
@@ -13187,16 +13224,10 @@ function cleanStringForHtml(rawStr) {
13187
13224
  const isLastLine = i === lines.length - 1;
13188
13225
  const isLastNonEmptyLine = i === lastNonEmptyLine;
13189
13226
  let trimmedLine = line.replace(/\t/g, " ");
13190
- if (!isFirstLine) {
13191
- trimmedLine = trimmedLine.replace(/^[ ]+/, "");
13192
- }
13193
- if (!isLastLine) {
13194
- trimmedLine = trimmedLine.replace(/[ ]+$/, "");
13195
- }
13227
+ if (!isFirstLine) trimmedLine = trimmedLine.replace(/^[ ]+/, "");
13228
+ if (!isLastLine) trimmedLine = trimmedLine.replace(/[ ]+$/, "");
13196
13229
  if (trimmedLine) {
13197
- if (!isLastNonEmptyLine) {
13198
- trimmedLine += " ";
13199
- }
13230
+ if (!isLastNonEmptyLine) trimmedLine += " ";
13200
13231
  str += trimmedLine;
13201
13232
  }
13202
13233
  }
@@ -13217,23 +13248,73 @@ function isEmptyLiteralWrap(strings) {
13217
13248
  function getPropValue(value) {
13218
13249
  return t.isJSXExpressionContainer(value) ? value.expression : value;
13219
13250
  }
13251
+ function getAttributeName(nameNode) {
13252
+ if (nameNode.type === "JSXNamespacedName") {
13253
+ return `${nameNode.namespace.name}:${nameNode.name.name}`;
13254
+ }
13255
+ return nameNode.name;
13256
+ }
13220
13257
  function createAttributeProperty(name, value) {
13221
13258
  value = value || t.booleanLiteral(true);
13222
- const attrNameStr = name.name;
13259
+ const attrNameStr = getAttributeName(name);
13223
13260
  const propName = attrNameStr.match("-|:") ? t.stringLiteral(attrNameStr) : t.identifier(attrNameStr);
13224
13261
  const propValue = getPropValue(value);
13225
- return t.objectProperty(propName, propValue, false, propName.name === propValue.name);
13262
+ const isShorthand = propName.type === "Identifier" && propValue.type === "Identifier" && propName.name === propValue.name;
13263
+ return t.objectProperty(propName, propValue, false, isShorthand);
13226
13264
  }
13227
13265
  function createAttributeExpression(name, value) {
13228
13266
  return t.objectExpression([createAttributeProperty(name, value)]);
13229
13267
  }
13268
+ function addBrahmosRuntime(programPath) {
13269
+ if (programPath.node.hasBrahmosRuntime) return;
13270
+ const jsxImport = t.importSpecifier(t.identifier("_brahmosJSX"), t.identifier("jsx"));
13271
+ const htmlImport = t.importSpecifier(t.identifier("_brahmosHtml"), t.identifier("html"));
13272
+ const importStatement = t.importDeclaration([jsxImport, htmlImport], t.stringLiteral("potatejs"));
13273
+ programPath.node.body.unshift(importStatement);
13274
+ programPath.node.hasBrahmosRuntime = true;
13275
+ }
13276
+ function transformToAstNode(res) {
13277
+ if (typeof res === "string") {
13278
+ return { type: "Literal", value: res, raw: `'${res}'` };
13279
+ }
13280
+ if (res.type === "TaggedTemplateExpression") {
13281
+ return {
13282
+ type: "CallExpression",
13283
+ callee: {
13284
+ type: "TaggedTemplateExpression",
13285
+ tag: { type: "Identifier", name: res.tag },
13286
+ quasi: {
13287
+ type: "TemplateLiteral",
13288
+ quasis: res.template.strings.map((s) => ({
13289
+ type: "TemplateElement",
13290
+ value: {
13291
+ raw: s.value.raw || "",
13292
+ cooked: s.value.cooked || ""
13293
+ },
13294
+ tail: s.tail
13295
+ })),
13296
+ expressions: res.template.expressions
13297
+ }
13298
+ },
13299
+ arguments: [res.meta]
13300
+ };
13301
+ }
13302
+ return res;
13303
+ }
13230
13304
 
13231
13305
  // src/plugin/partUtils.js
13232
13306
  function getSlimIndex(index) {
13233
13307
  return index === void 0 || index === -1 ? "" : index;
13234
13308
  }
13235
13309
  function isValidTemplateElement(node) {
13236
- return t.isJSXText(node) || node.elementCounter !== void 0;
13310
+ return t.isJSXText(node) || node && node.elementCounter !== void 0;
13311
+ }
13312
+ function getEffectiveNodePath(path) {
13313
+ let currentPath = path;
13314
+ while (currentPath.parentPath && t.isJSXFragment(currentPath.parentPath.node)) {
13315
+ currentPath = currentPath.parentPath;
13316
+ }
13317
+ return currentPath;
13237
13318
  }
13238
13319
  function flattenFragmentChildren(parent) {
13239
13320
  if (!parent || !parent.children) return [];
@@ -13260,41 +13341,35 @@ function getPartMetaStringLiteral(partsMeta) {
13260
13341
  const secondaryIndex = getSlimIndex(isAttribute ? part.attributeIndex : part.prevChildIndex);
13261
13342
  return `${combinedBooleanCode}|${primaryIndex}|${secondaryIndex}`;
13262
13343
  });
13263
- return partsMetaWithShortKeys.join(",");
13344
+ return t.stringLiteral(partsMetaWithShortKeys.join(","));
13264
13345
  }
13265
13346
  function getNonFragmentParent(path) {
13266
- let currentPath = path;
13267
- while (currentPath && currentPath.parentPath) {
13268
- const parentNode = currentPath.parentPath.node;
13269
- if (!t.isJSXFragment(parentNode)) {
13270
- return parentNode;
13271
- }
13272
- currentPath = currentPath.parentPath;
13273
- }
13274
- return null;
13347
+ const effectivePath = getEffectiveNodePath(path);
13348
+ const parentNode = effectivePath.parentPath ? effectivePath.parentPath.node : null;
13349
+ if (parentNode && !isValidTemplateElement(parentNode)) return parentNode;
13350
+ return parentNode;
13275
13351
  }
13276
13352
  function getPreviousSiblingIndex(path) {
13277
13353
  const { node } = path;
13278
13354
  const parent = getNonFragmentParent(path);
13279
- if (!parent) return { prevChildIndex: -1, hasExpressionSibling: false };
13355
+ if (!parent) return {};
13280
13356
  const children = flattenFragmentChildren(parent);
13281
- const nodeIndex = children.indexOf(node);
13282
- if (nodeIndex === -1) return { prevChildIndex: -1, hasExpressionSibling: false };
13357
+ if (!children.length) return {};
13283
13358
  const validChildren = children.filter((child) => {
13284
13359
  if (t.isJSXText(child)) {
13285
13360
  return !!cleanStringForHtml(child.value);
13286
- } else if (child.type === "JSXExpressionContainer" && t.isJSXEmptyExpression(child.expression)) {
13361
+ } else if (t.isJSXExpressionContainer(child) && t.isJSXEmptyExpression(child.expression)) {
13287
13362
  return false;
13288
13363
  }
13289
13364
  return true;
13290
13365
  });
13291
- const validNodeIndex = validChildren.indexOf(node);
13292
- const prevSibling = validChildren[validNodeIndex - 1];
13366
+ const nodeIndex = validChildren.indexOf(node);
13367
+ if (nodeIndex === -1) return {};
13368
+ const prevSibling = validChildren[nodeIndex - 1];
13293
13369
  const hasExpressionSibling = !!prevSibling && !isValidTemplateElement(prevSibling);
13294
13370
  let prevChildIndex = -1;
13295
- for (let i = 0; i <= validNodeIndex; i++) {
13296
- const child = validChildren[i];
13297
- if (isValidTemplateElement(child) || i > 0 && !isValidTemplateElement(validChildren[i - 1])) {
13371
+ for (let i = 0; i <= nodeIndex; i++) {
13372
+ if (isValidTemplateElement(validChildren[i]) || i > 0 && !isValidTemplateElement(validChildren[i - 1])) {
13298
13373
  prevChildIndex += 1;
13299
13374
  }
13300
13375
  }
@@ -13303,19 +13378,106 @@ function getPreviousSiblingIndex(path) {
13303
13378
  hasExpressionSibling
13304
13379
  };
13305
13380
  }
13381
+ function isHTMLNode(node) {
13382
+ if (!t.isJSXElement(node)) return false;
13383
+ const nameNode = node.openingElement.name;
13384
+ const tagName = nameNode.name;
13385
+ return isHTMLElement(tagName) && tagName !== "svg";
13386
+ }
13387
+ function isRenderableText(node) {
13388
+ return t.isJSXText(node) && !!cleanStringForHtml(node.value);
13389
+ }
13306
13390
  function isWrappedWithString(path) {
13391
+ const effectivePath = getEffectiveNodePath(path);
13307
13392
  const parent = getNonFragmentParent(path);
13308
13393
  if (!parent) return false;
13309
13394
  const children = flattenFragmentChildren(parent);
13310
- const nodeIndex = children.indexOf(path.node);
13311
- if (nodeIndex <= 0 || nodeIndex >= children.length - 1) return false;
13395
+ let nodeIndex = children.indexOf(effectivePath.node);
13312
13396
  const prevNode = children[nodeIndex - 1];
13313
- const nextNode = children[nodeIndex + 1];
13314
- const isRenderableText = (n) => t.isJSXText(n) && !!cleanStringForHtml(n.value);
13315
- return isRenderableText(prevNode) && isRenderableText(nextNode);
13397
+ if (!(prevNode && isRenderableText(prevNode))) return false;
13398
+ let nextNode;
13399
+ while (nextNode = children[nodeIndex + 1]) {
13400
+ if (isRenderableText(nextNode)) {
13401
+ return true;
13402
+ } else if (t.isJSXExpressionContainer(nextNode) || !isHTMLNode(nextNode)) {
13403
+ nodeIndex += 1;
13404
+ } else {
13405
+ return false;
13406
+ }
13407
+ }
13408
+ return false;
13409
+ }
13410
+
13411
+ // src/plugin/svg.js
13412
+ function isSvgHasDynamicPart(part) {
13413
+ let hasDynamicPart = false;
13414
+ function walk(node) {
13415
+ if (hasDynamicPart) return;
13416
+ if (!node || typeof node !== "object") return;
13417
+ if (node.type === "JSXSpreadAttribute") {
13418
+ hasDynamicPart = true;
13419
+ return;
13420
+ }
13421
+ if (node.type === "JSXExpressionContainer") {
13422
+ hasDynamicPart = true;
13423
+ return;
13424
+ }
13425
+ if (node.type === "JSXElement") {
13426
+ const nameNode = node.openingElement.name;
13427
+ if (nameNode.type === "JSXMemberExpression") {
13428
+ hasDynamicPart = true;
13429
+ return;
13430
+ }
13431
+ const tagName = nameNode.name;
13432
+ if (!isHTMLElement(tagName)) {
13433
+ hasDynamicPart = true;
13434
+ return;
13435
+ }
13436
+ }
13437
+ for (const key in node) {
13438
+ if (key === "parent" || key === "parentPath" || key === "loc") continue;
13439
+ const val = node[key];
13440
+ if (Array.isArray(val)) {
13441
+ val.forEach(walk);
13442
+ } else if (val && typeof val === "object") {
13443
+ walk(val);
13444
+ }
13445
+ }
13446
+ }
13447
+ walk(part.node);
13448
+ return hasDynamicPart;
13316
13449
  }
13317
13450
 
13318
13451
  // src/plugin/taggedTemplate.js
13452
+ function jsxNameToExpression(node) {
13453
+ if (node.type === "JSXIdentifier") {
13454
+ return { type: "Identifier", name: node.name };
13455
+ } else if (node.type === "JSXMemberExpression") {
13456
+ return {
13457
+ type: "MemberExpression",
13458
+ object: jsxNameToExpression(node.object),
13459
+ property: jsxNameToExpression(node.property),
13460
+ computed: false
13461
+ };
13462
+ }
13463
+ throw new Error(`Unsupported JSX name type: ${node.type}`);
13464
+ }
13465
+ function needsToBeJSXCall(path) {
13466
+ const { node } = path;
13467
+ if (node.type === "JSXFragment") return false;
13468
+ const nameNode = node.openingElement.name;
13469
+ if (nameNode.type === "JSXMemberExpression") return true;
13470
+ const tagName = nameNode.name;
13471
+ if (!isHTMLElement(tagName)) return true;
13472
+ if (tagName === "svg" && isSvgHasDynamicPart(path)) return true;
13473
+ return node.openingElement.attributes.some(
13474
+ (attr) => attr.type === "JSXAttribute" && attr.name.name === "key"
13475
+ );
13476
+ }
13477
+ function getAttrValue(value) {
13478
+ if (!value) return { type: "Literal", value: true };
13479
+ return value.type === "JSXExpressionContainer" ? value.expression : { type: "Literal", value: value.value };
13480
+ }
13319
13481
  function getLiteralParts(rootPath) {
13320
13482
  const strings = [];
13321
13483
  const expressions = [];
@@ -13337,120 +13499,111 @@ function getLiteralParts(rootPath) {
13337
13499
  const refNodeIndex = isAttribute ? elementCounter - 1 : parent ? parent.elementCounter : 0;
13338
13500
  let partMeta = { refNodeIndex, isAttribute };
13339
13501
  if (isAttribute) {
13340
- partMeta.attributeIndex = path.node.staticAttributes ? path.node.staticAttributes.length : 0;
13502
+ const elementNode = path.parentPath.node;
13503
+ partMeta.attributeIndex = elementNode.staticAttributes ? elementNode.staticAttributes.length : 0;
13341
13504
  } else {
13342
13505
  partMeta = { ...partMeta, ...getPreviousSiblingIndex(path) };
13343
13506
  }
13344
13507
  partsMeta.push(partMeta);
13345
13508
  expressions.push(expression);
13509
+ return expression;
13510
+ }
13511
+ function pushAttributeToExpressions(expression, lastExpression, path) {
13512
+ if (lastExpression && lastExpression.type === "ObjectExpression") {
13513
+ const props = expression.type === "ObjectExpression" ? expression.properties : [{ type: "SpreadElement", argument: expression }];
13514
+ lastExpression.properties.push(...props);
13515
+ return lastExpression;
13516
+ }
13517
+ pushToExpressions(expression, path, true);
13518
+ stringPart.push(" ");
13519
+ return expression;
13346
13520
  }
13347
13521
  function recursePath(path) {
13348
- if (!path || !path.node) return;
13522
+ if (!path) return;
13523
+ if (Array.isArray(path)) {
13524
+ path.forEach(recursePath);
13525
+ return;
13526
+ }
13527
+ if (!path.node) return;
13349
13528
  const { node } = path;
13350
- if (t.isJSXElement(node) || t.isJSXFragment(node)) {
13351
- if (t.isJSXElement(node)) {
13352
- const { openingElement } = node;
13353
- const tagName = openingElement.name.name;
13354
- if (isHTMLElement(tagName)) {
13355
- node.elementCounter = elementCounter;
13356
- node.staticAttributes = [];
13357
- elementCounter += 1;
13358
- stringPart.push(`<${tagName}`);
13359
- openingElement.attributes.forEach((attr) => {
13360
- if (t.isJSXSpreadAttribute(attr)) {
13361
- const attrPath = createPath(attr, path);
13362
- pushToExpressions(attr.argument, attrPath, true);
13363
- stringPart.push(" ");
13529
+ if (node.type === "JSXElement") {
13530
+ const { openingElement } = node;
13531
+ const nameNode = openingElement.name;
13532
+ if (!needsToBeJSXCall(path)) {
13533
+ const tagName = nameNode.name;
13534
+ node.elementCounter = elementCounter;
13535
+ node.staticAttributes = [];
13536
+ elementCounter += 1;
13537
+ stringPart.push(`<${tagName} `);
13538
+ let lastExpression = null;
13539
+ openingElement.attributes.forEach((attr) => {
13540
+ if (attr.type === "JSXSpreadAttribute") {
13541
+ lastExpression = pushAttributeToExpressions(attr.argument, lastExpression, createPath(attr, path));
13542
+ } else {
13543
+ const { name, value } = attr;
13544
+ const attrNameStr = getAttributeName(name);
13545
+ if (needsToBeExpression(tagName, attrNameStr) || value && value.type === "JSXExpressionContainer") {
13546
+ const expr = createAttributeExpression(name, value);
13547
+ lastExpression = pushAttributeToExpressions(expr, lastExpression, createPath(attr, path));
13364
13548
  } else {
13365
- const { name, value } = attr;
13366
- let attrName = name.name;
13367
- if (needsToBeExpression(tagName, attrName) || value && t.isJSXExpressionContainer(value)) {
13368
- const expr = createAttributeExpression(name, value);
13369
- const attrPath = createPath(attr, path);
13370
- pushToExpressions(expr, attrPath, true);
13371
- stringPart.push(" ");
13372
- } else {
13373
- attrName = PROPERTY_ATTRIBUTE_MAP[attrName] || attrName;
13374
- let attrString = ` ${attrName}`;
13375
- if (value) {
13376
- const attrValue = value.value;
13377
- const quote = attrValue.includes('"') ? `'` : `"`;
13378
- attrString = `${attrString}=${quote}${attrValue}${quote}`;
13379
- }
13380
- stringPart.push(attrString);
13381
- node.staticAttributes.push(attr);
13549
+ const attrName = PROPERTY_ATTRIBUTE_MAP[attrNameStr] || attrNameStr;
13550
+ let attrString = ` ${attrName}`;
13551
+ if (value) {
13552
+ const attrValue = value.value;
13553
+ const quote = attrValue.includes('"') ? "'" : '"';
13554
+ attrString = `${attrString}=${quote}${attrValue}${quote}`;
13382
13555
  }
13556
+ stringPart.push(attrString);
13557
+ node.staticAttributes.push(attr);
13558
+ lastExpression = null;
13383
13559
  }
13384
- });
13385
- stringPart.push(">");
13386
- const children2 = path.get("children");
13387
- if (Array.isArray(children2)) {
13388
- children2.forEach((child) => recursePath(child));
13389
- }
13390
- if (!SELF_CLOSING_TAGS.includes(tagName)) {
13391
- stringPart.push(`</${tagName}>`);
13392
13560
  }
13393
- return;
13394
- } else {
13395
- const propsProperties = [];
13396
- openingElement.attributes.forEach((attr) => {
13397
- if (t.isJSXAttribute(attr)) {
13398
- let attrName = attr.name.name;
13399
- const value = attr.value;
13400
- let valNode;
13401
- attrName = PROPERTY_ATTRIBUTE_MAP[attrName] || attrName;
13402
- if (!value) {
13403
- valNode = { type: "Literal", value: true };
13404
- } else if (t.isJSXExpressionContainer(value)) {
13405
- valNode = value.expression;
13406
- } else {
13407
- valNode = { type: "Literal", value: value.value };
13408
- }
13409
- propsProperties.push({
13410
- type: "Property",
13411
- key: { type: "Identifier", name: attrName },
13412
- value: valNode,
13413
- kind: "init"
13414
- });
13415
- } else if (t.isJSXSpreadAttribute(attr)) {
13416
- propsProperties.push({
13417
- type: "SpreadElement",
13418
- argument: attr.argument
13419
- });
13561
+ });
13562
+ stringPart.push(">");
13563
+ path.get("children").forEach(recursePath);
13564
+ if (!SELF_CLOSING_TAGS.includes(tagName)) stringPart.push(`</${tagName}>`);
13565
+ } else {
13566
+ const propsProperties = [];
13567
+ let keyValue = null;
13568
+ openingElement.attributes.forEach((attr) => {
13569
+ if (attr.type === "JSXAttribute") {
13570
+ const attrName = attr.name.name;
13571
+ const valNode = getAttrValue(attr.value);
13572
+ if (attrName === "key") {
13573
+ keyValue = valNode;
13574
+ } else {
13575
+ propsProperties.push({ type: "Property", key: { type: "Identifier", name: attrName }, value: valNode, kind: "init" });
13420
13576
  }
13577
+ } else if (attr.type === "JSXSpreadAttribute") {
13578
+ propsProperties.push({ type: "SpreadElement", argument: attr.argument });
13579
+ }
13580
+ });
13581
+ const childrenPaths = path.get("children");
13582
+ if (childrenPaths && childrenPaths.length) {
13583
+ propsProperties.push({
13584
+ type: "Property",
13585
+ key: { type: "Identifier", name: "children" },
13586
+ value: transformToAstNode(getTaggedTemplate(childrenPaths)),
13587
+ kind: "init"
13421
13588
  });
13422
- let extractedText = "";
13423
- const children2 = path.get("children");
13424
- if (Array.isArray(children2)) {
13425
- children2.forEach((cp) => {
13426
- if (t.isJSXText(cp.node)) {
13427
- extractedText += cleanStringForHtml(cp.node.value);
13428
- }
13429
- });
13430
- }
13431
- const callExpr = {
13432
- type: "CallExpression",
13433
- callee: { type: "Identifier", name: "jsx" },
13434
- arguments: [
13435
- { type: "Identifier", name: tagName },
13436
- { type: "ObjectExpression", properties: propsProperties },
13437
- { type: "Literal", value: extractedText }
13438
- ]
13439
- };
13440
- pushToExpressions(callExpr, path, false);
13441
- return;
13442
13589
  }
13443
- }
13444
- const children = path.get("children");
13445
- if (Array.isArray(children)) {
13446
- children.forEach((child) => recursePath(child));
13447
- }
13448
- } else if (t.isJSXText(node)) {
13590
+ pushToExpressions({
13591
+ type: "CallExpression",
13592
+ callee: {
13593
+ type: "Identifier",
13594
+ name: "_brahmosJSX"
13595
+ },
13596
+ arguments: keyValue ? [jsxNameToExpression(nameNode), { type: "ObjectExpression", properties: propsProperties }, keyValue] : [jsxNameToExpression(nameNode), { type: "ObjectExpression", properties: propsProperties }]
13597
+ }, path, false);
13598
+ }
13599
+ } else if (node.type === "JSXFragment") {
13600
+ path.get("children").forEach(recursePath);
13601
+ } else if (node.type === "JSXText") {
13449
13602
  const cleanStr = cleanStringForHtml(node.value);
13450
13603
  if (cleanStr) stringPart.push(cleanStr);
13451
- } else if (t.isJSXExpressionContainer(node) && !t.isJSXEmptyExpression(node.expression)) {
13604
+ } else if (node.type === "JSXExpressionContainer" && node.expression.type !== "JSXEmptyExpression") {
13452
13605
  if (isWrappedWithString(path)) {
13453
- stringPart.push("");
13606
+ stringPart.push(`<!--${BRAHMOS_PLACEHOLDER}-->`);
13454
13607
  }
13455
13608
  pushToExpressions(node.expression, path, false);
13456
13609
  }
@@ -13459,33 +13612,51 @@ function getLiteralParts(rootPath) {
13459
13612
  pushToStrings(true);
13460
13613
  return { strings, expressions, partsMeta };
13461
13614
  }
13462
- function getTaggedTemplate(node) {
13463
- const path = createPath(node);
13464
- const { strings, expressions, partsMeta } = getLiteralParts(path);
13465
- if (expressions.length === 1 && isEmptyLiteralWrap(strings)) {
13466
- return expressions[0];
13615
+ function getSingleTextChild(path) {
13616
+ let jsxText;
13617
+ if (Array.isArray(path) && path.length === 1 && path[0].node.type === "JSXText") {
13618
+ jsxText = path[0].node;
13619
+ } else if (path.node && path.node.type === "JSXFragment" && path.node.children.length === 1 && path.node.children[0].type === "JSXText") {
13620
+ jsxText = path.node.children[0];
13621
+ }
13622
+ return jsxText && { type: "Literal", value: cleanStringForHtml(jsxText.value) };
13623
+ }
13624
+ function getTaggedTemplate(nodeOrPath) {
13625
+ let path;
13626
+ if (Array.isArray(nodeOrPath) || nodeOrPath.node && nodeOrPath.get) {
13627
+ path = nodeOrPath;
13628
+ } else {
13629
+ path = createPath(nodeOrPath);
13467
13630
  }
13468
- const metaStr = getPartMetaStringLiteral(partsMeta);
13631
+ const singleTextChild = getSingleTextChild(path);
13632
+ if (singleTextChild) return singleTextChild;
13633
+ const { strings, expressions, partsMeta } = getLiteralParts(path);
13634
+ if (expressions.length === 1 && isEmptyLiteralWrap(strings)) return expressions[0];
13469
13635
  return {
13470
13636
  type: "TaggedTemplateExpression",
13471
- tag: "html",
13637
+ tag: "_brahmosHtml",
13472
13638
  template: {
13639
+ type: "TemplateLiteral",
13473
13640
  strings,
13474
13641
  expressions
13475
13642
  },
13476
- meta: metaStr
13643
+ meta: getPartMetaStringLiteral(partsMeta)
13477
13644
  };
13478
13645
  }
13479
13646
 
13480
13647
  // src/plugin/walkAndTransform.js
13481
13648
  function walkAndTransform(node) {
13482
13649
  if (!node || typeof node !== "object") return node;
13650
+ if (node.type === "Program") {
13651
+ addBrahmosRuntime(createPath(node));
13652
+ }
13483
13653
  if (Array.isArray(node)) {
13484
13654
  return node.map(walkAndTransform);
13485
13655
  }
13486
13656
  if (node.type === "JSXElement" || node.type === "JSXFragment") {
13487
13657
  const result = getTaggedTemplate(node);
13488
- return transformToAstNode(result);
13658
+ const astNode = transformToAstNode(result);
13659
+ return walkAndTransform(astNode);
13489
13660
  }
13490
13661
  const newNode = { ...node };
13491
13662
  for (const key in newNode) {
@@ -13495,36 +13666,6 @@ function walkAndTransform(node) {
13495
13666
  }
13496
13667
  return newNode;
13497
13668
  }
13498
- function transformToAstNode(res) {
13499
- if (typeof res === "string") {
13500
- return { type: "Literal", value: res, raw: `'${res}'` };
13501
- }
13502
- if (res.type === "TaggedTemplateExpression") {
13503
- return {
13504
- type: "CallExpression",
13505
- callee: {
13506
- type: "TaggedTemplateExpression",
13507
- // tag name uses 'html' etc. passed from getTaggedTemplate
13508
- tag: { type: "Identifier", name: res.tag },
13509
- quasi: {
13510
- type: "TemplateLiteral",
13511
- quasis: res.template.strings.map((s) => ({
13512
- type: "TemplateElement",
13513
- // astring requires value: { raw, cooked } to output the content
13514
- value: {
13515
- raw: s.value.raw || "",
13516
- cooked: s.value.cooked || ""
13517
- },
13518
- tail: s.tail
13519
- })),
13520
- expressions: res.template.expressions
13521
- }
13522
- },
13523
- arguments: [{ type: "Literal", value: res.meta, raw: `'${res.meta}'` }]
13524
- };
13525
- }
13526
- return res;
13527
- }
13528
13669
 
13529
13670
  // src/plugin/transformer.js
13530
13671
  var parser = Parser.extend((0, import_acorn_jsx.default)());
@@ -13533,36 +13674,7 @@ function transformCode(source) {
13533
13674
  ecmaVersion: "latest",
13534
13675
  sourceType: "module"
13535
13676
  });
13536
- const LIBRARY_NAME = "potatejs";
13537
- const IMPORT_NAME = "html";
13538
- let isHtmlImported = false;
13539
- for (const node of ast.body) {
13540
- if (node.type === "ImportDeclaration" && node.source.value === LIBRARY_NAME) {
13541
- if (node.specifiers.some((s) => s.imported && s.imported.name === IMPORT_NAME)) {
13542
- isHtmlImported = true;
13543
- break;
13544
- }
13545
- }
13546
- }
13547
13677
  const transformedAst = walkAndTransform(ast);
13548
- const needsHtml = JSON.stringify(transformedAst).includes(`"name":"${IMPORT_NAME}"`);
13549
- if (needsHtml && !isHtmlImported) {
13550
- transformedAst.body.unshift({
13551
- type: "ImportDeclaration",
13552
- specifiers: [
13553
- {
13554
- type: "ImportSpecifier",
13555
- imported: { type: "Identifier", name: IMPORT_NAME },
13556
- local: { type: "Identifier", name: IMPORT_NAME }
13557
- }
13558
- ],
13559
- source: {
13560
- type: "Literal",
13561
- value: LIBRARY_NAME,
13562
- raw: `'${LIBRARY_NAME}'`
13563
- }
13564
- });
13565
- }
13566
13678
  return generate(transformedAst);
13567
13679
  }
13568
13680