@base44-preview/vite-plugin 1.0.6-pr.63.d7abd73 → 1.0.18-pr.80.79b32f2
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/html-injections-plugin.d.ts.map +1 -1
- package/dist/html-injections-plugin.js +4 -2
- package/dist/html-injections-plugin.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/injections/auto-popup-suppressor.d.ts +6 -0
- package/dist/injections/auto-popup-suppressor.d.ts.map +1 -0
- package/dist/injections/auto-popup-suppressor.js +264 -0
- package/dist/injections/auto-popup-suppressor.js.map +1 -0
- package/dist/injections/canvas-wheel-zoom-bridge.d.ts +5 -0
- package/dist/injections/canvas-wheel-zoom-bridge.d.ts.map +1 -0
- package/dist/injections/canvas-wheel-zoom-bridge.js +64 -0
- package/dist/injections/canvas-wheel-zoom-bridge.js.map +1 -0
- package/dist/injections/page-height-bridge.d.ts +14 -0
- package/dist/injections/page-height-bridge.d.ts.map +1 -0
- package/dist/injections/page-height-bridge.js +510 -0
- package/dist/injections/page-height-bridge.js.map +1 -0
- package/dist/injections/visual-edit-agent.d.ts.map +1 -1
- package/dist/injections/visual-edit-agent.js +21 -0
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/jsx-processor.d.ts.map +1 -1
- package/dist/jsx-processor.js +1 -0
- package/dist/jsx-processor.js.map +1 -1
- package/dist/processors/collection-id-processor.d.ts +1 -0
- package/dist/processors/collection-id-processor.d.ts.map +1 -1
- package/dist/processors/collection-id-processor.js +17 -0
- package/dist/processors/collection-id-processor.js.map +1 -1
- package/dist/processors/collection-item-field-processor.d.ts.map +1 -1
- package/dist/processors/collection-item-field-processor.js +16 -5
- package/dist/processors/collection-item-field-processor.js.map +1 -1
- package/dist/processors/collection-item-id-processor.d.ts +27 -0
- package/dist/processors/collection-item-id-processor.d.ts.map +1 -1
- package/dist/processors/collection-item-id-processor.js +128 -1
- package/dist/processors/collection-item-id-processor.js.map +1 -1
- package/dist/processors/utils/collection-tracing-utils.d.ts +1 -1
- package/dist/processors/utils/collection-tracing-utils.d.ts.map +1 -1
- package/dist/processors/utils/collection-tracing-utils.js +48 -10
- package/dist/processors/utils/collection-tracing-utils.js.map +1 -1
- package/dist/processors/utils/shared-utils.js +1 -1
- package/dist/processors/utils/shared-utils.js.map +1 -1
- package/dist/statics/index.mjs +8 -8
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/bridge.ts +1 -1
- package/src/html-injections-plugin.ts +4 -2
- package/src/index.ts +2 -2
- package/src/injections/auto-popup-suppressor.ts +271 -0
- package/src/injections/canvas-wheel-zoom-bridge.ts +78 -0
- package/src/injections/page-height-bridge.ts +566 -0
- package/src/injections/visual-edit-agent.ts +32 -1
- package/src/jsx-processor.ts +1 -0
- package/src/processors/collection-id-processor.ts +17 -0
- package/src/processors/collection-item-field-processor.ts +23 -5
- package/src/processors/collection-item-id-processor.ts +154 -0
- package/src/processors/utils/collection-tracing-utils.ts +54 -8
- package/src/processors/utils/shared-utils.ts +1 -1
|
@@ -348,16 +348,34 @@ export class DataItemFieldProcessor {
|
|
|
348
348
|
if (!param.isObjectPattern()) continue;
|
|
349
349
|
|
|
350
350
|
for (const prop of param.get("properties")) {
|
|
351
|
+
if (!prop.isObjectProperty()) continue;
|
|
352
|
+
const key = (prop.node as t.ObjectProperty).key;
|
|
353
|
+
const val = (prop.node as t.ObjectProperty).value;
|
|
354
|
+
|
|
355
|
+
// Reuse a forwarding param already injected by processRootElement
|
|
356
|
+
if (
|
|
357
|
+
this.types.isStringLiteral(key) &&
|
|
358
|
+
key.value === DATA_COLLECTION_ITEM_ID &&
|
|
359
|
+
this.types.isIdentifier(val)
|
|
360
|
+
) {
|
|
361
|
+
this.attributeUtils.addExpressionAttribute(
|
|
362
|
+
path,
|
|
363
|
+
DATA_COLLECTION_ITEM_ID,
|
|
364
|
+
this.types.identifier(val.name)
|
|
365
|
+
);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Use an existing id / _id destructured prop
|
|
351
370
|
if (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
this.types.isIdentifier(prop.node.value)
|
|
371
|
+
this.types.isIdentifier(key) &&
|
|
372
|
+
(key.name === "id" || key.name === "_id") &&
|
|
373
|
+
this.types.isIdentifier(val)
|
|
356
374
|
) {
|
|
357
375
|
this.attributeUtils.addExpressionAttribute(
|
|
358
376
|
path,
|
|
359
377
|
DATA_COLLECTION_ITEM_ID,
|
|
360
|
-
this.types.identifier(
|
|
378
|
+
this.types.identifier(val.name)
|
|
361
379
|
);
|
|
362
380
|
return;
|
|
363
381
|
}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import type { NodePath } from "@babel/traverse";
|
|
2
2
|
import type * as t from "@babel/types";
|
|
3
3
|
import { DATA_COLLECTION_ITEM_ID } from "../consts.js";
|
|
4
|
+
import { JSXUtils } from "../jsx-utils.js";
|
|
4
5
|
import {
|
|
5
6
|
JSXAttributeUtils,
|
|
6
7
|
ExpressionAnalysisUtils,
|
|
8
|
+
PathNavigationUtils,
|
|
7
9
|
} from "./utils/shared-utils.js";
|
|
8
10
|
|
|
11
|
+
const FORWARDING_PARAM_NAME = "__dataCollectionItemId";
|
|
12
|
+
|
|
9
13
|
export class DataItemIdProcessor {
|
|
10
14
|
private attributeUtils: JSXAttributeUtils;
|
|
11
15
|
private expressionUtils: ExpressionAnalysisUtils;
|
|
16
|
+
private pathUtils: PathNavigationUtils;
|
|
12
17
|
|
|
13
18
|
constructor(private types: typeof t) {
|
|
14
19
|
this.attributeUtils = new JSXAttributeUtils(types);
|
|
15
20
|
this.expressionUtils = new ExpressionAnalysisUtils(types);
|
|
21
|
+
this.pathUtils = new PathNavigationUtils(types);
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
process(path: NodePath<t.JSXOpeningElement>): void {
|
|
@@ -39,6 +45,154 @@ export class DataItemIdProcessor {
|
|
|
39
45
|
);
|
|
40
46
|
}
|
|
41
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Called for every root DOM element of a component. Adds a `data-collection-item-id`
|
|
50
|
+
* forwarding attribute so that when the component is used as a collection item
|
|
51
|
+
* (with `data-collection-item-id` passed as a prop from a parent `.map()`), the
|
|
52
|
+
* attribute flows through to the actual DOM element.
|
|
53
|
+
*
|
|
54
|
+
* Skipped when:
|
|
55
|
+
* - The root element already spreads props (e.g. `{...props}`) — forwarding is automatic
|
|
56
|
+
* - The enclosing function maps over a collection — it's a container, not an item
|
|
57
|
+
*/
|
|
58
|
+
processRootElement(path: NodePath<t.JSXOpeningElement>): void {
|
|
59
|
+
if (this.attributeUtils.hasAttribute(path, DATA_COLLECTION_ITEM_ID)) return;
|
|
60
|
+
|
|
61
|
+
// Only DOM or allowed custom elements (e.g. motion.div)
|
|
62
|
+
const name = JSXUtils.getElementName(path.node);
|
|
63
|
+
if (!name || !JSXUtils.isDOMOrAllowed(name)) return;
|
|
64
|
+
|
|
65
|
+
// Only the root return element of a component function
|
|
66
|
+
if (!this.pathUtils.isRootReturnElement(path)) return;
|
|
67
|
+
|
|
68
|
+
// Skip if root element already spreads all props — forwarding is handled naturally
|
|
69
|
+
if (this.hasSpreadAttribute(path)) return;
|
|
70
|
+
|
|
71
|
+
const fn = this.pathUtils.findEnclosingFunction(path);
|
|
72
|
+
if (!fn) return;
|
|
73
|
+
|
|
74
|
+
// Skip if this function IS a .map()/.flatMap() callback — it's an iteration
|
|
75
|
+
// function, not a component (e.g. [...Array(3)].map((_, i) => <div />))
|
|
76
|
+
if (this.isMapCallbackFunction(fn)) return;
|
|
77
|
+
|
|
78
|
+
// Skip if this function maps over a collection — it's a container, not an item
|
|
79
|
+
if (this.functionContainsMapCall(fn)) return;
|
|
80
|
+
|
|
81
|
+
const expr = this.buildCollectionItemIdExpression(fn);
|
|
82
|
+
if (!expr) return;
|
|
83
|
+
|
|
84
|
+
this.attributeUtils.addExpressionAttribute(path, DATA_COLLECTION_ITEM_ID, expr);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private hasSpreadAttribute(path: NodePath<t.JSXOpeningElement>): boolean {
|
|
88
|
+
return path.node.attributes.some((attr) =>
|
|
89
|
+
this.types.isJSXSpreadAttribute(attr)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Returns true when `fn` is a direct callback argument to a `.map()` or
|
|
95
|
+
* `.flatMap()` call — i.e. the function is an iteration callback, not a
|
|
96
|
+
* component definition. This prevents injecting prop-forwarding into
|
|
97
|
+
* patterns like `[...Array(3)].map((_, i) => <div />)` where the first
|
|
98
|
+
* param may be `undefined`.
|
|
99
|
+
*/
|
|
100
|
+
private isMapCallbackFunction(fn: NodePath<t.Function>): boolean {
|
|
101
|
+
const parent = fn.parentPath;
|
|
102
|
+
if (!parent?.isCallExpression()) return false;
|
|
103
|
+
const callee = parent.node.callee;
|
|
104
|
+
return (
|
|
105
|
+
this.types.isMemberExpression(callee) &&
|
|
106
|
+
this.types.isIdentifier(callee.property) &&
|
|
107
|
+
(callee.property.name === "map" || callee.property.name === "flatMap")
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private functionContainsMapCall(fn: NodePath<t.Function>): boolean {
|
|
112
|
+
let found = false;
|
|
113
|
+
const types = this.types;
|
|
114
|
+
fn.traverse({
|
|
115
|
+
// Stop at nested functions — event handlers / callbacks defined inside the
|
|
116
|
+
// component should not cause it to be treated as a collection container.
|
|
117
|
+
Function(innerFnPath) {
|
|
118
|
+
innerFnPath.skip();
|
|
119
|
+
},
|
|
120
|
+
CallExpression(callPath) {
|
|
121
|
+
if (found) {
|
|
122
|
+
callPath.stop();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const callee = callPath.node.callee;
|
|
126
|
+
if (
|
|
127
|
+
types.isMemberExpression(callee) &&
|
|
128
|
+
types.isIdentifier(callee.property) &&
|
|
129
|
+
(callee.property.name === "map" || callee.property.name === "flatMap")
|
|
130
|
+
) {
|
|
131
|
+
found = true;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
return found;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Returns an expression for reading `data-collection-item-id` from the component's
|
|
140
|
+
* props, modifying the function's params destructuring if necessary.
|
|
141
|
+
*/
|
|
142
|
+
private buildCollectionItemIdExpression(
|
|
143
|
+
fn: NodePath<t.Function>
|
|
144
|
+
): t.Expression | null {
|
|
145
|
+
const params = fn.get("params");
|
|
146
|
+
const firstParam = Array.isArray(params) ? params[0] : params;
|
|
147
|
+
if (!firstParam) return null;
|
|
148
|
+
|
|
149
|
+
if (firstParam.isObjectPattern()) {
|
|
150
|
+
// Check if already destructured (key must be a string literal — hyphens in the
|
|
151
|
+
// attribute name rule out a plain identifier)
|
|
152
|
+
for (const prop of firstParam.get("properties")) {
|
|
153
|
+
if (!prop.isObjectProperty()) continue;
|
|
154
|
+
const key = (prop.node as t.ObjectProperty).key;
|
|
155
|
+
const val = (prop.node as t.ObjectProperty).value;
|
|
156
|
+
if (
|
|
157
|
+
this.types.isStringLiteral(key) &&
|
|
158
|
+
key.value === DATA_COLLECTION_ITEM_ID &&
|
|
159
|
+
this.types.isIdentifier(val)
|
|
160
|
+
) {
|
|
161
|
+
return this.types.identifier(val.name);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Add "data-collection-item-id": __dataCollectionItemId to destructuring
|
|
166
|
+
const newProp = this.types.objectProperty(
|
|
167
|
+
this.types.stringLiteral(DATA_COLLECTION_ITEM_ID),
|
|
168
|
+
this.types.identifier(FORWARDING_PARAM_NAME)
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const restIdx = firstParam.node.properties.findIndex((p) =>
|
|
172
|
+
this.types.isRestElement(p)
|
|
173
|
+
);
|
|
174
|
+
if (restIdx === -1) {
|
|
175
|
+
firstParam.node.properties.push(newProp);
|
|
176
|
+
} else {
|
|
177
|
+
firstParam.node.properties.splice(restIdx, 0, newProp);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return this.types.identifier(FORWARDING_PARAM_NAME);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (firstParam.isIdentifier()) {
|
|
184
|
+
// props?.["data-collection-item-id"] — optional access in case param is nullish
|
|
185
|
+
return this.types.optionalMemberExpression(
|
|
186
|
+
this.types.identifier(firstParam.node.name),
|
|
187
|
+
this.types.stringLiteral(DATA_COLLECTION_ITEM_ID),
|
|
188
|
+
true, // computed
|
|
189
|
+
true // optional
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
|
|
42
196
|
private findKeyAttribute(
|
|
43
197
|
path: NodePath<t.JSXOpeningElement>
|
|
44
198
|
): t.JSXAttribute | null {
|
|
@@ -2,20 +2,17 @@ import type { NodePath } from "@babel/traverse";
|
|
|
2
2
|
import type * as t from "@babel/types";
|
|
3
3
|
import type { CollectionInfo } from "../../capabilities/inline-edit/types.js";
|
|
4
4
|
import {
|
|
5
|
-
ExpressionAnalysisUtils,
|
|
6
5
|
BindingUtils,
|
|
7
6
|
CallExpressionUtils,
|
|
8
7
|
} from "./shared-utils.js";
|
|
9
8
|
|
|
10
9
|
export class CollectionTracingUtils {
|
|
11
|
-
private expressionUtils: ExpressionAnalysisUtils;
|
|
12
10
|
private bindingUtils: BindingUtils;
|
|
13
11
|
private callUtils: CallExpressionUtils;
|
|
14
12
|
private visitedSetters = new Set<string>();
|
|
15
13
|
private visitedGetByIdSetters = new Set<string>();
|
|
16
14
|
|
|
17
15
|
constructor(private types: typeof t) {
|
|
18
|
-
this.expressionUtils = new ExpressionAnalysisUtils(types);
|
|
19
16
|
this.bindingUtils = new BindingUtils(types);
|
|
20
17
|
this.callUtils = new CallExpressionUtils(types);
|
|
21
18
|
}
|
|
@@ -104,6 +101,14 @@ export class CollectionTracingUtils {
|
|
|
104
101
|
return this.traceExpression(init);
|
|
105
102
|
}
|
|
106
103
|
|
|
104
|
+
if (init.isConditionalExpression()) {
|
|
105
|
+
const consequent = init.get("consequent") as NodePath<t.Expression>;
|
|
106
|
+
const alternate = init.get("alternate") as NodePath<t.Expression>;
|
|
107
|
+
const result = this.traceExpression(consequent);
|
|
108
|
+
if (result) return result;
|
|
109
|
+
return this.traceExpression(alternate);
|
|
110
|
+
}
|
|
111
|
+
|
|
107
112
|
if (init.isMemberExpression()) {
|
|
108
113
|
return this.traceExpression(init);
|
|
109
114
|
}
|
|
@@ -137,18 +142,59 @@ export class CollectionTracingUtils {
|
|
|
137
142
|
this.visitedSetters.add(setterName);
|
|
138
143
|
|
|
139
144
|
const functionScope = declaratorPath.getFunctionParent() ?? declaratorPath.scope.path;
|
|
145
|
+
|
|
146
|
+
// Pattern 1: setData(result) — direct call
|
|
140
147
|
const setterCall = this.bindingUtils.findSetterCallInScope(
|
|
141
148
|
setterName,
|
|
142
149
|
functionScope
|
|
143
150
|
);
|
|
151
|
+
if (setterCall) {
|
|
152
|
+
const args = setterCall.get("arguments");
|
|
153
|
+
const firstArg = args[0];
|
|
154
|
+
if (!firstArg || !firstArg.isExpression()) return null;
|
|
155
|
+
return this.traceExpression(firstArg);
|
|
156
|
+
}
|
|
144
157
|
|
|
145
|
-
|
|
158
|
+
// Pattern 2: somePromise.then(setData) — setter passed as .then callback
|
|
159
|
+
const thenCall = this.findThenCallWithSetter(setterName, functionScope);
|
|
160
|
+
if (thenCall) {
|
|
161
|
+
const callee = thenCall.get("callee");
|
|
162
|
+
if (callee.isMemberExpression()) {
|
|
163
|
+
const promiseExpr = callee.get("object") as NodePath<t.Expression>;
|
|
164
|
+
return this.traceExpression(promiseExpr);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
146
167
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (!firstArg || !firstArg.isExpression()) return null;
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
150
170
|
|
|
151
|
-
|
|
171
|
+
private findThenCallWithSetter(
|
|
172
|
+
setterName: string,
|
|
173
|
+
scope: NodePath
|
|
174
|
+
): NodePath<t.CallExpression> | null {
|
|
175
|
+
let result: NodePath<t.CallExpression> | null = null;
|
|
176
|
+
|
|
177
|
+
scope.traverse({
|
|
178
|
+
CallExpression: (callPath: NodePath<t.CallExpression>) => {
|
|
179
|
+
if (result) {
|
|
180
|
+
callPath.stop();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const callee = callPath.node.callee;
|
|
184
|
+
if (
|
|
185
|
+
this.types.isMemberExpression(callee) &&
|
|
186
|
+
this.types.isIdentifier(callee.property) &&
|
|
187
|
+
callee.property.name === "then" &&
|
|
188
|
+
callPath.node.arguments.length > 0 &&
|
|
189
|
+
this.types.isIdentifier(callPath.node.arguments[0]) &&
|
|
190
|
+
callPath.node.arguments[0].name === setterName
|
|
191
|
+
) {
|
|
192
|
+
result = callPath;
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return result;
|
|
152
198
|
}
|
|
153
199
|
|
|
154
200
|
private traceMemberExpression(
|
|
@@ -541,7 +541,7 @@ export class CallExpressionUtils {
|
|
|
541
541
|
const method = callee.property;
|
|
542
542
|
if (
|
|
543
543
|
!this.types.isIdentifier(method) ||
|
|
544
|
-
(method.name !== "list" && method.name !== "getAll")
|
|
544
|
+
(method.name !== "list" && method.name !== "getAll" && method.name !== "filter")
|
|
545
545
|
) {
|
|
546
546
|
return null;
|
|
547
547
|
}
|