@base44-preview/vite-plugin 1.0.20-pr.82.75ad211 → 1.0.20-pr.83.ee1eb29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/vite-plugin",
3
- "version": "1.0.20-pr.82.75ad211",
3
+ "version": "1.0.20-pr.83.ee1eb29",
4
4
  "description": "The Vite plugin for base44 based applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -82,12 +82,21 @@ export function updateElementClasses(elements: Element[], classes: string): void
82
82
  }
83
83
 
84
84
  /** Set a single attribute on all provided elements. */
85
- export function updateElementAttribute(elements: Element[], attribute: string, value: string): void {
85
+ export function updateElementAttribute(
86
+ elements: Element[],
87
+ attribute: string,
88
+ value: string,
89
+ arrIndex?: number | string
90
+ ): void {
86
91
  if (!ALLOWED_ATTRIBUTES.includes(attribute)) {
87
92
  return;
88
93
  }
89
94
 
90
- elements.forEach((element) => {
95
+ const targetElements = arrIndex != null
96
+ ? elements.filter((element) => (element as HTMLElement).dataset.arrIndex === String(arrIndex))
97
+ : elements;
98
+
99
+ targetElements.forEach((element) => {
91
100
  element.setAttribute(attribute, value);
92
101
  });
93
102
  }
@@ -368,12 +368,13 @@ export function setupVisualEditAgent() {
368
368
  const updateElementAttributeAndReposition = (
369
369
  visualSelectorId: string,
370
370
  attribute: string,
371
- value: string
371
+ value: string,
372
+ arrIndex?: number | string
372
373
  ) => {
373
374
  const elements = findElementsById(visualSelectorId);
374
375
  if (elements.length === 0) return;
375
376
 
376
- updateElementAttribute(elements, attribute, value);
377
+ updateElementAttribute(elements, attribute, value, arrIndex);
377
378
 
378
379
  // Reposition overlays after attribute change (e.g. image src swap can affect layout)
379
380
  setTimeout(() => {
@@ -529,7 +530,8 @@ export function setupVisualEditAgent() {
529
530
  updateElementAttributeAndReposition(
530
531
  message.data.visualSelectorId,
531
532
  message.data.attribute,
532
- message.data.value
533
+ message.data.value,
534
+ message.data.arrIndex
533
535
  );
534
536
  } else {
535
537
  console.warn(
@@ -652,20 +654,17 @@ export function setupVisualEditAgent() {
652
654
  ? message.referenceVhBase
653
655
  : undefined
654
656
  );
655
- postAckIfRequested(event, message);
656
657
  break;
657
658
 
658
659
  case "measure-page-height":
659
660
  pageHeightBridge.measurePageHeight(
660
- safeAckOrigin(event),
661
+ event.origin && event.origin !== "null" ? event.origin : "*",
661
662
  typeof message.settleMs === "number" ? message.settleMs : undefined
662
663
  );
663
- postAckIfRequested(event, message);
664
664
  break;
665
665
 
666
666
  case "suppress-auto-popups":
667
667
  autoPopupSuppressor.suppress();
668
- postAckIfRequested(event, message);
669
668
  break;
670
669
 
671
670
  case "toggle-canvas-wheel-zoom-bridge":
@@ -758,22 +757,3 @@ export function setupVisualEditAgent() {
758
757
  // Send ready message to parent
759
758
  window.parent.postMessage({ type: "visual-edit-agent-ready" }, "*");
760
759
  }
761
-
762
- // "*" fallback covers jsdom (empty origin) and sandboxed iframes (literal "null").
763
- export function safeAckOrigin(event: MessageEvent): string {
764
- return event.origin && event.origin !== "null" ? event.origin : "*";
765
- }
766
-
767
- // Echoes `<type>:ack` to the parent when the incoming message includes a
768
- // reqId. No-op without reqId — keeps senders that don't expect acks working.
769
- export function postAckIfRequested(
770
- event: MessageEvent,
771
- message: { type?: unknown; reqId?: unknown },
772
- ): void {
773
- if (typeof message.reqId !== "string") return;
774
- if (typeof message.type !== "string") return;
775
- window.parent.postMessage(
776
- { type: `${message.type}:ack`, reqId: message.reqId },
777
- safeAckOrigin(event),
778
- );
779
- }
@@ -69,6 +69,9 @@ export class StaticArrayProcessor {
69
69
  path: NodePath<t.JSXOpeningElement>,
70
70
  callbackParam: string
71
71
  ): string | null {
72
+ const imageSrcFieldPath = this.findImageSrcFieldPath(path, callbackParam);
73
+ if (imageSrcFieldPath) return imageSrcFieldPath;
74
+
72
75
  const parentElement = path.parentPath;
73
76
  if (!parentElement?.isJSXElement()) return null;
74
77
 
@@ -80,6 +83,36 @@ export class StaticArrayProcessor {
80
83
  return null;
81
84
  }
82
85
 
86
+ private findImageSrcFieldPath(
87
+ path: NodePath<t.JSXOpeningElement>,
88
+ callbackParam: string
89
+ ): string | null {
90
+ const elementName = this.getElementName(path);
91
+ if (elementName !== "img" && elementName !== "Image") return null;
92
+
93
+ for (const attr of path.node.attributes) {
94
+ if (
95
+ !this.types.isJSXAttribute(attr) ||
96
+ !this.types.isJSXIdentifier(attr.name) ||
97
+ attr.name.name !== "src" ||
98
+ !attr.value ||
99
+ !this.types.isJSXExpressionContainer(attr.value)
100
+ ) {
101
+ continue;
102
+ }
103
+
104
+ const expression = attr.value.expression;
105
+ if (
106
+ this.types.isMemberExpression(expression) ||
107
+ this.types.isOptionalMemberExpression(expression)
108
+ ) {
109
+ return this.extractFieldPathFromExpression(expression, callbackParam);
110
+ }
111
+ }
112
+
113
+ return null;
114
+ }
115
+
83
116
  private extractFieldPathFromChild(
84
117
  child: NodePath<t.JSXElement["children"][number]>,
85
118
  callbackParam: string
@@ -92,6 +125,17 @@ export class StaticArrayProcessor {
92
125
  return this.extractFieldPath(expression, callbackParam);
93
126
  }
94
127
 
128
+ private extractFieldPathFromExpression(
129
+ expr: t.MemberExpression | t.OptionalMemberExpression,
130
+ callbackParam: string
131
+ ): string | null {
132
+ const parts = this.collectMemberExpressionPartsFromNode(expr);
133
+ if (!parts) return null;
134
+
135
+ const { rootName, propertyNames } = parts;
136
+ return rootName === callbackParam ? propertyNames.join(".") : null;
137
+ }
138
+
95
139
  private extractFieldPath(
96
140
  expr: NodePath<t.MemberExpression>,
97
141
  callbackParam: string
@@ -122,6 +166,35 @@ export class StaticArrayProcessor {
122
166
  return { rootName: current.node.name, propertyNames };
123
167
  }
124
168
 
169
+ private collectMemberExpressionPartsFromNode(
170
+ expr: t.MemberExpression | t.OptionalMemberExpression
171
+ ): { rootName: string; propertyNames: string[] } | null {
172
+ const propertyNames: string[] = [];
173
+ let current: t.Expression = expr;
174
+
175
+ while (
176
+ this.types.isMemberExpression(current) ||
177
+ this.types.isOptionalMemberExpression(current)
178
+ ) {
179
+ const property = current.property;
180
+ if (!this.types.isIdentifier(property)) return null;
181
+
182
+ propertyNames.unshift(property.name);
183
+ current = current.object as t.Expression;
184
+ }
185
+
186
+ if (!this.types.isIdentifier(current)) return null;
187
+
188
+ return { rootName: current.name, propertyNames };
189
+ }
190
+
191
+ private getElementName(path: NodePath<t.JSXOpeningElement>): string | null {
192
+ const name = path.node.name;
193
+ if (this.types.isJSXIdentifier(name)) return name.name;
194
+ if (this.types.isJSXMemberExpression(name)) return name.property.name;
195
+ return null;
196
+ }
197
+
125
198
  private ensureIndexParam(arrayInfo: ArrayMapInfo): string {
126
199
  if (arrayInfo.indexParam) {
127
200
  return arrayInfo.indexParam;