mitway-tagger 1.3.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.
package/dist/index.js ADDED
@@ -0,0 +1,865 @@
1
+ // src/features/jsxSource.ts
2
+ var VIRTUAL_JSX_RUNTIME = "virtual:mitway-jsx-runtime";
3
+ var RESOLVED_VIRTUAL_JSX_RUNTIME = "\0" + VIRTUAL_JSX_RUNTIME;
4
+ var ORIGINAL_JSX_RUNTIME = "\0__original_react_jsx_dev_runtime";
5
+ var JSX_RUNTIME_CODE = `
6
+ import * as OriginalRuntime from '\\0__original_react_jsx_dev_runtime';
7
+
8
+ // Symbol for storing source info on DOM nodes
9
+ const SOURCE_SYMBOL = Symbol.for('__mitwaySource__');
10
+
11
+ // Global map of source locations to DOM elements (using WeakRef)
12
+ if (typeof window !== 'undefined' && !window.mitwaySourceMap) {
13
+ window.mitwaySourceMap = new Map();
14
+ }
15
+
16
+ /**
17
+ * Creates a ref callback that attaches source info to the DOM node
18
+ */
19
+ function createSourceRef(source, existingRef) {
20
+ return (node) => {
21
+ if (node && source) {
22
+ // Attach source info directly to the DOM node
23
+ node[SOURCE_SYMBOL] = {
24
+ fileName: source.fileName,
25
+ lineNumber: source.lineNumber,
26
+ columnNumber: source.columnNumber,
27
+ };
28
+
29
+ // Add to global source map for lookup
30
+ if (typeof window !== 'undefined' && window.mitwaySourceMap) {
31
+ const key = source.fileName + ':' + source.lineNumber + ':' + source.columnNumber;
32
+
33
+ if (!window.mitwaySourceMap.has(key)) {
34
+ window.mitwaySourceMap.set(key, new Set());
35
+ }
36
+
37
+ // Use WeakRef to avoid memory leaks
38
+ const weakRef = new WeakRef(node);
39
+ window.mitwaySourceMap.get(key).add(weakRef);
40
+
41
+ // Cleanup dead refs periodically
42
+ const refs = window.mitwaySourceMap.get(key);
43
+ if (refs.size > 100) {
44
+ for (const ref of refs) {
45
+ if (!ref.deref()) {
46
+ refs.delete(ref);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ // Call existing ref if present
54
+ if (existingRef) {
55
+ if (typeof existingRef === 'function') {
56
+ existingRef(node);
57
+ } else if (typeof existingRef === 'object') {
58
+ existingRef.current = node;
59
+ }
60
+ }
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Custom jsxDEV that wraps the original with source tracking
66
+ */
67
+ export function jsxDEV(type, props, key, isStaticChildren, source, self) {
68
+ // Only track HTML elements and custom components, not fragments
69
+ if (source && type && typeof type !== 'symbol') {
70
+ const existingRef = props?.ref;
71
+ const newProps = {
72
+ ...props,
73
+ ref: createSourceRef(source, existingRef),
74
+ };
75
+
76
+ return OriginalRuntime.jsxDEV(type, newProps, key, isStaticChildren, source, self);
77
+ }
78
+
79
+ return OriginalRuntime.jsxDEV(type, props, key, isStaticChildren, source, self);
80
+ }
81
+
82
+ // Re-export everything else from the original runtime
83
+ export const Fragment = OriginalRuntime.Fragment;
84
+ export const jsx = OriginalRuntime.jsx;
85
+ export const jsxs = OriginalRuntime.jsxs;
86
+ `;
87
+ function createJsxSourcePlugin(options) {
88
+ return {
89
+ name: "mitway-tagger:jsx-source",
90
+ enforce: "pre",
91
+ resolveId(id, importer) {
92
+ if (id === ORIGINAL_JSX_RUNTIME || id === "\0__original_react_jsx_dev_runtime") {
93
+ return this.resolve("react/jsx-dev-runtime", importer, { skipSelf: true });
94
+ }
95
+ if (id === "react/jsx-dev-runtime") {
96
+ return RESOLVED_VIRTUAL_JSX_RUNTIME;
97
+ }
98
+ if (id === VIRTUAL_JSX_RUNTIME) {
99
+ return RESOLVED_VIRTUAL_JSX_RUNTIME;
100
+ }
101
+ return null;
102
+ },
103
+ load(id) {
104
+ if (id === RESOLVED_VIRTUAL_JSX_RUNTIME) {
105
+ return JSX_RUNTIME_CODE;
106
+ }
107
+ return null;
108
+ },
109
+ config() {
110
+ return {
111
+ // Ensure we're using jsxDEV in development
112
+ esbuild: {
113
+ jsx: "automatic",
114
+ jsxDev: true
115
+ }
116
+ };
117
+ }
118
+ };
119
+ }
120
+
121
+ // src/features/virtualOverrides.ts
122
+ import path from "path";
123
+ var virtualOverrides = /* @__PURE__ */ new Map();
124
+ function normalizePath(filePath) {
125
+ return filePath.replace(/\\/g, "/");
126
+ }
127
+ function getAbsolutePath(relativePath, root) {
128
+ if (path.isAbsolute(relativePath)) {
129
+ return normalizePath(relativePath);
130
+ }
131
+ return normalizePath(path.join(root, relativePath));
132
+ }
133
+ function findModuleByPath(server, filePath) {
134
+ const normalizedPath = normalizePath(filePath);
135
+ for (const [, mod] of server.moduleGraph.idToModuleMap) {
136
+ if (mod.file && normalizePath(mod.file) === normalizedPath) {
137
+ return mod;
138
+ }
139
+ }
140
+ const variations = [
141
+ normalizedPath,
142
+ "/" + normalizedPath,
143
+ normalizedPath.replace(/^\//, "")
144
+ ];
145
+ for (const variation of variations) {
146
+ const mod = server.moduleGraph.getModuleById(variation);
147
+ if (mod) return mod;
148
+ }
149
+ return void 0;
150
+ }
151
+ async function invalidateModule(server, filePath) {
152
+ const mod = findModuleByPath(server, filePath);
153
+ if (mod) {
154
+ server.moduleGraph.invalidateModule(mod);
155
+ if (mod.file) {
156
+ server.ws.send({
157
+ type: "update",
158
+ updates: [{
159
+ type: "js-update",
160
+ path: mod.url,
161
+ acceptedPath: mod.url,
162
+ timestamp: Date.now()
163
+ }]
164
+ });
165
+ }
166
+ return true;
167
+ }
168
+ server.ws.send({ type: "full-reload" });
169
+ return false;
170
+ }
171
+ function createVirtualOverridesPlugin() {
172
+ let server;
173
+ let root;
174
+ return {
175
+ name: "mitway-tagger:virtual-overrides",
176
+ enforce: "pre",
177
+ configResolved(config) {
178
+ root = config.root;
179
+ },
180
+ configureServer(_server) {
181
+ server = _server;
182
+ server.ws.on("mitway:override", async (data) => {
183
+ const absolutePath = getAbsolutePath(data.path, root);
184
+ console.log("[mitway-tagger] Setting override for:", absolutePath);
185
+ virtualOverrides.set(absolutePath, data.content);
186
+ await invalidateModule(server, absolutePath);
187
+ server.ws.send("mitway:override-applied", { path: data.path });
188
+ });
189
+ server.ws.on("mitway:clear-override", async (data) => {
190
+ const absolutePath = getAbsolutePath(data.path, root);
191
+ console.log("[mitway-tagger] Clearing override for:", absolutePath);
192
+ virtualOverrides.delete(absolutePath);
193
+ await invalidateModule(server, absolutePath);
194
+ server.ws.send("mitway:override-cleared", { path: data.path });
195
+ });
196
+ server.ws.on("mitway:clear-all-overrides", async () => {
197
+ console.log("[mitway-tagger] Clearing all overrides");
198
+ const paths = Array.from(virtualOverrides.keys());
199
+ virtualOverrides.clear();
200
+ for (const filePath of paths) {
201
+ await invalidateModule(server, filePath);
202
+ }
203
+ server.ws.send("mitway:all-overrides-cleared", { count: paths.length });
204
+ });
205
+ server.ws.on("mitway:get-overrides", () => {
206
+ const overrides = Array.from(virtualOverrides.entries()).map(([path2, content]) => ({
207
+ path: path2,
208
+ contentLength: content.length
209
+ }));
210
+ server.ws.send("mitway:overrides-list", { overrides });
211
+ });
212
+ },
213
+ /**
214
+ * Load hook - serves overridden content if available
215
+ */
216
+ load(id) {
217
+ const normalizedId = normalizePath(id);
218
+ if (virtualOverrides.has(normalizedId)) {
219
+ console.log("[mitway-tagger] Serving override for:", normalizedId);
220
+ return virtualOverrides.get(normalizedId);
221
+ }
222
+ const withoutSlash = normalizedId.replace(/^\//, "");
223
+ if (virtualOverrides.has(withoutSlash)) {
224
+ console.log("[mitway-tagger] Serving override for:", withoutSlash);
225
+ return virtualOverrides.get(withoutSlash);
226
+ }
227
+ return null;
228
+ },
229
+ /**
230
+ * Transform hook - can be used for additional processing
231
+ */
232
+ transform(code, id) {
233
+ return null;
234
+ }
235
+ };
236
+ }
237
+
238
+ // src/features/visualEditor.ts
239
+ var VISUAL_EDITOR_SCRIPT = `
240
+ <script>
241
+ (function() {
242
+ 'use strict';
243
+
244
+ // State
245
+ let isSelecting = false;
246
+ let selectedElement = null;
247
+ let originalStyles = new Map();
248
+ let highlightOverlay = null;
249
+ let selectionOverlay = null;
250
+
251
+ // Create highlight overlay element
252
+ function createOverlay(id, borderColor) {
253
+ const overlay = document.createElement('div');
254
+ overlay.id = id;
255
+ overlay.style.cssText = \`
256
+ position: fixed;
257
+ pointer-events: none;
258
+ border: 2px solid \${borderColor};
259
+ background: \${borderColor}10;
260
+ z-index: 999999;
261
+ transition: all 0.1s ease;
262
+ display: none;
263
+ \`;
264
+ document.body.appendChild(overlay);
265
+ return overlay;
266
+ }
267
+
268
+ // Initialize overlays
269
+ function initOverlays() {
270
+ if (!highlightOverlay) {
271
+ highlightOverlay = createOverlay('mitway-highlight-overlay', '#00BDFF');
272
+ }
273
+ if (!selectionOverlay) {
274
+ selectionOverlay = createOverlay('mitway-selection-overlay', '#00FF88');
275
+ selectionOverlay.style.border = '2px dashed #00FF88';
276
+ }
277
+ }
278
+
279
+ // Position overlay on element
280
+ function positionOverlay(overlay, element) {
281
+ if (!overlay || !element) return;
282
+ const rect = element.getBoundingClientRect();
283
+ overlay.style.top = rect.top + 'px';
284
+ overlay.style.left = rect.left + 'px';
285
+ overlay.style.width = rect.width + 'px';
286
+ overlay.style.height = rect.height + 'px';
287
+ overlay.style.display = 'block';
288
+ }
289
+
290
+ // Hide overlay
291
+ function hideOverlay(overlay) {
292
+ if (overlay) {
293
+ overlay.style.display = 'none';
294
+ }
295
+ }
296
+
297
+ // Get XPath for element
298
+ function getXPath(element) {
299
+ if (!element) return '';
300
+ if (element.id) return '//*[@id="' + element.id + '"]';
301
+ if (element === document.body) return '/html/body';
302
+
303
+ let ix = 0;
304
+ const siblings = element.parentNode ? element.parentNode.childNodes : [];
305
+
306
+ for (let i = 0; i < siblings.length; i++) {
307
+ const sibling = siblings[i];
308
+ if (sibling === element) {
309
+ const parentPath = getXPath(element.parentNode);
310
+ const tagName = element.tagName.toLowerCase();
311
+ return parentPath + '/' + tagName + '[' + (ix + 1) + ']';
312
+ }
313
+ if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
314
+ ix++;
315
+ }
316
+ }
317
+ return '';
318
+ }
319
+
320
+ // Get element by XPath
321
+ function getElementByXPath(xpath) {
322
+ try {
323
+ const result = document.evaluate(
324
+ xpath,
325
+ document,
326
+ null,
327
+ XPathResult.FIRST_ORDERED_NODE_TYPE,
328
+ null
329
+ );
330
+ return result.singleNodeValue;
331
+ } catch (e) {
332
+ return null;
333
+ }
334
+ }
335
+
336
+ // Check if element has dynamic styles (className with expressions)
337
+ function hasDynamicStyles(element) {
338
+ const classAttr = element.getAttribute('class') || '';
339
+ return classAttr.includes('\${') ||
340
+ classAttr.includes('?') ||
341
+ classAttr.includes('(') ||
342
+ element.className.includes('[object');
343
+ }
344
+
345
+ // Get computed styles for element
346
+ function getElementStyles(element) {
347
+ const computed = getComputedStyle(element);
348
+ return {
349
+ color: computed.color,
350
+ backgroundColor: computed.backgroundColor,
351
+ fontSize: computed.fontSize,
352
+ fontWeight: computed.fontWeight,
353
+ fontStyle: computed.fontStyle,
354
+ textAlign: computed.textAlign,
355
+ marginTop: computed.marginTop,
356
+ marginRight: computed.marginRight,
357
+ marginBottom: computed.marginBottom,
358
+ marginLeft: computed.marginLeft,
359
+ paddingTop: computed.paddingTop,
360
+ paddingRight: computed.paddingRight,
361
+ paddingBottom: computed.paddingBottom,
362
+ paddingLeft: computed.paddingLeft,
363
+ };
364
+ }
365
+
366
+ // Get source info from mitway-tagger jsxSource
367
+ function getSourceInfo(element) {
368
+ const SOURCE_SYMBOL = Symbol.for('__mitwaySource__');
369
+ let current = element;
370
+
371
+ // Walk up the tree to find the first element with source info
372
+ while (current && current !== document.body) {
373
+ if (current[SOURCE_SYMBOL]) {
374
+ return current[SOURCE_SYMBOL];
375
+ }
376
+ current = current.parentElement;
377
+ }
378
+
379
+ return null;
380
+ }
381
+
382
+ // Get element data for selection
383
+ function getElementData(element) {
384
+ const rect = element.getBoundingClientRect();
385
+ const sourceInfo = getSourceInfo(element);
386
+
387
+ return {
388
+ tagName: element.tagName,
389
+ textContent: element.textContent?.trim().substring(0, 500) || '',
390
+ className: element.className || '',
391
+ computedStyles: getElementStyles(element),
392
+ xpath: getXPath(element),
393
+ rect: {
394
+ top: rect.top,
395
+ left: rect.left,
396
+ width: rect.width,
397
+ height: rect.height,
398
+ },
399
+ hasDynamicStyles: hasDynamicStyles(element),
400
+ source: sourceInfo ? {
401
+ fileName: sourceInfo.fileName,
402
+ lineNumber: sourceInfo.lineNumber,
403
+ columnNumber: sourceInfo.columnNumber,
404
+ } : null,
405
+ };
406
+ }
407
+
408
+ // Store original inline styles
409
+ function storeOriginalStyles(element) {
410
+ if (!originalStyles.has(element)) {
411
+ originalStyles.set(element, element.getAttribute('style') || '');
412
+ }
413
+ }
414
+
415
+ // Apply preview styles to element
416
+ function applyPreviewStyles(element, styles) {
417
+ if (!element) return;
418
+ storeOriginalStyles(element);
419
+
420
+ Object.entries(styles).forEach(([key, value]) => {
421
+ if (value !== undefined && value !== null && value !== '') {
422
+ element.style[key] = value;
423
+ }
424
+ });
425
+
426
+ if (styles.textContent !== undefined) {
427
+ element.textContent = styles.textContent;
428
+ }
429
+
430
+ if (styles.classes !== undefined) {
431
+ element.className = styles.classes;
432
+ }
433
+ }
434
+
435
+ // Restore original styles
436
+ function restoreOriginalStyles(element) {
437
+ if (!element) return;
438
+ const original = originalStyles.get(element);
439
+ if (original !== undefined) {
440
+ element.setAttribute('style', original);
441
+ originalStyles.delete(element);
442
+ } else {
443
+ element.removeAttribute('style');
444
+ }
445
+ }
446
+
447
+ // Handle mouse move during selection
448
+ function handleMouseMove(event) {
449
+ if (!isSelecting) return;
450
+
451
+ const target = event.target;
452
+
453
+ if (target.id === 'mitway-highlight-overlay' ||
454
+ target.id === 'mitway-selection-overlay' ||
455
+ target.tagName === 'SCRIPT' ||
456
+ target.tagName === 'STYLE' ||
457
+ target.tagName === 'HTML') {
458
+ return;
459
+ }
460
+
461
+ positionOverlay(highlightOverlay, target);
462
+
463
+ window.parent?.postMessage({
464
+ type: 'VISUAL_EDITOR_ELEMENT_HOVER',
465
+ payload: {
466
+ tagName: target.tagName,
467
+ className: target.className,
468
+ }
469
+ }, '*');
470
+ }
471
+
472
+ // Handle click during selection
473
+ function handleClick(event) {
474
+ if (!isSelecting) return;
475
+
476
+ event.preventDefault();
477
+ event.stopPropagation();
478
+
479
+ const target = event.target;
480
+
481
+ if (target.id === 'mitway-highlight-overlay' ||
482
+ target.id === 'mitway-selection-overlay') {
483
+ return;
484
+ }
485
+
486
+ selectedElement = target;
487
+ isSelecting = false;
488
+
489
+ hideOverlay(highlightOverlay);
490
+ positionOverlay(selectionOverlay, target);
491
+
492
+ window.parent?.postMessage({
493
+ type: 'VISUAL_EDITOR_ELEMENT_SELECTED',
494
+ payload: getElementData(target)
495
+ }, '*');
496
+ }
497
+
498
+ // Enable selector mode
499
+ function enableSelector() {
500
+ initOverlays();
501
+ isSelecting = true;
502
+ selectedElement = null;
503
+ hideOverlay(selectionOverlay);
504
+ document.body.style.cursor = 'crosshair';
505
+ document.addEventListener('mousemove', handleMouseMove, true);
506
+ document.addEventListener('click', handleClick, true);
507
+ }
508
+
509
+ // Disable selector mode
510
+ function disableSelector() {
511
+ isSelecting = false;
512
+ selectedElement = null;
513
+ document.body.style.cursor = '';
514
+ document.removeEventListener('mousemove', handleMouseMove, true);
515
+ document.removeEventListener('click', handleClick, true);
516
+ hideOverlay(highlightOverlay);
517
+ hideOverlay(selectionOverlay);
518
+
519
+ originalStyles.forEach((_, element) => {
520
+ restoreOriginalStyles(element);
521
+ });
522
+ originalStyles.clear();
523
+ }
524
+
525
+ // Listen for messages from parent (mITway-App)
526
+ window.addEventListener('message', (event) => {
527
+ if (!event.data || typeof event.data.type !== 'string') return;
528
+
529
+ const { type, payload } = event.data;
530
+
531
+ switch (type) {
532
+ case 'VISUAL_EDITOR_ENABLE_SELECTOR':
533
+ enableSelector();
534
+ break;
535
+
536
+ case 'VISUAL_EDITOR_DISABLE_SELECTOR':
537
+ disableSelector();
538
+ break;
539
+
540
+ case 'VISUAL_EDITOR_PREVIEW_STYLES':
541
+ if (payload?.xpath) {
542
+ const element = getElementByXPath(payload.xpath);
543
+ if (element) {
544
+ applyPreviewStyles(element, payload.styles || {});
545
+ }
546
+ }
547
+ break;
548
+
549
+ case 'VISUAL_EDITOR_RESTORE_ORIGINAL':
550
+ if (payload?.xpath) {
551
+ const element = getElementByXPath(payload.xpath);
552
+ if (element) {
553
+ restoreOriginalStyles(element);
554
+ }
555
+ }
556
+ break;
557
+ }
558
+ });
559
+
560
+ // Notify parent that visual editor bridge is ready
561
+ window.parent?.postMessage({ type: 'VISUAL_EDITOR_BRIDGE_READY' }, '*');
562
+ })();
563
+ </script>`;
564
+ function createVisualEditorPlugin() {
565
+ return {
566
+ name: "mitway-tagger:visual-editor",
567
+ transformIndexHtml(html) {
568
+ return html.replace("</head>", VISUAL_EDITOR_SCRIPT + "\n</head>");
569
+ }
570
+ };
571
+ }
572
+
573
+ // src/features/iframeNavigation.ts
574
+ var IFRAME_NAVIGATION_SCRIPT = `
575
+ <script>
576
+ (function() {
577
+ 'use strict';
578
+
579
+ let lastPath = window.location.pathname + window.location.search + window.location.hash;
580
+
581
+ function notifyParent() {
582
+ const path = window.location.pathname + window.location.search + window.location.hash;
583
+
584
+ if (path !== lastPath) {
585
+ lastPath = path;
586
+
587
+ try {
588
+ window.parent.postMessage({
589
+ type: 'IFRAME_NAVIGATION',
590
+ url: path
591
+ }, '*');
592
+ } catch (e) {
593
+ // Silently fail if postMessage is blocked
594
+ }
595
+ }
596
+ }
597
+
598
+ // Intercept history methods
599
+ const originalPushState = history.pushState;
600
+ const originalReplaceState = history.replaceState;
601
+
602
+ history.pushState = function() {
603
+ originalPushState.apply(this, arguments);
604
+ setTimeout(notifyParent, 0);
605
+ };
606
+
607
+ history.replaceState = function() {
608
+ originalReplaceState.apply(this, arguments);
609
+ setTimeout(notifyParent, 0);
610
+ };
611
+
612
+ // Listen to navigation events
613
+ window.addEventListener('popstate', function() {
614
+ setTimeout(notifyParent, 0);
615
+ });
616
+
617
+ document.addEventListener('click', function() {
618
+ setTimeout(notifyParent, 100);
619
+ }, true);
620
+
621
+ // Initial notification
622
+ setTimeout(notifyParent, 500);
623
+
624
+ // Fallback check
625
+ setInterval(notifyParent, 500);
626
+
627
+ // Listen for parent navigation commands
628
+ window.addEventListener('message', function(event) {
629
+ if (event.data && event.data.type === 'NAVIGATE_TO') {
630
+ window.history.pushState(null, '', event.data.url);
631
+ window.dispatchEvent(new PopStateEvent('popstate'));
632
+ setTimeout(notifyParent, 0);
633
+ }
634
+ });
635
+ })();
636
+ </script>`;
637
+ function createIframeNavigationPlugin() {
638
+ return {
639
+ name: "mitway-tagger:iframe-navigation",
640
+ transformIndexHtml(html) {
641
+ return html.replace("</body>", `${IFRAME_NAVIGATION_SCRIPT}</body>`);
642
+ }
643
+ };
644
+ }
645
+
646
+ // src/features/themeBridge.ts
647
+ var THEME_BRIDGE_SCRIPT = `
648
+ <script>
649
+ (function() {
650
+ // Store original CSS variable values for restoration
651
+ let originalStyles = {};
652
+
653
+ // CSS variables used in the theme
654
+ // Base variables (without --color- prefix, used in :root)
655
+ const baseVars = [
656
+ '--background', '--foreground', '--card', '--card-foreground',
657
+ '--popover', '--popover-foreground', '--primary', '--primary-foreground',
658
+ '--secondary', '--secondary-foreground', '--muted', '--muted-foreground',
659
+ '--accent', '--accent-foreground', '--destructive', '--destructive-foreground',
660
+ '--border', '--input', '--ring',
661
+ '--chart-1', '--chart-2', '--chart-3', '--chart-4', '--chart-5',
662
+ '--sidebar', '--sidebar-foreground', '--sidebar-primary',
663
+ '--sidebar-primary-foreground', '--sidebar-accent', '--sidebar-accent-foreground',
664
+ '--sidebar-border', '--sidebar-ring'
665
+ ];
666
+
667
+ // Radius variables (no hsl wrapper needed)
668
+ const radiusVars = ['--radius', '--radius-sm', '--radius-md', '--radius-lg', '--radius-xl'];
669
+
670
+ // Capture original styles on first preview
671
+ function captureOriginalStyles() {
672
+ if (Object.keys(originalStyles).length > 0) return;
673
+ const root = document.documentElement;
674
+ const computed = getComputedStyle(root);
675
+ [...baseVars, ...radiusVars].forEach(prop => {
676
+ const value = computed.getPropertyValue(prop).trim();
677
+ if (value) originalStyles[prop] = value;
678
+ });
679
+ }
680
+
681
+ // Check if a value is a radius (not a color)
682
+ function isRadiusVar(key) {
683
+ return key.includes('radius');
684
+ }
685
+
686
+ // Normalize variable name to base format (--background, --primary, etc.)
687
+ function normalizeVarName(key) {
688
+ // Remove leading dashes if present
689
+ let normalized = key.replace(/^-+/, '');
690
+
691
+ // Remove 'color-' prefix if present (convert from Tailwind v4 format)
692
+ if (normalized.startsWith('color-')) {
693
+ normalized = normalized.replace('color-', '');
694
+ }
695
+
696
+ return '--' + normalized;
697
+ }
698
+
699
+ // Wrap color value with hsl() if needed
700
+ function wrapWithHsl(value, isRadius) {
701
+ if (isRadius) return value;
702
+
703
+ // Already has hsl/hsla/rgb/rgba/oklch wrapper
704
+ if (/^(hsl|hsla|rgb|rgba|oklch)\\(/.test(value)) {
705
+ return value;
706
+ }
707
+
708
+ // Wrap with hsl()
709
+ return 'hsl(' + value + ')';
710
+ }
711
+
712
+ // Apply theme colors to CSS variables
713
+ // Values are received WITHOUT hsl() wrapper from mITway-App
714
+ function applyTheme(theme) {
715
+ if (!theme) return;
716
+ const root = document.documentElement;
717
+
718
+ Object.entries(theme).forEach(([key, value]) => {
719
+ const cssVar = normalizeVarName(key);
720
+ const isRadius = isRadiusVar(key);
721
+ const finalValue = wrapWithHsl(value, isRadius);
722
+
723
+ // Set the base variable (--background, --primary, etc.)
724
+ root.style.setProperty(cssVar, finalValue);
725
+
726
+ // Also set with --color- prefix for @theme inline compatibility
727
+ if (!isRadius) {
728
+ const colorVar = '--color-' + cssVar.replace('--', '');
729
+ root.style.setProperty(colorVar, finalValue);
730
+ }
731
+ });
732
+ }
733
+
734
+ // Restore original CSS variables
735
+ function restoreOriginal() {
736
+ const root = document.documentElement;
737
+ Object.entries(originalStyles).forEach(([key, value]) => {
738
+ root.style.setProperty(key, value);
739
+ // Also restore --color- prefixed version
740
+ if (!isRadiusVar(key)) {
741
+ const colorVar = '--color-' + key.replace('--', '');
742
+ root.style.setProperty(colorVar, value);
743
+ }
744
+ });
745
+ }
746
+
747
+ // Listen for theme messages from parent (mITway-App)
748
+ window.addEventListener('message', (event) => {
749
+ // Accept messages from any origin (mITway-App domains)
750
+ if (!event.data || typeof event.data.type !== 'string') return;
751
+
752
+ switch (event.data.type) {
753
+ case 'PREVIEW_THEME':
754
+ captureOriginalStyles();
755
+ applyTheme(event.data.theme);
756
+ break;
757
+
758
+ case 'RESTORE_THEME':
759
+ restoreOriginal();
760
+ break;
761
+
762
+ case 'APPLY_THEME':
763
+ applyTheme(event.data.theme);
764
+ // Notify parent that theme was applied
765
+ window.parent?.postMessage({
766
+ type: 'THEME_APPLIED',
767
+ themeId: event.data.themeId
768
+ }, '*');
769
+ break;
770
+ }
771
+ });
772
+
773
+ // Notify parent that theme bridge is ready
774
+ window.parent?.postMessage({ type: 'THEME_BRIDGE_READY' }, '*');
775
+ })();
776
+ </script>`;
777
+ function createThemeBridgePlugin() {
778
+ return {
779
+ name: "mitway-tagger:theme-bridge",
780
+ transformIndexHtml(html) {
781
+ return html.replace("</head>", `${THEME_BRIDGE_SCRIPT}
782
+ </head>`);
783
+ }
784
+ };
785
+ }
786
+
787
+ // src/index.ts
788
+ var defaultOptions = {
789
+ jsxSource: true,
790
+ virtualOverrides: true,
791
+ visualEditor: true,
792
+ iframeNavigation: true,
793
+ themeBridge: true,
794
+ extensions: [".jsx", ".tsx"],
795
+ exclude: ["node_modules", ".git"]
796
+ };
797
+ function mitwayTagger(options = {}) {
798
+ const opts = { ...defaultOptions, ...options };
799
+ const plugins = [];
800
+ if (opts.jsxSource) {
801
+ plugins.push(createJsxSourcePlugin(opts));
802
+ }
803
+ if (opts.virtualOverrides) {
804
+ plugins.push(createVirtualOverridesPlugin());
805
+ }
806
+ if (opts.visualEditor) {
807
+ plugins.push(createVisualEditorPlugin());
808
+ }
809
+ if (opts.iframeNavigation) {
810
+ plugins.push(createIframeNavigationPlugin());
811
+ }
812
+ if (opts.themeBridge) {
813
+ plugins.push(createThemeBridgePlugin());
814
+ }
815
+ return plugins;
816
+ }
817
+ var index_default = mitwayTagger;
818
+ var mitwayServerConfig = {
819
+ host: "0.0.0.0",
820
+ port: 80,
821
+ cors: {
822
+ origin: [
823
+ "https://app.nttmitway.com",
824
+ "https://app.dev.nttmitway.com",
825
+ "http://app.mitway.local",
826
+ /^http:\/\/localhost(:\d+)?$/
827
+ ],
828
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
829
+ allowedHeaders: ["Content-Type", "Authorization"],
830
+ credentials: true
831
+ },
832
+ headers: {
833
+ "Content-Security-Policy": "frame-ancestors https://app.nttmitway.com https://app.dev.nttmitway.com http://app.mitway.local http://localhost:*"
834
+ },
835
+ allowedHosts: [".azurecontainerapps.io", ".nttmitway.com"]
836
+ };
837
+ function createmITwayServerConfig(options = {}) {
838
+ const { additionalOrigins = [], additionalHosts = [], port = 80 } = options;
839
+ const allOrigins = [...mitwayServerConfig.cors.origin, ...additionalOrigins];
840
+ const allHosts = [...mitwayServerConfig.allowedHosts, ...additionalHosts];
841
+ const frameAncestors = allOrigins.filter((o) => typeof o === "string").join(" ");
842
+ return {
843
+ host: "0.0.0.0",
844
+ port,
845
+ cors: {
846
+ ...mitwayServerConfig.cors,
847
+ origin: allOrigins
848
+ },
849
+ headers: {
850
+ "Content-Security-Policy": `frame-ancestors ${frameAncestors} http://localhost:*`
851
+ },
852
+ allowedHosts: allHosts
853
+ };
854
+ }
855
+ export {
856
+ createIframeNavigationPlugin,
857
+ createJsxSourcePlugin,
858
+ createThemeBridgePlugin,
859
+ createVirtualOverridesPlugin,
860
+ createVisualEditorPlugin,
861
+ createmITwayServerConfig,
862
+ index_default as default,
863
+ mitwayServerConfig,
864
+ mitwayTagger
865
+ };