@jxsuite/compiler 0.34.0 → 0.34.1

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/dist/cli.js CHANGED
@@ -249,7 +249,7 @@ Build complete: ${A.length} routes, ${_} files`),J.length>0)G(` ${J.length} err
249
249
  ${R.rules.join(`
250
250
  `)}
251
251
  </style>
252
- </head>`);u.html=IV(u.html,d,W.defaults?.lang??"en");let i=(V.$elements??[]).filter((b)=>typeof b==="string"&&!b.startsWith("./")&&!b.startsWith("../"));if(i.length>0)u.html=MV(u.html,i);let m=null;if(!W.build?.adapter)try{let b=await n4(Z.sourcePath);if(b)m=b}catch{}return{doc:V,excludeFromSitemap:K.$sitemap===!1,files:u.files,html:u.html,serverHandler:m}}function QX(Z,W){return Z.map((X)=>{if(!X||typeof X!=="object")return X;let Q={...X};if(Q.attributes){Q.attributes={...Q.attributes};for(let[J,G]of Object.entries(Q.attributes))if(typeof G==="string"&&a(G))Q.attributes[J]=C0(G,W)??G}if(typeof Q.textContent==="string"&&a(Q.textContent))Q.textContent=C0(Q.textContent,W)??Q.textContent;return Q})}function FV(Z){return Z.map((W)=>{if(!W||typeof W!=="object"||!W.attributes)return W;let X={...W,attributes:{...W.attributes}};for(let Q of["href","src"]){let J=X.attributes[Q];if(typeof J==="string"&&LV(J))X.attributes[Q]=`/node_modules/${J}`}return X})}function LV(Z){return!Z.startsWith("/")&&!Z.startsWith("./")&&!Z.startsWith("../")&&!Z.startsWith("http")&&!Z.startsWith("data:")}function GX(Z,W){if(!Z||typeof Z!=="object")return Z;let X={};for(let[Q,J]of Object.entries(Z))if(Q==="children"&&Array.isArray(J))X.children=J.map((G)=>{if(typeof G==="string")return G;return GX(G,W)});else if(Q==="style"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U))G[Y]=H1(U,W)??U;X.style=G}else if(Q==="attributes"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U))G[Y]=H1(U,W)??U;X.attributes=G}else if(Q==="$props"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U)){let K=H1(U,W);G[Y]=K!==null?K??null:U}X.$props=G}else if(typeof J==="string"&&a(J))X[Q]=H1(J,W)??J;else X[Q]=J;return X}function H1(Z,W){try{let X=W.$map?.item,Q=W.$map?.index,J=Z.match(/^\$\{(.+)\}$/s);if(J)return Function("state","$map","item","index",`return (${J[1]})`)(W,W.$map,X,Q);return Function("state","$map","item","index",`return \`${Z}\``)(W,W.$map,X,Q)}catch{return null}}function U2(Z,W){if(!Z||typeof Z!=="object")return;if(typeof Z.innerHTML==="string"&&a(Z.innerHTML)){let Q=C0(Z.innerHTML,W);if(Q!=null)Z.innerHTML=String(Q).replaceAll("${","&#36;{")}if(typeof Z.textContent==="string"&&a(Z.textContent))Z.textContent=C0(Z.textContent,W)??Z.textContent;if(Z.style&&typeof Z.style==="object"){for(let[Q,J]of Object.entries(Z.style))if(typeof J==="string"&&a(J))Z.style[Q]=C0(J,W)??J}if(Z.attributes&&typeof Z.attributes==="object"){for(let[Q,J]of Object.entries(Z.attributes))if(typeof J==="string"&&a(J))Z.attributes[Q]=C0(J,W)??J}if(Z.$props&&typeof Z.$props==="object"){for(let[Q,J]of Object.entries(Z.$props))if(typeof J==="string"&&a(J))Z.$props[Q]=C0(J,W)??J}let X=Z.children;if(R0(X)){let Q=JX(X,W);if(Q){Z.children=Q;return}}if(typeof X==="string"&&a(X)){let Q=C0(X,W);if(Array.isArray(Q)){let J=Q;Z.children=J;for(let G of J)U2(G,W)}}else if(Array.isArray(Z.children)){let Q=0;while(Q<Z.children.length){let J=Z.children[Q];if(typeof J==="string"&&a(J)){let G=C0(J,W);if(Array.isArray(G)){let Y=G;Z.children.splice(Q,1,...Y);for(let U of Y)U2(U,W);Q+=Y.length;continue}}if(R0(J)){let G=JX(J,W);if(G){Z.children.splice(Q,1,...G),Q+=G.length;continue}}U2(J,W),Q+=1}}}function JX(Z,W){let X=Z.items,Q=null;if(f0(X))Q=C1(X.$ref,W);else if(Array.isArray(X))Q=X;let J=Z.map;if(!Array.isArray(Q)||!J)return null;return Q.map((G,Y)=>{let U=Object.create(W);U.$map={index:Y,item:G},U["$map/item"]=G,U["$map/index"]=Y;let K=GX(J,U);return U2(K,U),K})}function K8(Z,W,X){if(!Z||typeof Z!=="object")return;if(Array.isArray(Z)){for(let J of Z)K8(J,W,X);return}if(Array.isArray(Z.children))for(let J of Z.children)K8(J,W,X);let Q=W.get(Z.tagName);if(Q){let J=Array.isArray(Z.children)&&Z.children.length>0?Z.children.map((U)=>{if(X&&U&&typeof U==="object")v6(U,X.rules,X.media,"",X.counter,"jxs");return Y4(U,{},null)}).join(`
252
+ </head>`);u.html=IV(u.html,d,W.defaults?.lang??"en");let i=(V.$elements??[]).filter((b)=>typeof b==="string"&&!b.startsWith("./")&&!b.startsWith("../"));if(i.length>0)u.html=MV(u.html,i);let m=null;if(!W.build?.adapter)try{let b=await n4(Z.sourcePath);if(b)m=b}catch{}return{doc:V,excludeFromSitemap:K.$sitemap===!1,files:u.files,html:u.html,serverHandler:m}}function QX(Z,W){return Z.map((X)=>{if(!X||typeof X!=="object")return X;let Q={...X};if(Q.attributes){Q.attributes={...Q.attributes};for(let[J,G]of Object.entries(Q.attributes))if(typeof G==="string"&&a(G))Q.attributes[J]=C0(G,W)??G}if(typeof Q.textContent==="string"&&a(Q.textContent))Q.textContent=C0(Q.textContent,W)??Q.textContent;return Q})}function FV(Z){return Z.map((W)=>{if(!W||typeof W!=="object"||!W.attributes)return W;let X={...W,attributes:{...W.attributes}};for(let Q of["href","src"]){let J=X.attributes[Q];if(typeof J==="string"&&LV(J))X.attributes[Q]=`/node_modules/${J}`}return X})}function LV(Z){return!Z.startsWith("/")&&!Z.startsWith("./")&&!Z.startsWith("../")&&!Z.startsWith("http")&&!Z.startsWith("data:")}function GX(Z,W){if(!Z||typeof Z!=="object")return Z;let X={};for(let[Q,J]of Object.entries(Z))if(Q==="children"&&Array.isArray(J))X.children=J.map((G)=>{if(typeof G==="string")return G;return GX(G,W)});else if(Q==="style"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U))G[Y]=H1(U,W)??U;X.style=G}else if(Q==="attributes"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U))G[Y]=H1(U,W)??U;X.attributes=G}else if(Q==="$props"&&J&&typeof J==="object"){let G={...J};for(let[Y,U]of Object.entries(G))if(a(U)){let K=H1(U,W);G[Y]=K!==null?K??null:U}X.$props=G}else if(typeof J==="string"&&a(J))X[Q]=H1(J,W)??J;else X[Q]=J;return X}function H1(Z,W){try{let X=W.$map?.item,Q=W.$map?.index,J=Z.match(/^\$\{(.+)\}$/s);if(J)return Function("state","$map","item","index",`return (${J[1]})`)(W,W.$map,X,Q);return Function("state","$map","item","index",`return \`${Z}\``)(W,W.$map,X,Q)}catch{return null}}function U2(Z,W){if(!Z||typeof Z!=="object")return;if(typeof Z.innerHTML==="string"&&a(Z.innerHTML)){let Q=C0(Z.innerHTML,W);if(Q!=null)Z.innerHTML=String(Q).replaceAll("${","&#36;{")}if(typeof Z.textContent==="string"&&a(Z.textContent))Z.textContent=C0(Z.textContent,W)??Z.textContent;if(Z.style&&typeof Z.style==="object"){for(let[Q,J]of Object.entries(Z.style))if(typeof J==="string"&&a(J))Z.style[Q]=C0(J,W)??J}if(Z.attributes&&typeof Z.attributes==="object"){for(let[Q,J]of Object.entries(Z.attributes))if(typeof J==="string"&&a(J))Z.attributes[Q]=C0(J,W)??J}if(Z.$props&&typeof Z.$props==="object"){for(let[Q,J]of Object.entries(Z.$props))if(typeof J==="string"&&a(J))Z.$props[Q]=C0(J,W)??J}let X=Z.children;if(R0(X)){let Q=JX(X,W);if(Q){Z.children=Q;return}}if(typeof X==="string"&&a(X)){let Q=C0(X,W);if(Array.isArray(Q)){let J=Q;Z.children=J;for(let G of J)U2(G,W)}}else if(Array.isArray(Z.children)){let Q=0;while(Q<Z.children.length){let J=Z.children[Q];if(typeof J==="string"&&a(J)){let G=C0(J,W);if(Array.isArray(G)){let Y=G;Z.children.splice(Q,1,...Y);for(let U of Y)U2(U,W);Q+=Y.length;continue}}if(R0(J)){let G=JX(J,W);if(G){Z.children.splice(Q,1,...G),Q+=G.length;continue}}U2(J,W),Q+=1}}}function JX(Z,W){let X=Z.items,Q=null;if(f0(X))Q=C1(X.$ref,W);else if(Array.isArray(X))Q=X;let J=Z.map;if(!Array.isArray(Q)||!J)return null;return Q.map((G,Y)=>{let U=Object.create(W);U.$map={index:Y,item:G},U["$map/item"]=G,U["$map/index"]=Y;let K=GX(J,U);return U2(K,U),K})}function K8(Z,W,X){if(!Z||typeof Z!=="object")return;if(Array.isArray(Z)){for(let J of Z)K8(J,W,X);return}if(Array.isArray(Z.children))for(let J of Z.children)K8(J,W,X);let Q=W.get(Z.tagName);if(Q){if(Z.attributes){let U=null;for(let[K,V]of Object.entries(Z.attributes))if(K.startsWith("props.")&&K.length>6)U??={},U[K.slice(6)]=V,delete Z.attributes[K];if(U)Z.$props={...U,...Z.$props}}let J=Array.isArray(Z.children)&&Z.children.length>0?Z.children.map((U)=>{if(X&&U&&typeof U==="object")v6(U,X.rules,X.media,"",X.counter,"jxs");return Y4(U,{},null)}).join(`
253
253
  `):null,G=R8(Q,Z.$props||null,J),Y=x1(Q);if(Z.innerHTML=G,delete Z.children,Q.style&&Z.$props){let U={...Q.state};for(let[H,B]of Object.entries(Z.$props))U[H]=H in U?B:B;let K=V4(U,null),V={};for(let[H,B]of Object.entries(Q.style))if(typeof B==="string"&&a(B)){let $=$0(B,K);if($!=null)V[H]=$}if(Object.keys(V).length>0)Z.style={...Z.style,...V}}if(delete Z.$props,Y)Z.$static=!0;else Z.$prerendered=!0}}function AV(Z,W,X=new Map,Q=new Set){let J=W.filter(($)=>Z.includes(`<${$}`));if(J.length===0)return Z;let G=J.filter(($)=>X.has($)).map(($)=>`<link rel="stylesheet" href="/components/${$}.css">`).join(`
254
254
  `),Y=Z;if(G)Y=Y.replace("</head>",` ${G}
255
255
  </head>`);let U=J.filter(($)=>!Q.has($));if(U.length===0)return Y;let K=`<script type="importmap">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/compiler",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "Jx static HTML compiler, island detector, and site builder",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,8 +43,8 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@apidevtools/json-schema-ref-parser": "^15.4.0",
46
- "@jxsuite/parser": "^0.34.0",
47
- "@jxsuite/runtime": "^0.34.0",
46
+ "@jxsuite/parser": "^0.35.0",
47
+ "@jxsuite/runtime": "^0.34.1",
48
48
  "@jxsuite/schema": "^0.34.0",
49
49
  "sharp": "^0.35.3"
50
50
  },
@@ -957,6 +957,27 @@ function expandComponents(
957
957
 
958
958
  const def = componentDefs.get(node.tagName as string);
959
959
  if (def) {
960
+ // JSON-authored instances pass props as literal `props.*` attribute keys (markdown directives
961
+ // Are normalized to $props by the parser's expandDotPaths, but JSON is parsed verbatim).
962
+ // Lift them into $props so the pre-render sees them, and strip them from attributes so they
963
+ // Don't leak into the emitted HTML. Values stay raw strings — no coercion, matching the
964
+ // Markdown path and the runtime's $props semantics. Explicit $props wins on key conflicts.
965
+ if (node.attributes) {
966
+ let lifted: NonNullable<JxElement["$props"]> | null = null;
967
+ for (const [key, value] of Object.entries(node.attributes)) {
968
+ if (key.startsWith("props.") && key.length > "props.".length) {
969
+ lifted ??= {};
970
+ // JxAttributeValue is JSON-representable (primitives or a $ref object), so the
971
+ // Narrowing to JsonValue is sound.
972
+ lifted[key.slice("props.".length)] = value as JsonValue;
973
+ delete node.attributes[key];
974
+ }
975
+ }
976
+ if (lifted) {
977
+ node.$props = { ...lifted, ...node.$props };
978
+ }
979
+ }
980
+
960
981
  const slotContent =
961
982
  Array.isArray(node.children) && node.children.length > 0
962
983
  ? node.children