unified-video-framework 1.4.382 → 1.4.384
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/core/dist/interfaces.d.ts +28 -2
- package/packages/core/dist/interfaces.d.ts.map +1 -1
- package/packages/core/dist/interfaces.js +0 -1
- package/packages/core/dist/interfaces.js.map +1 -1
- package/packages/core/src/interfaces.ts +53 -3
- package/packages/react-native/dist/drm/AndroidDRMProtection.js +1 -1
- package/packages/react-native/dist/drm/iOSDRMProtection.js +1 -1
- package/packages/web/dist/WebPlayer.d.ts +2 -0
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +9731 -9644
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/dist/drm/DRMHelper.d.ts +28 -0
- package/packages/web/dist/drm/DRMHelper.d.ts.map +1 -0
- package/packages/web/dist/drm/DRMHelper.js +117 -0
- package/packages/web/dist/drm/DRMHelper.js.map +1 -0
- package/packages/web/dist/index.d.ts +0 -1
- package/packages/web/dist/index.d.ts.map +1 -1
- package/packages/web/dist/index.js +6 -7
- package/packages/web/dist/index.js.map +1 -1
- package/packages/web/dist/react/WebPlayerView.d.ts +21 -0
- package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
- package/packages/web/dist/react/WebPlayerView.js.map +1 -1
- package/packages/web/dist/security/CanvasVideoRenderer.d.ts +26 -0
- package/packages/web/dist/security/CanvasVideoRenderer.d.ts.map +1 -0
- package/packages/web/dist/security/CanvasVideoRenderer.js +143 -0
- package/packages/web/dist/security/CanvasVideoRenderer.js.map +1 -0
- package/packages/web/dist/security/ScreenProtectionController.d.ts +39 -0
- package/packages/web/dist/security/ScreenProtectionController.d.ts.map +1 -0
- package/packages/web/dist/security/ScreenProtectionController.js +278 -0
- package/packages/web/dist/security/ScreenProtectionController.js.map +1 -0
- package/packages/web/src/WebPlayer.ts +120 -2
- package/packages/web/src/drm/DRMHelper.ts +203 -0
- package/packages/web/src/index.ts +0 -3
- package/packages/web/src/react/WebPlayerView.tsx +24 -0
- package/packages/web/src/security/CanvasVideoRenderer.ts +246 -0
- package/packages/web/src/security/ScreenProtectionController.ts +391 -0
- package/scripts/fix-imports.js +18 -16
- package/packages/core/src/interfaces/IDRMProtection.ts +0 -285
- package/packages/react-native/src/drm/AndroidDRMProtection.ts +0 -419
- package/packages/react-native/src/drm/iOSDRMProtection.ts +0 -415
- package/packages/web/src/drm/WebDRMProtection.ts +0 -596
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { ScreenCaptureEvent, EnhancedScreenProtectionConfig } from '@unified-video/core';
|
|
2
|
+
import { CanvasVideoRenderer } from './CanvasVideoRenderer';
|
|
3
|
+
|
|
4
|
+
export interface ScreenProtectionOptions {
|
|
5
|
+
videoElement: HTMLVideoElement;
|
|
6
|
+
containerElement: HTMLElement;
|
|
7
|
+
config: EnhancedScreenProtectionConfig;
|
|
8
|
+
watermarkConfig?: any;
|
|
9
|
+
onDetection?: (event: ScreenCaptureEvent) => void;
|
|
10
|
+
onDevToolsDetected?: () => void;
|
|
11
|
+
onPause?: () => void; // Callback to pause video
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ScreenProtectionController {
|
|
15
|
+
private opts: ScreenProtectionOptions;
|
|
16
|
+
private overlayElement: HTMLElement | null = null;
|
|
17
|
+
private canvasRenderer: CanvasVideoRenderer | null = null;
|
|
18
|
+
private detectionIntervals: NodeJS.Timeout[] = [];
|
|
19
|
+
private eventListeners: Array<{ target: any; event: string; handler: any }> = [];
|
|
20
|
+
private isActive: boolean = false;
|
|
21
|
+
private devToolsOpen: boolean = false;
|
|
22
|
+
private originalGetDisplayMedia: any = null;
|
|
23
|
+
|
|
24
|
+
constructor(opts: ScreenProtectionOptions) {
|
|
25
|
+
this.opts = opts;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public activate(): void {
|
|
29
|
+
if (this.isActive) return;
|
|
30
|
+
|
|
31
|
+
console.log('[ScreenProtectionController] Activating screen protection...');
|
|
32
|
+
|
|
33
|
+
// Apply video element protection
|
|
34
|
+
this.applyVideoProtection();
|
|
35
|
+
|
|
36
|
+
// Initialize canvas rendering if enabled
|
|
37
|
+
this.initializeCanvasRendering();
|
|
38
|
+
|
|
39
|
+
// Create interference overlay (only if not using canvas)
|
|
40
|
+
if (!this.canvasRenderer) {
|
|
41
|
+
this.createInterferenceOverlay();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Setup behavioral detection
|
|
45
|
+
this.setupDetection();
|
|
46
|
+
|
|
47
|
+
this.isActive = true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public deactivate(): void {
|
|
51
|
+
if (!this.isActive) return;
|
|
52
|
+
|
|
53
|
+
console.log('[ScreenProtectionController] Deactivating screen protection...');
|
|
54
|
+
|
|
55
|
+
// Deactivate canvas renderer
|
|
56
|
+
if (this.canvasRenderer) {
|
|
57
|
+
this.canvasRenderer.deactivate();
|
|
58
|
+
this.canvasRenderer = null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Remove overlay
|
|
62
|
+
if (this.overlayElement && this.overlayElement.parentElement) {
|
|
63
|
+
this.overlayElement.parentElement.removeChild(this.overlayElement);
|
|
64
|
+
this.overlayElement = null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Clear all intervals
|
|
68
|
+
this.detectionIntervals.forEach(interval => clearInterval(interval));
|
|
69
|
+
this.detectionIntervals = [];
|
|
70
|
+
|
|
71
|
+
// Remove all event listeners
|
|
72
|
+
this.eventListeners.forEach(({ target, event, handler }) => {
|
|
73
|
+
target.removeEventListener(event, handler);
|
|
74
|
+
});
|
|
75
|
+
this.eventListeners = [];
|
|
76
|
+
|
|
77
|
+
// Restore original getDisplayMedia
|
|
78
|
+
if (this.originalGetDisplayMedia && navigator.mediaDevices) {
|
|
79
|
+
navigator.mediaDevices.getDisplayMedia = this.originalGetDisplayMedia;
|
|
80
|
+
this.originalGetDisplayMedia = null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.isActive = false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public destroy(): void {
|
|
87
|
+
this.deactivate();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private initializeCanvasRendering(): void {
|
|
91
|
+
// Check if canvas rendering is enabled
|
|
92
|
+
if (!this.opts.config.canvasRendering?.enabled) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log('[ScreenProtectionController] Initializing canvas-based video rendering...');
|
|
97
|
+
console.warn('[ScreenProtectionController] WARNING: Canvas rendering does NOT prevent screenshots.');
|
|
98
|
+
console.warn('[ScreenProtectionController] This only adds obfuscation. Use DRM for true protection.');
|
|
99
|
+
|
|
100
|
+
// Get watermark text
|
|
101
|
+
const watermarkText = this.opts.config.forensicWatermark?.userId
|
|
102
|
+
? `PROTECTED - ${this.opts.config.forensicWatermark.userId}`
|
|
103
|
+
: 'PROTECTED CONTENT';
|
|
104
|
+
|
|
105
|
+
// Create canvas renderer
|
|
106
|
+
this.canvasRenderer = new CanvasVideoRenderer({
|
|
107
|
+
sourceVideo: this.opts.videoElement,
|
|
108
|
+
containerElement: this.opts.containerElement,
|
|
109
|
+
watermarkText: watermarkText,
|
|
110
|
+
enableNoise: this.opts.config.canvasRendering.enableNoise ?? true,
|
|
111
|
+
enableDynamicTransforms: this.opts.config.canvasRendering.enableDynamicTransforms ?? true
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Activate canvas rendering
|
|
115
|
+
this.canvasRenderer.activate();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private applyVideoProtection(): void {
|
|
119
|
+
const { videoElement, containerElement } = this.opts;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
// Prevent Picture-in-Picture
|
|
123
|
+
videoElement.disablePictureInPicture = true;
|
|
124
|
+
(videoElement as any).autoPictureInPicture = false;
|
|
125
|
+
} catch (e) {
|
|
126
|
+
console.warn('[ScreenProtection] Could not disable PiP:', e);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
// Set controlsList to hide download button (if supported)
|
|
131
|
+
if ('controlsList' in videoElement) {
|
|
132
|
+
(videoElement as any).controlsList.add('nodownload');
|
|
133
|
+
}
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.warn('[ScreenProtection] controlsList not supported:', e);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Prevent text selection
|
|
139
|
+
containerElement.style.userSelect = 'none';
|
|
140
|
+
containerElement.style.webkitUserSelect = 'none';
|
|
141
|
+
(containerElement.style as any).webkitTouchCallout = 'none';
|
|
142
|
+
|
|
143
|
+
// Prevent right-click context menu
|
|
144
|
+
const contextMenuHandler = (e: Event): boolean => {
|
|
145
|
+
if (containerElement.contains(e.target as Node)) {
|
|
146
|
+
e.preventDefault();
|
|
147
|
+
e.stopPropagation();
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
};
|
|
152
|
+
document.addEventListener('contextmenu', contextMenuHandler);
|
|
153
|
+
this.eventListeners.push({ target: document, event: 'contextmenu', handler: contextMenuHandler });
|
|
154
|
+
|
|
155
|
+
console.log('[ScreenProtection] Video protection applied');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private createInterferenceOverlay(): void {
|
|
159
|
+
const { containerElement } = this.opts;
|
|
160
|
+
|
|
161
|
+
// Create transparent overlay
|
|
162
|
+
this.overlayElement = document.createElement('div');
|
|
163
|
+
this.overlayElement.className = 'uvf-screen-protection-overlay';
|
|
164
|
+
this.overlayElement.setAttribute('aria-hidden', 'true');
|
|
165
|
+
|
|
166
|
+
// Style the overlay
|
|
167
|
+
Object.assign(this.overlayElement.style, {
|
|
168
|
+
position: 'absolute',
|
|
169
|
+
top: '0',
|
|
170
|
+
left: '0',
|
|
171
|
+
width: '100%',
|
|
172
|
+
height: '100%',
|
|
173
|
+
pointerEvents: 'none', // Don't block user interactions
|
|
174
|
+
zIndex: '3', // Between video (1) and watermark (5)
|
|
175
|
+
mixBlendMode: 'screen',
|
|
176
|
+
opacity: '0.01',
|
|
177
|
+
background: 'transparent',
|
|
178
|
+
// Add subtle noise pattern
|
|
179
|
+
backgroundImage: 'url("data:image/svg+xml,%3Csvg viewBox=\'0 0 256 256\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cfilter id=\'noise\'%3E%3CfeTurbulence type=\'fractalNoise\' baseFrequency=\'0.9\' numOctaves=\'4\' stitchTiles=\'stitch\'/%3E%3C/filter%3E%3Crect width=\'100%25\' height=\'100%25\' filter=\'url(%23noise)\' opacity=\'0.05\'/%3E%3C/svg%3E")',
|
|
180
|
+
transition: 'opacity 0.3s ease-in-out'
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Insert into container
|
|
184
|
+
const watermarkCanvas = containerElement.querySelector('.uvf-watermark-layer');
|
|
185
|
+
if (watermarkCanvas) {
|
|
186
|
+
containerElement.insertBefore(this.overlayElement, watermarkCanvas);
|
|
187
|
+
} else {
|
|
188
|
+
containerElement.appendChild(this.overlayElement);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Start overlay animation
|
|
192
|
+
this.animateOverlay();
|
|
193
|
+
|
|
194
|
+
console.log('[ScreenProtection] Interference overlay created');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private animateOverlay(): void {
|
|
198
|
+
if (!this.overlayElement || !this.isActive) return;
|
|
199
|
+
|
|
200
|
+
// Subtle opacity pulsing
|
|
201
|
+
const baseOpacity = 0.01;
|
|
202
|
+
const variation = baseOpacity * 0.5;
|
|
203
|
+
const newOpacity = baseOpacity + (Math.random() * variation - variation / 2);
|
|
204
|
+
|
|
205
|
+
this.overlayElement.style.opacity = newOpacity.toString();
|
|
206
|
+
|
|
207
|
+
// Continue animation
|
|
208
|
+
setTimeout(() => this.animateOverlay(), 3000 + Math.random() * 2000);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private setupDetection(): void {
|
|
212
|
+
// DevTools detection
|
|
213
|
+
this.detectDevTools();
|
|
214
|
+
|
|
215
|
+
// Focus loss detection
|
|
216
|
+
this.detectFocusLoss();
|
|
217
|
+
|
|
218
|
+
// Visibility change detection
|
|
219
|
+
this.detectVisibilityChange();
|
|
220
|
+
|
|
221
|
+
// Screen Capture API detection
|
|
222
|
+
this.detectScreenCaptureAPI();
|
|
223
|
+
|
|
224
|
+
console.log('[ScreenProtection] Detection mechanisms active');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private detectDevTools(): void {
|
|
228
|
+
const threshold = 160;
|
|
229
|
+
let previousState = false;
|
|
230
|
+
|
|
231
|
+
const checkDevTools = () => {
|
|
232
|
+
if (!this.isActive) return;
|
|
233
|
+
|
|
234
|
+
const widthDiff = window.outerWidth - window.innerWidth;
|
|
235
|
+
const heightDiff = window.outerHeight - window.innerHeight;
|
|
236
|
+
|
|
237
|
+
const isOpen = widthDiff > threshold || heightDiff > threshold;
|
|
238
|
+
|
|
239
|
+
if (isOpen && !previousState) {
|
|
240
|
+
this.devToolsOpen = true;
|
|
241
|
+
this.handleDetection({
|
|
242
|
+
type: 'devtools',
|
|
243
|
+
timestamp: Date.now(),
|
|
244
|
+
details: { widthDiff, heightDiff }
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (this.opts.onDevToolsDetected) {
|
|
248
|
+
this.opts.onDevToolsDetected();
|
|
249
|
+
}
|
|
250
|
+
} else if (!isOpen && previousState) {
|
|
251
|
+
this.devToolsOpen = false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
previousState = isOpen;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const interval = setInterval(checkDevTools, 500);
|
|
258
|
+
this.detectionIntervals.push(interval);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private detectFocusLoss(): void {
|
|
262
|
+
const blurHandler = () => {
|
|
263
|
+
this.handleDetection({
|
|
264
|
+
type: 'focus-loss',
|
|
265
|
+
timestamp: Date.now(),
|
|
266
|
+
details: { documentHidden: document.hidden }
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
window.addEventListener('blur', blurHandler);
|
|
271
|
+
this.eventListeners.push({ target: window, event: 'blur', handler: blurHandler });
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private detectVisibilityChange(): void {
|
|
275
|
+
const visibilityHandler = () => {
|
|
276
|
+
if (document.hidden) {
|
|
277
|
+
this.handleDetection({
|
|
278
|
+
type: 'visibility-change',
|
|
279
|
+
timestamp: Date.now(),
|
|
280
|
+
details: { visibilityState: document.visibilityState }
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
document.addEventListener('visibilitychange', visibilityHandler);
|
|
286
|
+
this.eventListeners.push({ target: document, event: 'visibilitychange', handler: visibilityHandler });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private detectScreenCaptureAPI(): void {
|
|
290
|
+
// Monkey-patch getDisplayMedia if it exists
|
|
291
|
+
if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
|
|
292
|
+
this.originalGetDisplayMedia = navigator.mediaDevices.getDisplayMedia.bind(
|
|
293
|
+
navigator.mediaDevices
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
const self = this;
|
|
297
|
+
navigator.mediaDevices.getDisplayMedia = async function (...args: any[]) {
|
|
298
|
+
// Detected screen capture attempt
|
|
299
|
+
self.handleDetection({
|
|
300
|
+
type: 'screen-capture-api',
|
|
301
|
+
timestamp: Date.now(),
|
|
302
|
+
details: { api: 'getDisplayMedia', args: args.length }
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// Still allow the call to proceed (can't block it)
|
|
306
|
+
return self.originalGetDisplayMedia(...args);
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private handleDetection(event: ScreenCaptureEvent): void {
|
|
312
|
+
console.warn('[ScreenProtection] Detection event:', event);
|
|
313
|
+
|
|
314
|
+
// Trigger callback
|
|
315
|
+
if (this.opts.onDetection) {
|
|
316
|
+
this.opts.onDetection(event);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Send to backend tracking endpoint if configured
|
|
320
|
+
if (this.opts.config.trackingEndpoint) {
|
|
321
|
+
this.sendTrackingEvent(event);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Execute configured action
|
|
325
|
+
const action = this.opts.config.onDetection || 'warn';
|
|
326
|
+
|
|
327
|
+
switch (action) {
|
|
328
|
+
case 'warn':
|
|
329
|
+
this.executeWarnAction();
|
|
330
|
+
break;
|
|
331
|
+
case 'pause':
|
|
332
|
+
this.executePauseAction();
|
|
333
|
+
break;
|
|
334
|
+
case 'degrade':
|
|
335
|
+
this.executeDegradeAction();
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private async sendTrackingEvent(event: ScreenCaptureEvent): Promise<void> {
|
|
341
|
+
try {
|
|
342
|
+
await fetch(this.opts.config.trackingEndpoint!, {
|
|
343
|
+
method: 'POST',
|
|
344
|
+
headers: {
|
|
345
|
+
'Content-Type': 'application/json'
|
|
346
|
+
},
|
|
347
|
+
body: JSON.stringify({
|
|
348
|
+
event,
|
|
349
|
+
userAgent: navigator.userAgent,
|
|
350
|
+
timestamp: new Date().toISOString(),
|
|
351
|
+
forensicData: this.opts.config.forensicWatermark
|
|
352
|
+
})
|
|
353
|
+
});
|
|
354
|
+
} catch (error) {
|
|
355
|
+
console.error('[ScreenProtection] Failed to send tracking event:', error);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
private executeWarnAction(): void {
|
|
360
|
+
const message = this.opts.config.warningMessage ||
|
|
361
|
+
'Screen recording or screenshot detected. This content is protected.';
|
|
362
|
+
|
|
363
|
+
console.warn(`[ScreenProtection] ${message}`);
|
|
364
|
+
|
|
365
|
+
// Could also show visual warning in player (future enhancement)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
private executePauseAction(): void {
|
|
369
|
+
console.warn('[ScreenProtection] Pausing playback due to suspicious activity');
|
|
370
|
+
|
|
371
|
+
if (this.opts.onPause) {
|
|
372
|
+
this.opts.onPause();
|
|
373
|
+
} else {
|
|
374
|
+
this.opts.videoElement.pause();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
private executeDegradeAction(): void {
|
|
379
|
+
console.warn('[ScreenProtection] Degrading video quality due to suspicious activity');
|
|
380
|
+
|
|
381
|
+
// Apply visual degradation
|
|
382
|
+
this.opts.videoElement.style.filter = 'blur(10px) brightness(0.5)';
|
|
383
|
+
|
|
384
|
+
// Restore after 5 seconds
|
|
385
|
+
setTimeout(() => {
|
|
386
|
+
if (this.opts.videoElement.style.filter) {
|
|
387
|
+
this.opts.videoElement.style.filter = '';
|
|
388
|
+
}
|
|
389
|
+
}, 5000);
|
|
390
|
+
}
|
|
391
|
+
}
|
package/scripts/fix-imports.js
CHANGED
|
@@ -10,21 +10,22 @@ const path = require('path');
|
|
|
10
10
|
|
|
11
11
|
function fixImports(filePath) {
|
|
12
12
|
let content = fs.readFileSync(filePath, 'utf8');
|
|
13
|
-
|
|
14
|
-
//
|
|
13
|
+
|
|
14
|
+
// Replace @unified-video/core imports with relative paths
|
|
15
15
|
if (filePath.includes(path.join('packages', 'web', 'dist'))) {
|
|
16
|
-
//
|
|
16
|
+
// Fix CommonJS require statements
|
|
17
17
|
content = content.replace(
|
|
18
|
-
/
|
|
19
|
-
'
|
|
18
|
+
/require\(["']@unified-video\/core["']\)/g,
|
|
19
|
+
'require("../../core/dist")'
|
|
20
20
|
);
|
|
21
|
+
// Fix ES module import statements
|
|
21
22
|
content = content.replace(
|
|
22
|
-
/
|
|
23
|
-
'
|
|
23
|
+
/from\s+["']@unified-video\/core["']/g,
|
|
24
|
+
'from "../../core/dist/index.js"'
|
|
24
25
|
);
|
|
25
26
|
content = content.replace(
|
|
26
|
-
/
|
|
27
|
-
'
|
|
27
|
+
/import\s+["']@unified-video\/core["']/g,
|
|
28
|
+
'import "../../core/dist/index.js"'
|
|
28
29
|
);
|
|
29
30
|
|
|
30
31
|
// Fix relative imports within the same package to include .js extension
|
|
@@ -42,18 +43,19 @@ function fixImports(filePath) {
|
|
|
42
43
|
}
|
|
43
44
|
);
|
|
44
45
|
} else if (filePath.includes(path.join('packages', 'react-native', 'dist'))) {
|
|
45
|
-
//
|
|
46
|
+
// Fix CommonJS require statements
|
|
46
47
|
content = content.replace(
|
|
47
|
-
/
|
|
48
|
-
'
|
|
48
|
+
/require\(["']@unified-video\/core["']\)/g,
|
|
49
|
+
'require("../../core/dist")'
|
|
49
50
|
);
|
|
51
|
+
// Fix ES module import statements
|
|
50
52
|
content = content.replace(
|
|
51
|
-
/
|
|
52
|
-
'
|
|
53
|
+
/from\s+["']@unified-video\/core["']/g,
|
|
54
|
+
'from "../../core/dist/index.js"'
|
|
53
55
|
);
|
|
54
56
|
content = content.replace(
|
|
55
|
-
/
|
|
56
|
-
'
|
|
57
|
+
/import\s+["']@unified-video\/core["']/g,
|
|
58
|
+
'import "../../core/dist/index.js"'
|
|
57
59
|
);
|
|
58
60
|
|
|
59
61
|
// Fix relative imports within the same package to include .js extension
|