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