@constela/start 1.0.0 → 1.1.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.
Files changed (2) hide show
  1. package/dist/index.js +152 -20
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -460,6 +460,38 @@ function isCustomComponent(name) {
460
460
  if (!name) return false;
461
461
  return /^[A-Z]/.test(name);
462
462
  }
463
+ var DISALLOWED_PATTERNS = [
464
+ /\bfunction\b/i,
465
+ /\b(eval|Function|setTimeout|setInterval)\b/,
466
+ /\bimport\b/,
467
+ /\brequire\b/,
468
+ /\bfetch\b/,
469
+ /\bwindow\b/,
470
+ /\bdocument\b/,
471
+ /\bglobal\b/,
472
+ /\bprocess\b/,
473
+ /\b__proto__\b/,
474
+ /\bconstructor\b/,
475
+ /\bprototype\b/
476
+ ];
477
+ function isSafeLiteral(value) {
478
+ return !DISALLOWED_PATTERNS.some((pattern) => pattern.test(value));
479
+ }
480
+ function safeEvalLiteral(value) {
481
+ try {
482
+ return JSON.parse(value);
483
+ } catch {
484
+ }
485
+ if (!isSafeLiteral(value)) {
486
+ return null;
487
+ }
488
+ try {
489
+ const fn = new Function(`return (${value});`);
490
+ return fn();
491
+ } catch {
492
+ return null;
493
+ }
494
+ }
463
495
  function parseAttributeValue(attr) {
464
496
  if (attr.value === null) {
465
497
  return lit(true);
@@ -474,6 +506,12 @@ function parseAttributeValue(attr) {
474
506
  if (exprValue === "null") return lit(null);
475
507
  const num = Number(exprValue);
476
508
  if (!Number.isNaN(num)) return lit(num);
509
+ if (exprValue.startsWith("[") || exprValue.startsWith("{")) {
510
+ const parsed = safeEvalLiteral(exprValue);
511
+ if (parsed !== null && parsed !== void 0) {
512
+ return lit(parsed);
513
+ }
514
+ }
477
515
  return lit(exprValue);
478
516
  }
479
517
  return lit(null);
@@ -610,36 +648,130 @@ function transformJsxElement(node, ctx) {
610
648
  const children = transformChildren(node.children, ctx);
611
649
  return elementNode(name, props, children);
612
650
  }
651
+ function substituteExpression(expr, props) {
652
+ const exprAny = expr;
653
+ if (exprAny.expr === "param") {
654
+ const paramExpr = expr;
655
+ const propValue = props[paramExpr.name];
656
+ if (!propValue) {
657
+ return { expr: "lit", value: null };
658
+ }
659
+ if (paramExpr.path && propValue.expr === "var") {
660
+ const varExpr = propValue;
661
+ return {
662
+ expr: "var",
663
+ name: varExpr.name,
664
+ path: paramExpr.path
665
+ };
666
+ }
667
+ return propValue;
668
+ }
669
+ if (expr.expr === "bin") {
670
+ const binExpr = expr;
671
+ return {
672
+ expr: "bin",
673
+ op: binExpr.op,
674
+ left: substituteExpression(binExpr.left, props),
675
+ right: substituteExpression(binExpr.right, props)
676
+ };
677
+ }
678
+ if (expr.expr === "not") {
679
+ const notExpr = expr;
680
+ return {
681
+ expr: "not",
682
+ operand: substituteExpression(notExpr.operand, props)
683
+ };
684
+ }
685
+ if (expr.expr === "cond") {
686
+ const condExpr = expr;
687
+ return {
688
+ expr: "cond",
689
+ if: substituteExpression(condExpr.if, props),
690
+ then: substituteExpression(condExpr.then, props),
691
+ else: substituteExpression(condExpr.else, props)
692
+ };
693
+ }
694
+ if (expr.expr === "get") {
695
+ const getExpr = expr;
696
+ return {
697
+ expr: "get",
698
+ base: substituteExpression(getExpr.base, props),
699
+ path: getExpr.path
700
+ };
701
+ }
702
+ return expr;
703
+ }
613
704
  function applyComponentView(view, props, children) {
614
705
  return substituteInNode(view, props, children);
615
706
  }
616
707
  function substituteInNode(node, props, children) {
617
- if (node.kind === "element") {
618
- const elem = node;
619
- const newProps = elem.props ? { ...elem.props } : {};
620
- for (const [key, value] of Object.entries(props)) {
621
- if (!(key in newProps)) {
622
- newProps[key] = value;
708
+ switch (node.kind) {
709
+ case "each": {
710
+ const eachNode = node;
711
+ const result = {
712
+ kind: "each",
713
+ items: substituteExpression(eachNode.items, props),
714
+ as: eachNode.as,
715
+ body: substituteInNode(eachNode.body, props, children)
716
+ };
717
+ if (eachNode.index) {
718
+ result.index = eachNode.index;
719
+ }
720
+ if (eachNode.key) {
721
+ result.key = substituteExpression(eachNode.key, props);
623
722
  }
723
+ return result;
624
724
  }
625
- let newChildren;
626
- if (elem.children) {
627
- newChildren = [];
628
- for (const child of elem.children) {
629
- if (child.kind === "slot") {
630
- newChildren.push(...children);
631
- } else {
632
- newChildren.push(substituteInNode(child, props, children));
725
+ case "text": {
726
+ const textNode2 = node;
727
+ return {
728
+ kind: "text",
729
+ value: substituteExpression(textNode2.value, props)
730
+ };
731
+ }
732
+ case "if": {
733
+ const ifNode = node;
734
+ const result = {
735
+ kind: "if",
736
+ condition: substituteExpression(ifNode.condition, props),
737
+ then: substituteInNode(ifNode.then, props, children)
738
+ };
739
+ if (ifNode.else) {
740
+ result.else = substituteInNode(ifNode.else, props, children);
741
+ }
742
+ return result;
743
+ }
744
+ case "element": {
745
+ const elem = node;
746
+ const newProps = {};
747
+ if (elem.props) {
748
+ for (const [key, value] of Object.entries(elem.props)) {
749
+ newProps[key] = substituteExpression(value, props);
633
750
  }
634
751
  }
752
+ let newChildren;
753
+ if (elem.children) {
754
+ newChildren = [];
755
+ for (const child of elem.children) {
756
+ if (child.kind === "slot") {
757
+ newChildren.push(...children);
758
+ } else {
759
+ newChildren.push(substituteInNode(child, props, children));
760
+ }
761
+ }
762
+ }
763
+ return elementNode(
764
+ elem.tag,
765
+ Object.keys(newProps).length > 0 ? newProps : void 0,
766
+ newChildren && newChildren.length > 0 ? newChildren : void 0
767
+ );
635
768
  }
636
- return elementNode(
637
- elem.tag,
638
- Object.keys(newProps).length > 0 ? newProps : void 0,
639
- newChildren && newChildren.length > 0 ? newChildren : void 0
640
- );
769
+ case "markdown":
770
+ case "code":
771
+ return node;
772
+ default:
773
+ return node;
641
774
  }
642
- return node;
643
775
  }
644
776
  function transformChildren(children, ctx) {
645
777
  const result = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/start",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Meta-framework for Constela applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,11 +39,11 @@
39
39
  "remark-parse": "^11.0.0",
40
40
  "unified": "^11.0.0",
41
41
  "vite": "^6.0.0",
42
- "@constela/compiler": "0.6.1",
43
- "@constela/core": "0.7.0",
44
- "@constela/router": "6.0.0",
45
- "@constela/server": "2.0.0",
46
- "@constela/runtime": "0.9.1"
42
+ "@constela/compiler": "0.7.0",
43
+ "@constela/server": "3.0.0",
44
+ "@constela/runtime": "0.9.2",
45
+ "@constela/router": "7.0.0",
46
+ "@constela/core": "0.7.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/mdast": "^4.0.4",