@base44-preview/vite-plugin 0.2.27-pr.43.93e5e43 → 0.2.27-pr.44.b37fb09

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 (76) hide show
  1. package/dist/capabilities/inline-edit/controller.d.ts.map +1 -1
  2. package/dist/capabilities/inline-edit/controller.js +9 -3
  3. package/dist/capabilities/inline-edit/controller.js.map +1 -1
  4. package/dist/capabilities/inline-edit/dom-utils.d.ts +1 -0
  5. package/dist/capabilities/inline-edit/dom-utils.d.ts.map +1 -1
  6. package/dist/capabilities/inline-edit/dom-utils.js +17 -7
  7. package/dist/capabilities/inline-edit/dom-utils.js.map +1 -1
  8. package/dist/injections/visual-edit-agent.d.ts.map +1 -1
  9. package/dist/injections/visual-edit-agent.js +14 -4
  10. package/dist/injections/visual-edit-agent.js.map +1 -1
  11. package/dist/jsx-processor.d.ts +1 -4
  12. package/dist/jsx-processor.d.ts.map +1 -1
  13. package/dist/jsx-processor.js +6 -33
  14. package/dist/jsx-processor.js.map +1 -1
  15. package/dist/jsx-utils.d.ts +0 -9
  16. package/dist/jsx-utils.d.ts.map +1 -1
  17. package/dist/jsx-utils.js +0 -86
  18. package/dist/jsx-utils.js.map +1 -1
  19. package/dist/processors/shared-utils.d.ts +0 -77
  20. package/dist/processors/shared-utils.d.ts.map +1 -1
  21. package/dist/processors/shared-utils.js +0 -525
  22. package/dist/processors/shared-utils.js.map +1 -1
  23. package/dist/processors/static-array-processor.d.ts +3 -2
  24. package/dist/processors/static-array-processor.d.ts.map +1 -1
  25. package/dist/processors/static-array-processor.js +3 -2
  26. package/dist/processors/static-array-processor.js.map +1 -1
  27. package/dist/statics/index.mjs +2 -2
  28. package/dist/statics/index.mjs.map +1 -1
  29. package/dist/visual-edit-plugin.d.ts +1 -0
  30. package/dist/visual-edit-plugin.d.ts.map +1 -1
  31. package/dist/visual-edit-plugin.js +178 -29
  32. package/dist/visual-edit-plugin.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/capabilities/inline-edit/controller.ts +35 -29
  35. package/src/capabilities/inline-edit/dom-utils.ts +14 -4
  36. package/src/injections/visual-edit-agent.ts +20 -4
  37. package/src/jsx-processor.ts +14 -41
  38. package/src/jsx-utils.ts +0 -116
  39. package/src/processors/shared-utils.ts +0 -671
  40. package/src/processors/static-array-processor.ts +3 -6
  41. package/src/visual-edit-plugin.ts +215 -34
  42. package/dist/consts.d.ts +0 -12
  43. package/dist/consts.d.ts.map +0 -1
  44. package/dist/consts.js +0 -12
  45. package/dist/consts.js.map +0 -1
  46. package/dist/processors/collection-id-processor.d.ts +0 -20
  47. package/dist/processors/collection-id-processor.d.ts.map +0 -1
  48. package/dist/processors/collection-id-processor.js +0 -182
  49. package/dist/processors/collection-id-processor.js.map +0 -1
  50. package/dist/processors/collection-item-field-processor.d.ts +0 -39
  51. package/dist/processors/collection-item-field-processor.d.ts.map +0 -1
  52. package/dist/processors/collection-item-field-processor.js +0 -281
  53. package/dist/processors/collection-item-field-processor.js.map +0 -1
  54. package/dist/processors/collection-item-id-processor.d.ts +0 -12
  55. package/dist/processors/collection-item-id-processor.d.ts.map +0 -1
  56. package/dist/processors/collection-item-id-processor.js +0 -50
  57. package/dist/processors/collection-item-id-processor.js.map +0 -1
  58. package/dist/processors/collection-reference-field-processor.d.ts +0 -31
  59. package/dist/processors/collection-reference-field-processor.d.ts.map +0 -1
  60. package/dist/processors/collection-reference-field-processor.js +0 -174
  61. package/dist/processors/collection-reference-field-processor.js.map +0 -1
  62. package/dist/processors/collection-tracing-utils.d.ts +0 -36
  63. package/dist/processors/collection-tracing-utils.d.ts.map +0 -1
  64. package/dist/processors/collection-tracing-utils.js +0 -390
  65. package/dist/processors/collection-tracing-utils.js.map +0 -1
  66. package/dist/types.d.ts +0 -5
  67. package/dist/types.d.ts.map +0 -1
  68. package/dist/types.js +0 -2
  69. package/dist/types.js.map +0 -1
  70. package/src/consts.ts +0 -12
  71. package/src/processors/collection-id-processor.ts +0 -261
  72. package/src/processors/collection-item-field-processor.ts +0 -433
  73. package/src/processors/collection-item-id-processor.ts +0 -69
  74. package/src/processors/collection-reference-field-processor.ts +0 -225
  75. package/src/processors/collection-tracing-utils.ts +0 -507
  76. package/src/types.ts +0 -4
