@promakeai/inspector-hook 1.0.0 → 1.0.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"jsxUpdater.d.ts","sourceRoot":"","sources":["../../src/utils/jsxUpdater.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA+DtF"}
1
+ {"version":3,"file":"jsxUpdater.d.ts","sourceRoot":"","sources":["../../src/utils/jsxUpdater.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA+DtF"}
@@ -3,9 +3,14 @@
3
3
  * AST-based utility for updating styles and classNames in JSX/TSX source code
4
4
  */
5
5
  import * as parser from '@babel/parser';
6
- import traverse from '@babel/traverse';
7
- import generate from '@babel/generator';
6
+ import * as traverseModule from '@babel/traverse';
7
+ import * as generateModule from '@babel/generator';
8
8
  import * as t from '@babel/types';
9
+ // Browser compatibility: Handle both CommonJS and ESM default exports
10
+ // @ts-ignore - Babel modules have complex type definitions
11
+ const traverse = traverseModule.default || traverseModule;
12
+ // @ts-ignore - Babel modules have complex type definitions
13
+ const generate = generateModule.default || generateModule;
9
14
  /**
10
15
  * Create AST ObjectExpression from styles object
11
16
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promakeai/inspector-hook",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "React hook for controlling inspector in parent applications",
5
5
  "author": "Promake",
6
6
  "type": "module",
@@ -15,8 +15,7 @@
15
15
  "./package.json": "./package.json"
16
16
  },
17
17
  "files": [
18
- "dist",
19
- "src"
18
+ "dist"
20
19
  ],
21
20
  "scripts": {
22
21
  "build": "tsc --build",
@@ -45,7 +44,7 @@
45
44
  }
46
45
  },
47
46
  "devDependencies": {
48
- "@promakeai/inspector-types": "workspace:*",
47
+ "@promakeai/inspector-types": "^1.0.1",
49
48
  "@types/babel__traverse": "^7.20.0",
50
49
  "@types/babel__generator": "^7.6.0",
51
50
  "vitest": "^1.0.0"
@@ -56,11 +55,6 @@
56
55
  "@babel/generator": "^7.23.0",
57
56
  "@babel/types": "^7.23.0"
58
57
  },
59
- "repository": {
60
- "type": "git",
61
- "url": "https://github.com/promakeai/inspector.git",
62
- "directory": "packages/hook"
63
- },
64
58
  "publishConfig": {
65
59
  "access": "public"
66
60
  }
package/src/index.ts DELETED
@@ -1,384 +0,0 @@
1
- import { useEffect, useState, useCallback, RefObject } from "react";
2
- import type {
3
- InspectorCallbacks,
4
- InspectorLabels,
5
- InspectorTheme,
6
- UseInspectorReturn,
7
- SelectedElementData,
8
- UrlChangeData,
9
- PromptSubmittedData,
10
- TextUpdatedData,
11
- ImageUpdatedData,
12
- StyleUpdatedData,
13
- ErrorData,
14
- HighlightOptions,
15
- ElementInfoData,
16
- } from "@promakeai/inspector-types";
17
-
18
- type IframeMessage =
19
- | {
20
- type: "TOGGLE_INSPECTOR";
21
- active: boolean;
22
- labels?: InspectorLabels;
23
- theme?: InspectorTheme;
24
- }
25
- | {
26
- type: "SHOW_CONTENT_INPUT";
27
- show: boolean;
28
- updateImmediately?: boolean;
29
- }
30
- | {
31
- type: "SHOW_IMAGE_INPUT";
32
- show: boolean;
33
- updateImmediately?: boolean;
34
- }
35
- | {
36
- type: "SHOW_STYLE_EDITOR";
37
- show: boolean;
38
- }
39
- | {
40
- type: "SET_BADGE_VISIBLE";
41
- visible: boolean;
42
- badgeText?: string;
43
- }
44
- | {
45
- type: "HIGHLIGHT_ELEMENT";
46
- identifier: string | SelectedElementData;
47
- options?: HighlightOptions;
48
- }
49
- | {
50
- type: "GET_ELEMENT_BY_ID";
51
- inspectorId: string;
52
- }
53
- | {
54
- type: "SET_SHOW_CHILD_BORDERS";
55
- show: boolean;
56
- };
57
-
58
- type InspectorMessage =
59
- | {
60
- type: "INSPECTOR_ELEMENT_SELECTED";
61
- data: SelectedElementData;
62
- }
63
- | {
64
- type: "URL_CHANGED";
65
- data: UrlChangeData;
66
- }
67
- | {
68
- type: "INSPECTOR_PROMPT_SUBMITTED";
69
- data: PromptSubmittedData;
70
- }
71
- | {
72
- type: "INSPECTOR_TEXT_UPDATED";
73
- data: TextUpdatedData;
74
- }
75
- | {
76
- type: "INSPECTOR_IMAGE_UPDATED";
77
- data: ImageUpdatedData;
78
- }
79
- | {
80
- type: "INSPECTOR_STYLE_UPDATED";
81
- data: StyleUpdatedData;
82
- }
83
- | {
84
- type: "INSPECTOR_CLOSED";
85
- }
86
- | {
87
- type: "INSPECTOR_ERROR";
88
- data: ErrorData;
89
- }
90
- | {
91
- type: "ELEMENT_INFO_RESPONSE";
92
- data: ElementInfoData;
93
- };
94
-
95
- export function useInspector(
96
- iframeRef: RefObject<HTMLIFrameElement>,
97
- callbacks?: InspectorCallbacks,
98
- labels?: InspectorLabels,
99
- theme?: InspectorTheme
100
- ): UseInspectorReturn {
101
- const [isInspecting, setIsInspecting] = useState(false);
102
-
103
- /**
104
- * Send message to iframe
105
- */
106
- const sendMessage = useCallback(
107
- (message: IframeMessage) => {
108
- const iframe = iframeRef.current;
109
- if (!iframe || !iframe.contentWindow) {
110
- console.warn("Inspector: iframe not found or not loaded");
111
- return;
112
- }
113
-
114
- try {
115
- iframe.contentWindow.postMessage(message, "*");
116
- } catch (error) {
117
- console.error("Inspector: Failed to send message:", error);
118
- }
119
- },
120
- [iframeRef]
121
- );
122
-
123
- /**
124
- * Toggle inspector mode
125
- */
126
- const toggleInspector = useCallback(
127
- (active?: boolean) => {
128
- const newState = active !== undefined ? active : !isInspecting;
129
- setIsInspecting(newState);
130
-
131
- sendMessage({
132
- type: "TOGGLE_INSPECTOR",
133
- active: newState,
134
- labels: labels,
135
- theme: theme,
136
- });
137
- },
138
- [isInspecting, sendMessage, labels, theme]
139
- );
140
-
141
- /**
142
- * Start inspecting
143
- */
144
- const startInspecting = useCallback(() => {
145
- toggleInspector(true);
146
- }, [toggleInspector]);
147
-
148
- /**
149
- * Stop inspecting
150
- */
151
- const stopInspecting = useCallback(() => {
152
- toggleInspector(false);
153
- }, [toggleInspector]);
154
-
155
- /**
156
- * Show or hide content input
157
- */
158
- const showContentInput = useCallback(
159
- (show: boolean, updateImmediately?: boolean) => {
160
- sendMessage({
161
- type: "SHOW_CONTENT_INPUT",
162
- show: show,
163
- updateImmediately: updateImmediately,
164
- });
165
- },
166
- [sendMessage]
167
- );
168
-
169
- /**
170
- * Show or hide image input
171
- */
172
- const showImageInput = useCallback(
173
- (show: boolean, updateImmediately?: boolean) => {
174
- sendMessage({
175
- type: "SHOW_IMAGE_INPUT",
176
- show: show,
177
- updateImmediately: updateImmediately,
178
- });
179
- },
180
- [sendMessage]
181
- );
182
-
183
- /**
184
- * Show or hide style editor
185
- */
186
- const showStyleEditor = useCallback(
187
- (show: boolean) => {
188
- sendMessage({
189
- type: "SHOW_STYLE_EDITOR",
190
- show: show,
191
- });
192
- },
193
- [sendMessage]
194
- );
195
-
196
- /**
197
- * Show or hide "Built with Promake" badge
198
- */
199
- const setBadgeVisible = useCallback(
200
- (visible: boolean) => {
201
- sendMessage({
202
- type: "SET_BADGE_VISIBLE",
203
- visible: visible,
204
- badgeText: labels?.badgeText,
205
- });
206
- },
207
- [sendMessage, labels]
208
- );
209
-
210
- /**
211
- * Highlight an element in the iframe
212
- */
213
- const highlightElement = useCallback(
214
- (identifier: string | SelectedElementData, options?: HighlightOptions) => {
215
- sendMessage({
216
- type: "HIGHLIGHT_ELEMENT",
217
- identifier: identifier,
218
- options: options,
219
- });
220
- },
221
- [sendMessage]
222
- );
223
-
224
- /**
225
- * Request element info by inspector ID
226
- */
227
- const getElementByInspectorId = useCallback(
228
- (inspectorId: string) => {
229
- sendMessage({
230
- type: "GET_ELEMENT_BY_ID",
231
- inspectorId: inspectorId,
232
- });
233
- },
234
- [sendMessage]
235
- );
236
-
237
- /**
238
- * Toggle child borders visibility
239
- */
240
- const setShowChildBorders = useCallback(
241
- (show: boolean) => {
242
- sendMessage({
243
- type: "SET_SHOW_CHILD_BORDERS",
244
- show: show,
245
- });
246
- },
247
- [sendMessage]
248
- );
249
-
250
- /**
251
- * Listen for messages from iframe
252
- */
253
- useEffect(() => {
254
- const handleMessage = (event: MessageEvent<string | InspectorMessage>) => {
255
- // Parse message if it's a string (JSON stringified)
256
- let messageData: InspectorMessage;
257
-
258
- if (typeof event.data === "string") {
259
- try {
260
- messageData = JSON.parse(event.data);
261
- } catch {
262
- return; // Invalid JSON, ignore
263
- }
264
- } else {
265
- messageData = event.data;
266
- }
267
-
268
- // Security: Only handle expected message types
269
- if (!messageData || typeof messageData.type !== "string") {
270
- return;
271
- }
272
-
273
- switch (messageData.type) {
274
- case "INSPECTOR_ELEMENT_SELECTED":
275
- callbacks?.onElementSelected?.(messageData.data);
276
- break;
277
-
278
- case "URL_CHANGED":
279
- callbacks?.onUrlChange?.(messageData.data);
280
- break;
281
-
282
- case "INSPECTOR_PROMPT_SUBMITTED":
283
- callbacks?.onPromptSubmitted?.(messageData.data);
284
- break;
285
-
286
- case "INSPECTOR_TEXT_UPDATED":
287
- callbacks?.onTextUpdated?.(messageData.data);
288
- break;
289
-
290
- case "INSPECTOR_IMAGE_UPDATED":
291
- callbacks?.onImageUpdated?.(messageData.data);
292
- break;
293
-
294
- case "INSPECTOR_STYLE_UPDATED":
295
- callbacks?.onStyleUpdated?.(messageData.data);
296
- break;
297
-
298
- case "INSPECTOR_CLOSED":
299
- setIsInspecting(false);
300
- callbacks?.onInspectorClosed?.();
301
- break;
302
-
303
- case "INSPECTOR_ERROR":
304
- callbacks?.onError?.(messageData.data);
305
- break;
306
-
307
- case "ELEMENT_INFO_RESPONSE":
308
- callbacks?.onElementInfoReceived?.(messageData.data);
309
- break;
310
-
311
- default:
312
- // Unknown message type - ignore
313
- break;
314
- }
315
- };
316
-
317
- window.addEventListener("message", handleMessage);
318
-
319
- return () => {
320
- window.removeEventListener("message", handleMessage);
321
- };
322
- }, [callbacks]);
323
-
324
- /**
325
- * Cleanup: Turn off inspector on unmount
326
- */
327
- useEffect(() => {
328
- return () => {
329
- if (isInspecting) {
330
- sendMessage({
331
- type: "TOGGLE_INSPECTOR",
332
- active: false,
333
- labels: labels,
334
- theme: theme,
335
- });
336
- }
337
- };
338
- }, [isInspecting, sendMessage]);
339
-
340
- return {
341
- isInspecting,
342
- toggleInspector,
343
- startInspecting,
344
- stopInspecting,
345
- showContentInput,
346
- showImageInput,
347
- showStyleEditor,
348
- setBadgeVisible,
349
- highlightElement,
350
- getElementByInspectorId,
351
- setShowChildBorders,
352
- };
353
- }
354
-
355
- // Re-export types for convenience
356
- export type {
357
- ComponentInfo,
358
- ElementPosition,
359
- SelectedElementData,
360
- UrlChangeData,
361
- PromptSubmittedData,
362
- TextUpdatedData,
363
- ImageUpdatedData,
364
- StyleChanges,
365
- StyleUpdatedData,
366
- ErrorData,
367
- HighlightOptions,
368
- ElementInfoData,
369
- InspectorLabels,
370
- InspectorTheme,
371
- ContentInputRequestData,
372
- InspectorCallbacks,
373
- UseInspectorReturn,
374
- } from "@promakeai/inspector-types";
375
-
376
- // Export utility functions
377
- export { updateJSXSource } from "./utils/jsxUpdater.js";
378
- export type {
379
- UpdateJSXSourceOptions,
380
- UpdateJSXSourceResult,
381
- } from "./utils/jsxUpdater.js";
382
-
383
- // Export Vite plugin
384
- export { inspectorHookPlugin } from "./vite-plugin.js";
@@ -1,274 +0,0 @@
1
- /**
2
- * JSX Source Code Updater
3
- * AST-based utility for updating styles and classNames in JSX/TSX source code
4
- */
5
-
6
- import * as parser from '@babel/parser';
7
- import traverse from '@babel/traverse';
8
- import generate from '@babel/generator';
9
- import * as t from '@babel/types';
10
-
11
- export interface UpdateJSXSourceOptions {
12
- sourceCode: string;
13
- lineNumber: number;
14
- columnNumber: number;
15
- tagName: string;
16
- styles?: Record<string, string>;
17
- className?: string;
18
- }
19
-
20
- export interface UpdateJSXSourceResult {
21
- success: boolean;
22
- code: string;
23
- message?: string;
24
- }
25
-
26
- /**
27
- * Create AST ObjectExpression from styles object
28
- */
29
- function createStyleObjectExpression(styles: Record<string, string>): t.ObjectExpression {
30
- return t.objectExpression(
31
- Object.entries(styles).map(([key, value]) =>
32
- t.objectProperty(
33
- t.identifier(key),
34
- t.stringLiteral(value)
35
- )
36
- )
37
- );
38
- }
39
-
40
- /**
41
- * Find JSX element at specific line and column position
42
- */
43
- function findJSXElementAtPosition(
44
- ast: t.File,
45
- targetLine: number,
46
- targetColumn: number
47
- ): any {
48
- let foundElement: any = null;
49
-
50
- traverse(ast, {
51
- JSXOpeningElement(path: any) {
52
- const { loc } = path.node;
53
- if (
54
- loc &&
55
- loc.start.line === targetLine &&
56
- loc.start.column === targetColumn
57
- ) {
58
- foundElement = path;
59
- path.stop();
60
- }
61
- },
62
- });
63
-
64
- return foundElement;
65
- }
66
-
67
- /**
68
- * Merge new styles with existing style prop
69
- */
70
- function mergeStyleProp(
71
- jsxOpeningElement: any,
72
- newStyles: Record<string, string>
73
- ): void {
74
- const attributes = jsxOpeningElement.node.attributes;
75
-
76
- // Find existing style attribute
77
- const styleAttrIndex = attributes.findIndex(
78
- (attr: any) =>
79
- t.isJSXAttribute(attr) &&
80
- t.isJSXIdentifier(attr.name) &&
81
- attr.name.name === 'style'
82
- );
83
-
84
- const newStyleObjectExpression = createStyleObjectExpression(newStyles);
85
-
86
- if (styleAttrIndex !== -1) {
87
- // Update existing style attribute
88
- const styleAttr = attributes[styleAttrIndex];
89
-
90
- if (
91
- t.isJSXExpressionContainer(styleAttr.value) &&
92
- t.isObjectExpression(styleAttr.value.expression)
93
- ) {
94
- // Merge with existing styles
95
- const existingProps = styleAttr.value.expression.properties;
96
- const newProps = newStyleObjectExpression.properties;
97
-
98
- // Create map of new style keys
99
- const newStyleKeys = new Set(Object.keys(newStyles));
100
-
101
- // Filter out existing properties that will be replaced
102
- const filteredExisting = existingProps.filter(
103
- (prop: any) =>
104
- !t.isObjectProperty(prop) ||
105
- !t.isIdentifier(prop.key) ||
106
- !newStyleKeys.has(prop.key.name)
107
- );
108
-
109
- // Combine: keep non-updated existing properties + add new properties
110
- styleAttr.value.expression.properties = [
111
- ...filteredExisting,
112
- ...newProps,
113
- ];
114
- } else {
115
- // Replace entirely if existing value is not a simple object
116
- styleAttr.value = t.jsxExpressionContainer(newStyleObjectExpression);
117
- }
118
- } else {
119
- // Add new style attribute
120
- const styleAttr = t.jsxAttribute(
121
- t.jsxIdentifier('style'),
122
- t.jsxExpressionContainer(newStyleObjectExpression)
123
- );
124
- attributes.push(styleAttr);
125
- }
126
- }
127
-
128
- /**
129
- * Merge new className with existing className prop
130
- */
131
- function mergeClassNameProp(
132
- jsxOpeningElement: any,
133
- newClassName: string
134
- ): void {
135
- const attributes = jsxOpeningElement.node.attributes;
136
-
137
- // Find existing className attribute
138
- const classNameAttrIndex = attributes.findIndex(
139
- (attr: any) =>
140
- t.isJSXAttribute(attr) &&
141
- t.isJSXIdentifier(attr.name) &&
142
- attr.name.name === 'className'
143
- );
144
-
145
- if (classNameAttrIndex !== -1) {
146
- // Merge with existing className
147
- const classNameAttr = attributes[classNameAttrIndex];
148
-
149
- if (t.isStringLiteral(classNameAttr.value)) {
150
- // Simple string className
151
- const existingClasses = classNameAttr.value.value;
152
- classNameAttr.value = t.stringLiteral(`${existingClasses} ${newClassName}`.trim());
153
- } else if (
154
- t.isJSXExpressionContainer(classNameAttr.value) &&
155
- t.isStringLiteral(classNameAttr.value.expression)
156
- ) {
157
- // className={""} format
158
- const existingClasses = classNameAttr.value.expression.value;
159
- classNameAttr.value.expression = t.stringLiteral(`${existingClasses} ${newClassName}`.trim());
160
- } else if (
161
- t.isJSXExpressionContainer(classNameAttr.value) &&
162
- t.isTemplateLiteral(classNameAttr.value.expression)
163
- ) {
164
- // Template literal className
165
- const templateLiteral = classNameAttr.value.expression;
166
- const lastQuasi = templateLiteral.quasis[templateLiteral.quasis.length - 1];
167
- lastQuasi.value.raw += ` ${newClassName}`;
168
- lastQuasi.value.cooked = lastQuasi.value.raw;
169
- } else {
170
- // Complex expression - wrap in template literal
171
- classNameAttr.value = t.jsxExpressionContainer(
172
- t.templateLiteral(
173
- [
174
- t.templateElement({ raw: '', cooked: '' }, false),
175
- t.templateElement({ raw: ` ${newClassName}`, cooked: ` ${newClassName}` }, true),
176
- ],
177
- [classNameAttr.value.expression]
178
- )
179
- );
180
- }
181
- } else {
182
- // Add new className attribute
183
- const classNameAttr = t.jsxAttribute(
184
- t.jsxIdentifier('className'),
185
- t.stringLiteral(newClassName)
186
- );
187
- attributes.push(classNameAttr);
188
- }
189
- }
190
-
191
- /**
192
- * Update JSX source code with new styles and/or className
193
- *
194
- * @param options - Configuration options for the update
195
- * @returns Result object with success status, updated code, and optional message
196
- *
197
- * @example
198
- * ```typescript
199
- * const result = updateJSXSource({
200
- * sourceCode: '<div className="foo">Hello</div>',
201
- * lineNumber: 1,
202
- * columnNumber: 0,
203
- * tagName: 'div',
204
- * styles: { backgroundColor: 'red !important' },
205
- * className: 'bar'
206
- * });
207
- * // result.code: '<div className="foo bar" style={{ backgroundColor: "red !important" }}>Hello</div>'
208
- * ```
209
- */
210
- export function updateJSXSource(options: UpdateJSXSourceOptions): UpdateJSXSourceResult {
211
- const { sourceCode, lineNumber, columnNumber, tagName, styles, className } = options;
212
-
213
- try {
214
- // Parse JSX/TSX source code
215
- const ast = parser.parse(sourceCode, {
216
- sourceType: 'module',
217
- plugins: ['jsx', 'typescript', 'decorators-legacy'],
218
- });
219
-
220
- // Find the target JSX element at the specified position
221
- const elementPath = findJSXElementAtPosition(ast, lineNumber, columnNumber);
222
-
223
- if (!elementPath) {
224
- return {
225
- success: false,
226
- code: sourceCode,
227
- message: `Could not find JSX element <${tagName}> at line ${lineNumber}, column ${columnNumber}`,
228
- };
229
- }
230
-
231
- // Verify tag name matches (optional validation)
232
- const foundTagName = t.isJSXIdentifier(elementPath.node.name)
233
- ? elementPath.node.name.name
234
- : '';
235
-
236
- if (foundTagName.toLowerCase() !== tagName.toLowerCase()) {
237
- return {
238
- success: false,
239
- code: sourceCode,
240
- message: `Tag name mismatch: expected <${tagName}>, found <${foundTagName}>`,
241
- };
242
- }
243
-
244
- // Apply style updates if provided
245
- if (styles && Object.keys(styles).length > 0) {
246
- mergeStyleProp(elementPath, styles);
247
- }
248
-
249
- // Apply className updates if provided
250
- if (className && className.trim()) {
251
- mergeClassNameProp(elementPath, className.trim());
252
- }
253
-
254
- // Generate updated code
255
- const output = generate(ast, {
256
- retainLines: true,
257
- compact: false,
258
- concise: false,
259
- });
260
-
261
- return {
262
- success: true,
263
- code: output.code,
264
- message: 'JSX source updated successfully',
265
- };
266
- } catch (error) {
267
- return {
268
- success: false,
269
- code: sourceCode,
270
- message: error instanceof Error ? error.message : 'Unknown error occurred during JSX update',
271
- };
272
- }
273
- }
274
-