@@ -3,31 +3,196 @@ import { default as traverse } from "@babel/traverse";
3
3
  import { default as generate } from "@babel/generator";
4
4
  import * as t from "@babel/types";
5
5
  import type { Plugin } from "vite";
6
- import { JSXProcessor } from "./jsx-processor.js";
6
+ import { StaticArrayProcessor } from "./processors/static-array-processor.js";
7
7
  import { JSXUtils } from "./jsx-utils.js";
8
8
 
9
+ // Helper function to check if JSX element contains dynamic content
10
+ export function checkIfElementHasDynamicContent(jsxElement: any) {
11
+ let hasDynamicContent = false;
12
+
13
+ // Helper function to check if any node contains dynamic patterns
14
+ function checkNodeForDynamicContent(node: any) {
15
+ // JSX expressions like {variable}, {func()}, {obj.prop}
16
+ if (t.isJSXExpressionContainer(node)) {
17
+ const expression = node.expression;
18
+
19
+ // Skip empty expressions {}
20
+ if (t.isJSXEmptyExpression(expression)) {
21
+ return false;
22
+ }
23
+
24
+ // Any non-literal expression is considered dynamic
25
+ if (!t.isLiteral(expression)) {
26
+ return true;
27
+ }
28
+ }
29
+
30
+ // Template literals with expressions `Hello ${name}`
31
+ if (t.isTemplateLiteral(node) && node.expressions.length > 0) {
32
+ return true;
33
+ }
34
+
35
+ // Member expressions like props.title, state.value
36
+ if (t.isMemberExpression(node)) {
37
+ return true;
38
+ }
39
+
40
+ // Function calls like getData(), format()
41
+ if (t.isCallExpression(node)) {
42
+ return true;
43
+ }
44
+
45
+ // Conditional expressions like condition ? "yes" : "no"
46
+ if (t.isConditionalExpression(node)) {
47
+ return true;
48
+ }
49
+
50
+ // Identifier references (could be props, state, variables)
51
+ if (t.isIdentifier(node)) {
52
+ // Common dynamic identifiers
53
+ const dynamicNames = [
54
+ "props",
55
+ "state",
56
+ "data",
57
+ "item",
58
+ "value",
59
+ "text",
60
+ "content",
61
+ ];
62
+ if (dynamicNames.some((name) => node.name.includes(name))) {
63
+ return true;
64
+ }
65
+ }
66
+
67
+ return false;
68
+ }
69
+
70
+ // Recursively traverse all child nodes
71
+ function traverseNode(node: any) {
72
+ if (checkNodeForDynamicContent(node)) {
73
+ hasDynamicContent = true;
74
+ return;
75
+ }
76
+
77
+ // Recursively check child nodes
78
+ Object.keys(node).forEach((key) => {
79
+ const value = node[key];
80
+
81
+ if (Array.isArray(value)) {
82
+ value.forEach((child) => {
83
+ if (child && typeof child === "object" && child.type) {
84
+ traverseNode(child);
85
+ }
86
+ });
87
+ } else if (value && typeof value === "object" && value.type) {
88
+ traverseNode(value);
89
+ }
90
+ });
91
+ }
92
+
93
+ // Check the element's own attributes for dynamic content
94
+ const attributes = jsxElement.openingElement?.attributes || [];
95
+ attributes.forEach((attr: any) => {
96
+ if (hasDynamicContent) return; // Early exit if already found dynamic content
97
+
98
+ // Spread attributes like {...props} are always dynamic
99
+ if (t.isJSXSpreadAttribute(attr)) {
100
+ hasDynamicContent = true;
101
+ return;
102
+ }
103
+
104
+ // Check attribute values for dynamic expressions
105
+ if (t.isJSXAttribute(attr) && attr.value) {
106
+ traverseNode(attr.value);
107
+ }
108
+ });
109
+
110
+ // Check all children of the JSX element
111
+ jsxElement.children.forEach((child: any) => {
112
+ if (hasDynamicContent) return; // Early exit if already found dynamic content
113
+ traverseNode(child);
114
+ });
115
+
116
+ return hasDynamicContent;
117
+ }
118
+
9
119
  export function visualEditPlugin() {
10
120
  return {
11
121
  name: "visual-edit-transform",
12
122
  apply: (config) => config.mode === "development",
13
123
  enforce: "pre",
14
124
  order: "pre",
125
+ // Inject Tailwind CDN for visual editing capabilities
15
126
  transformIndexHtml(html: any) {
127
+ // Inject the Tailwind CSS CDN script right before the closing </head> tag
16
128
  const tailwindScript = ` <!-- Tailwind CSS CDN for visual editing -->\n <script src="https://cdn.tailwindcss.com"></script>\n `;
17
129
  return html.replace("</head>", tailwindScript + "</head>");
18
130
  },
19
131
  transform(code: any, id: any) {
132
+ // Skip node_modules and visual-edit-agent itself
20
133
  if (id.includes("node_modules") || id.includes("visual-edit-agent")) {
21
134
  return null;
22
135
  }
23
136
 
137
+ // Process JS/JSX/TS/TSX files
24
138
  if (!id.match(/\.(jsx?|tsx?)$/)) {
25
139
  return null;
26
140
  }
27
141
 
28
- const filename = extractFilename(id);
142
+ // Extract filename from path, preserving pages/ or components/ structure
143
+ const pathParts = id.split("/");
144
+ let filename;
145
+
146
+ // Check if this is a pages or components file
147
+ if (id.includes("/pages/")) {
148
+ const pagesIndex = pathParts.findIndex((part: any) => part === "pages");
149
+ if (pagesIndex >= 0 && pagesIndex < pathParts.length - 1) {
150
+ // Get all parts from 'pages' to the file, preserving nested structure
151
+ const relevantParts = pathParts.slice(pagesIndex, pathParts.length);
152
+ const lastPart = relevantParts[relevantParts.length - 1];
153
+ // Remove file extension from the last part
154
+ relevantParts[relevantParts.length - 1] = lastPart.includes(".")
155
+ ? lastPart.split(".")[0]
156
+ : lastPart;
157
+ filename = relevantParts.join("/");
158
+ } else {
159
+ filename = pathParts[pathParts.length - 1];
160
+ if (filename.includes(".")) {
161
+ filename = filename.split(".")[0];
162
+ }
163
+ }
164
+ } else if (id.includes("/components/")) {
165
+ const componentsIndex = pathParts.findIndex(
166
+ (part: any) => part === "components"
167
+ );
168
+ if (componentsIndex >= 0 && componentsIndex < pathParts.length - 1) {
169
+ // Get all parts from 'components' to the file, preserving nested structure
170
+ const relevantParts = pathParts.slice(
171
+ componentsIndex,
172
+ pathParts.length
173
+ );
174
+ const lastPart = relevantParts[relevantParts.length - 1];
175
+ // Remove file extension from the last part
176
+ relevantParts[relevantParts.length - 1] = lastPart.includes(".")
177
+ ? lastPart.split(".")[0]
178
+ : lastPart;
179
+ filename = relevantParts.join("/");
180
+ } else {
181
+ filename = pathParts[pathParts.length - 1];
182
+ if (filename.includes(".")) {
183
+ filename = filename.split(".")[0];
184
+ }
185
+ }
186
+ } else {
187
+ // For other files (like layout), just use the filename
188
+ filename = pathParts[pathParts.length - 1];
189
+ if (filename.includes(".")) {
190
+ filename = filename.split(".")[0];
191
+ }
192
+ }
29
193
 
30
194
  try {
195
+ // Parse the code into an AST
31
196
  const ast = parse(code, {
32
197
  sourceType: "module",
33
198
  plugins: [
@@ -49,17 +214,61 @@ export function visualEditPlugin() {
49
214
  ],
50
215
  });
51
216
 
217
+ // Traverse the AST and add source location and dynamic content attributes to JSX elements
52
218
  JSXUtils.init(t);
53
- const processor = new JSXProcessor(t, filename);
54
-
219
+ const staticArrayProcessor = new StaticArrayProcessor(t);
220
+ let elementsProcessed = 0;
55
221
  traverse.default(ast, {
56
222
  JSXElement(path) {
57
223
  const jsxElement = path.node;
224
+ const openingElement = jsxElement.openingElement;
225
+
226
+ // Skip fragments
58
227
  if (t.isJSXFragment(jsxElement)) return;
59
- processor.processJSXElement(path.get("openingElement"));
228
+
229
+ // Skip if already has source location attribute
230
+ const hasSourceLocation = openingElement.attributes.some(
231
+ (attr) =>
232
+ t.isJSXAttribute(attr) &&
233
+ t.isJSXIdentifier(attr.name) &&
234
+ attr.name.name === "data-source-location"
235
+ );
236
+
237
+ if (hasSourceLocation) return;
238
+
239
+ // Get line and column from AST node location
240
+ const { line, column } = openingElement.loc?.start || {
241
+ line: 1,
242
+ column: 0,
243
+ };
244
+
245
+ // Create the source location attribute
246
+ const sourceLocationAttr = t.jsxAttribute(
247
+ t.jsxIdentifier("data-source-location"),
248
+ t.stringLiteral(`${filename}:${line}:${column}`)
249
+ );
250
+
251
+ // Check if element has dynamic content
252
+ const isDynamic = checkIfElementHasDynamicContent(jsxElement);
253
+
254
+ // Create the dynamic content attribute
255
+ const dynamicContentAttr = t.jsxAttribute(
256
+ t.jsxIdentifier("data-dynamic-content"),
257
+ t.stringLiteral(isDynamic ? "true" : "false")
258
+ );
259
+
260
+ // Add both attributes to the beginning of the attributes array
261
+ openingElement.attributes.unshift(
262
+ sourceLocationAttr,
263
+ dynamicContentAttr
264
+ );
265
+
266
+ staticArrayProcessor.process(path.get("openingElement"));
267
+ elementsProcessed++;
60
268
  },
61
269
  });
62
270
 
271
+ // Generate the code back from the AST
63
272
  const result = generate.default(ast, {
64
273
  compact: false,
65
274
  concise: false,
@@ -73,38 +282,10 @@ export function visualEditPlugin() {
73
282
  } catch (error) {
74
283
  console.error("Failed to add source location to JSX:", error);
75
284
  return {
76
- code: code,
285
+ code: code, // Return original code on failure
77
286
  map: null,
78
287
  };
79
288
  }
80
289
  },
81
290
  } as Plugin;
82
291
  }
83
-
84
- function extractFilename(id: string): string {
85
- const pathParts = id.split("/");
86
-
87
- const segmentIndex = findSegmentIndex(pathParts, ["pages", "components"]);
88
- if (segmentIndex >= 0 && segmentIndex < pathParts.length - 1) {
89
- const relevantParts = pathParts.slice(segmentIndex);
90
- const last = relevantParts[relevantParts.length - 1];
91
- relevantParts[relevantParts.length - 1] = stripExtension(last ?? "");
92
- return relevantParts.join("/");
93
- }
94
-
95
- const lastPart = pathParts[pathParts.length - 1] ?? "";
96
- return stripExtension(lastPart);
97
- }
98
-
99
- function findSegmentIndex(parts: string[], segments: string[]): number {
100
- for (const segment of segments) {
101
- const idx = parts.findIndex((part) => part === segment);
102
- if (idx >= 0) return idx;
103
- }
104
- return -1;
105
- }
106
-
107
- function stripExtension(filename: string): string {
108
- const dotIndex = filename.indexOf(".");
109
- return dotIndex >= 0 ? filename.substring(0, dotIndex) : filename;
110
- }
package/dist/consts.d.ts DELETED
@@ -1,12 +0,0 @@
1
- export declare const DATA_COLLECTION_ID = "data-collection-id";
2
- export declare const DATA_COLLECTION_ITEM_ID = "data-collection-item-id";
3
- export declare const DATA_COLLECTION_ITEM_FIELD = "data-collection-item-field";
4
- export declare const DATA_COLLECTION_REFERENCE = "data-collection-reference";
5
- export declare const DATA_COLLECTION_FIELD_REFERENCE = "data-collection-field-reference";
6
- export declare const DATA_ARR_INDEX = "data-arr-index";
7
- export declare const DATA_ARR_VARIABLE_NAME = "data-arr-variable-name";
8
- export declare const DATA_ARR_FIELD = "data-arr-field";
9
- export declare const ALLOWED_CUSTOM_COMPONENTS: string[];
10
- export declare const MAX_JSX_DEPTH = 10;
11
- export declare const EXCLUDED_FIELDS: string[];
12
- //# sourceMappingURL=consts.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,eAAO,MAAM,+BAA+B,oCAAoC,CAAC;AACjF,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,eAAO,MAAM,yBAAyB,UAAoB,CAAC;AAC3D,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,eAAe,UAAyB,CAAC"}
package/dist/consts.js DELETED
@@ -1,12 +0,0 @@
1
- export const DATA_COLLECTION_ID = "data-collection-id";
2
- export const DATA_COLLECTION_ITEM_ID = "data-collection-item-id";
3
- export const DATA_COLLECTION_ITEM_FIELD = "data-collection-item-field";
4
- export const DATA_COLLECTION_REFERENCE = "data-collection-reference";
5
- export const DATA_COLLECTION_FIELD_REFERENCE = "data-collection-field-reference";
6
- export const DATA_ARR_INDEX = "data-arr-index";
7
- export const DATA_ARR_VARIABLE_NAME = "data-arr-variable-name";
8
- export const DATA_ARR_FIELD = "data-arr-field";
9
- export const ALLOWED_CUSTOM_COMPONENTS = ["Image", "Link"];
10
- export const MAX_JSX_DEPTH = 10;
11
- export const EXCLUDED_FIELDS = ["children", "length"];
12
- //# sourceMappingURL=consts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AACvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AACjE,MAAM,CAAC,MAAM,0BAA0B,GAAG,4BAA4B,CAAC;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAC;AACrE,MAAM,CAAC,MAAM,+BAA+B,GAAG,iCAAiC,CAAC;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAC/C,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC"}
@@ -1,20 +0,0 @@
1
- import type { NodePath } from "@babel/traverse";
2
- import type * as t from "@babel/types";
3
- export declare class CollectionIdProcessor {
4
- private types;
5
- private attributeUtils;
6
- private pathUtils;
7
- private expressionUtils;
8
- private tracingUtils;
9
- constructor(types: typeof t);
10
- process(path: NodePath<t.JSXOpeningElement>): void;
11
- private tryDirectMapInChildren;
12
- private extractMapSource;
13
- private traceMapCall;
14
- private traceOptionalMapCall;
15
- private callbackProducesJSX;
16
- private tryGetByIdInChildren;
17
- private checkChildForGetById;
18
- private tryComponentRootWithCollectionProp;
19
- }
20
- //# sourceMappingURL=collection-id-processor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection-id-processor.d.ts","sourceRoot":"","sources":["../../src/processors/collection-id-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAC;AAevC,qBAAa,qBAAqB;IAMpB,OAAO,CAAC,KAAK;IALzB,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,YAAY,CAAyB;gBAEzB,KAAK,EAAE,OAAO,CAAC;IAOnC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,IAAI;IAuBlD,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,gBAAgB;IA6BxB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,oBAAoB;IAgC5B,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,kCAAkC;CAkC3C"}
@@ -1,182 +0,0 @@
1
- import { DATA_COLLECTION_ID, DATA_COLLECTION_REFERENCE, MAX_JSX_DEPTH, } from "../consts.js";
2
- import { JSXUtils } from "../jsx-utils.js";
3
- import { JSXAttributeUtils, PathNavigationUtils, ExpressionAnalysisUtils, } from "./shared-utils.js";
4
- import { CollectionTracingUtils } from "./collection-tracing-utils.js";
5
- export class CollectionIdProcessor {
6
- types;
7
- attributeUtils;
8
- pathUtils;
9
- expressionUtils;
10
- tracingUtils;
11
- constructor(types) {
12
- this.types = types;
13
- this.attributeUtils = new JSXAttributeUtils(types);
14
- this.pathUtils = new PathNavigationUtils(types);
15
- this.expressionUtils = new ExpressionAnalysisUtils(types);
16
- this.tracingUtils = new CollectionTracingUtils(types);
17
- }
18
- process(path) {
19
- if (this.attributeUtils.hasAttribute(path, DATA_COLLECTION_ID))
20
- return;
21
- const info = this.tryDirectMapInChildren(path) ??
22
- this.tryGetByIdInChildren(path) ??
23
- this.tryComponentRootWithCollectionProp(path);
24
- if (!info)
25
- return;
26
- const target = this.pathUtils.findDOMElementTarget(path) ?? path;
27
- this.attributeUtils.addStringAttribute(target, DATA_COLLECTION_ID, info.id);
28
- if (info.references.length > 0) {
29
- this.attributeUtils.addStringAttribute(target, DATA_COLLECTION_REFERENCE, info.references.join(","));
30
- }
31
- }
32
- tryDirectMapInChildren(path) {
33
- const jsxElement = path.parentPath;
34
- if (!jsxElement?.isJSXElement())
35
- return null;
36
- const children = jsxElement.get("children");
37
- for (const child of children) {
38
- if (!child.isJSXExpressionContainer())
39
- continue;
40
- const expression = child.get("expression");
41
- if (expression.isJSXEmptyExpression())
42
- continue;
43
- const mapSource = this.extractMapSource(expression);
44
- if (mapSource)
45
- return mapSource;
46
- }
47
- return null;
48
- }
49
- extractMapSource(expr) {
50
- if (expr.isCallExpression()) {
51
- return this.traceMapCall(expr);
52
- }
53
- if (expr.isLogicalExpression()) {
54
- if (expr.node.operator === "&&") {
55
- const right = expr.get("right");
56
- return this.extractMapSource(right);
57
- }
58
- }
59
- if (expr.isConditionalExpression()) {
60
- const consequent = expr.get("consequent");
61
- const alternate = expr.get("alternate");
62
- return (this.extractMapSource(consequent) ?? this.extractMapSource(alternate));
63
- }
64
- if (expr.isOptionalCallExpression()) {
65
- return this.traceOptionalMapCall(expr);
66
- }
67
- return null;
68
- }
69
- traceMapCall(callPath) {
70
- const callee = callPath.get("callee");
71
- if (!callee.isMemberExpression())
72
- return null;
73
- const property = callee.get("property");
74
- if (!property.isIdentifier() ||
75
- (property.node.name !== "map" && property.node.name !== "flatMap")) {
76
- return null;
77
- }
78
- if (!this.callbackProducesJSX(callPath))
79
- return null;
80
- const arrayObj = callee.get("object");
81
- return this.tracingUtils.traceCollectionSource(arrayObj);
82
- }
83
- traceOptionalMapCall(callPath) {
84
- const callee = callPath.get("callee");
85
- if (!callee.isMemberExpression() &&
86
- !callee.isOptionalMemberExpression()) {
87
- return null;
88
- }
89
- const property = callee.get("property");
90
- if (!property.isIdentifier() ||
91
- (property.node.name !== "map" && property.node.name !== "flatMap")) {
92
- return null;
93
- }
94
- const arrayObj = callee.get("object");
95
- return this.tracingUtils.traceCollectionSource(arrayObj);
96
- }
97
- callbackProducesJSX(callPath) {
98
- const args = callPath.get("arguments");
99
- const callback = args[0];
100
- if (!callback)
101
- return false;
102
- if (callback.isArrowFunctionExpression()) {
103
- const body = callback.get("body");
104
- if (body.isBlockStatement()) {
105
- return JSXUtils.doesBlockReturnJSX(body.node);
106
- }
107
- return JSXUtils.producesJSX(body.node);
108
- }
109
- if (callback.isFunctionExpression()) {
110
- return JSXUtils.doesBlockReturnJSX(callback.node.body);
111
- }
112
- return false;
113
- }
114
- tryGetByIdInChildren(path, depth = 0) {
115
- if (depth > MAX_JSX_DEPTH)
116
- return null;
117
- const jsxElement = path.parentPath;
118
- if (!jsxElement?.isJSXElement())
119
- return null;
120
- const children = jsxElement.get("children");
121
- for (const child of children) {
122
- const info = this.checkChildForGetById(child, depth);
123
- if (info)
124
- return info;
125
- }
126
- for (const attr of path.node.attributes) {
127
- if (this.types.isJSXAttribute(attr) &&
128
- attr.value &&
129
- this.types.isJSXExpressionContainer(attr.value)) {
130
- const expr = attr.value.expression;
131
- if (this.types.isMemberExpression(expr)) {
132
- const info = this.tracingUtils.traceGetByIdSource(path);
133
- if (info)
134
- return info;
135
- }
136
- }
137
- }
138
- return null;
139
- }
140
- checkChildForGetById(child, depth) {
141
- if (child.isJSXExpressionContainer()) {
142
- const expr = child.get("expression");
143
- if (expr.isMemberExpression() ||
144
- expr.isOptionalMemberExpression()) {
145
- return this.tracingUtils.traceGetByIdSource(child);
146
- }
147
- }
148
- if (child.isJSXElement()) {
149
- const childOpening = child.get("openingElement");
150
- return this.tryGetByIdInChildren(childOpening, depth + 1);
151
- }
152
- return null;
153
- }
154
- tryComponentRootWithCollectionProp(path) {
155
- if (!this.pathUtils.isRootReturnElement(path))
156
- return null;
157
- const fn = this.pathUtils.findEnclosingFunction(path);
158
- if (!fn)
159
- return null;
160
- let info = null;
161
- fn.traverse({
162
- CallExpression: (callPath) => {
163
- if (info)
164
- return;
165
- const callee = callPath.get("callee");
166
- if (!callee.isMemberExpression())
167
- return;
168
- const prop = callee.get("property");
169
- if (!prop.isIdentifier() ||
170
- (prop.node.name !== "map" && prop.node.name !== "flatMap")) {
171
- return;
172
- }
173
- if (!this.callbackProducesJSX(callPath))
174
- return;
175
- const arrayObj = callee.get("object");
176
- info = this.tracingUtils.traceCollectionSource(arrayObj);
177
- },
178
- });
179
- return info;
180
- }
181
- }
182
- //# sourceMappingURL=collection-id-processor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection-id-processor.js","sourceRoot":"","sources":["../../src/processors/collection-id-processor.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- import type { NodePath } from "@babel/traverse";
2
- import type * as t from "@babel/types";
3
- export declare class DataItemFieldProcessor {
4
- private types;
5
- private attributeUtils;
6
- private expressionUtils;
7
- private staticUtils;
8
- constructor(types: typeof t);
9
- process(path: NodePath<t.JSXOpeningElement>): void;
10
- private extractFieldFromChildren;
11
- private extractFieldFromChild;
12
- private extractFromExpressionContainer;
13
- private extractFromMemberExpression;
14
- private extractFromSimpleIdentifier;
15
- private extractFromChildElement;
16
- private extractFromImageElement;
17
- private extractFromConditionalImage;
18
- private tryAddItemId;
19
- /**
20
- * Build the ID expression for a given root object name.
21
- * If a specific idField was resolved from a key attribute, generates root?.id (or root?._id).
22
- * If unknown (cross-file component), generates root?.id || root?._id to cover both conventions.
23
- */
24
- private buildIdExpression;
25
- /**
26
- * Walk up the JSX tree to find a key attribute that accesses .id or ._id.
27
- * Returns null when no key is found (e.g. cross-file component receiving props).
28
- */
29
- private resolveIdFieldName;
30
- private extractIdFieldFromKey;
31
- /**
32
- * For simple identifiers from destructured component props like ({ name, price }),
33
- * find or inject the id field in the ObjectPattern so we can reference it directly.
34
- */
35
- private tryAddItemIdFromDestructuredParams;
36
- private tryAddItemIdFromParentComponent;
37
- private findKeyWithId;
38
- }
39
- //# sourceMappingURL=collection-item-field-processor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection-item-field-processor.d.ts","sourceRoot":"","sources":["../../src/processors/collection-item-field-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAC;AAavC,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,KAAK;IAJzB,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,eAAe,CAA0B;IACjD,OAAO,CAAC,WAAW,CAAmB;gBAElB,KAAK,EAAE,OAAO,CAAC;IAMnC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,IAAI;IAoBlD,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,8BAA8B;IAwCtC,OAAO,CAAC,2BAA2B;IA0BnC,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,uBAAuB;IAyC/B,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,YAAY;IAoCpB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8BzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,qBAAqB;IAwB7B;;;OAGG;IACH,OAAO,CAAC,kCAAkC;IA6C1C,OAAO,CAAC,+BAA+B;IA8BvC,OAAO,CAAC,aAAa;CAmBtB"}