@contentstorage/i18next-plugin 2.0.18 → 2.0.20
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.esm.js +70 -27
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +70 -27
- package/dist/index.js.map +1 -1
- package/dist/post-processor.d.ts +6 -0
- package/dist/post-processor.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -72,14 +72,14 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customSc
|
|
|
72
72
|
const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';
|
|
73
73
|
const loadScript = (attempt = 1) => {
|
|
74
74
|
if (debug) {
|
|
75
|
-
console.log(`[
|
|
75
|
+
console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);
|
|
76
76
|
}
|
|
77
77
|
const scriptElement = win.document.createElement('script');
|
|
78
78
|
scriptElement.type = 'text/javascript';
|
|
79
79
|
scriptElement.src = cdnScriptUrl;
|
|
80
80
|
scriptElement.onload = () => {
|
|
81
81
|
if (debug) {
|
|
82
|
-
console.log(`[
|
|
82
|
+
console.log(`[Contentstorage] Live editor script loaded successfully`);
|
|
83
83
|
}
|
|
84
84
|
resolve(true);
|
|
85
85
|
};
|
|
@@ -87,13 +87,13 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customSc
|
|
|
87
87
|
// Clean up the failed script element
|
|
88
88
|
scriptElement.remove();
|
|
89
89
|
if (debug) {
|
|
90
|
-
console.error(`[
|
|
90
|
+
console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);
|
|
91
91
|
}
|
|
92
92
|
if (attempt < retries) {
|
|
93
93
|
setTimeout(() => loadScript(attempt + 1), delay);
|
|
94
94
|
}
|
|
95
95
|
else {
|
|
96
|
-
console.error(`[
|
|
96
|
+
console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);
|
|
97
97
|
resolve(false);
|
|
98
98
|
}
|
|
99
99
|
};
|
|
@@ -110,6 +110,16 @@ function getMemoryMap() {
|
|
|
110
110
|
const win = getContentstorageWindow();
|
|
111
111
|
return (win === null || win === void 0 ? void 0 : win.memoryMap) || null;
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Clears all entries from the memory map
|
|
115
|
+
* Used by live editor to refresh tracking
|
|
116
|
+
*/
|
|
117
|
+
function clearMemoryMap() {
|
|
118
|
+
const memoryMap = getMemoryMap();
|
|
119
|
+
if (memoryMap) {
|
|
120
|
+
memoryMap.clear();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
113
123
|
/**
|
|
114
124
|
* Sets the current language code on the window object
|
|
115
125
|
* This is used by the live editor to know which language is currently active
|
|
@@ -249,7 +259,7 @@ function trackTranslation(translationValue, translationKey, namespace, language,
|
|
|
249
259
|
};
|
|
250
260
|
memoryMap.set(translationValue, entry);
|
|
251
261
|
if (debug) {
|
|
252
|
-
console.log('[
|
|
262
|
+
console.log('[Contentstorage] Tracked translation:', {
|
|
253
263
|
value: translationValue,
|
|
254
264
|
key: normalizedKey,
|
|
255
265
|
namespace,
|
|
@@ -316,10 +326,10 @@ function flattenTranslations(obj, prefix = '') {
|
|
|
316
326
|
function debugMemoryMap() {
|
|
317
327
|
const memoryMap = getMemoryMap();
|
|
318
328
|
if (!memoryMap) {
|
|
319
|
-
console.log('[
|
|
329
|
+
console.log('[Contentstorage] Memory map not initialized');
|
|
320
330
|
return;
|
|
321
331
|
}
|
|
322
|
-
console.log('[
|
|
332
|
+
console.log('[Contentstorage] Memory map contents:');
|
|
323
333
|
console.log(`Total entries: ${memoryMap.size}`);
|
|
324
334
|
const entries = Array.from(memoryMap.entries()).slice(0, 10);
|
|
325
335
|
console.table(entries.map(([value, entry]) => {
|
|
@@ -413,7 +423,7 @@ function cleanScreenshotUrlParams() {
|
|
|
413
423
|
win.history.replaceState({}, '', url.toString());
|
|
414
424
|
}
|
|
415
425
|
catch (e) {
|
|
416
|
-
console.warn('[
|
|
426
|
+
console.warn('[Contentstorage] Failed to clean URL params:', e);
|
|
417
427
|
}
|
|
418
428
|
}
|
|
419
429
|
/**
|
|
@@ -470,6 +480,7 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
470
480
|
this.type = 'postProcessor';
|
|
471
481
|
this.name = 'contentstorage';
|
|
472
482
|
this.isLiveMode = false;
|
|
483
|
+
this.i18nextInstance = null;
|
|
473
484
|
this.options = {
|
|
474
485
|
debug: false,
|
|
475
486
|
liveEditorParam: 'contentstorage_live_editor',
|
|
@@ -489,8 +500,8 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
489
500
|
// Load the live editor script
|
|
490
501
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
491
502
|
if (this.options.debug) {
|
|
492
|
-
console.log('[
|
|
493
|
-
console.log(`[
|
|
503
|
+
console.log('[Contentstorage] Post-processor initialized in live mode');
|
|
504
|
+
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
494
505
|
}
|
|
495
506
|
}
|
|
496
507
|
// Check for screenshot mode (works without iframe)
|
|
@@ -508,7 +519,7 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
508
519
|
if (!screenshotConfig)
|
|
509
520
|
return;
|
|
510
521
|
if (this.options.debug) {
|
|
511
|
-
console.log('[
|
|
522
|
+
console.log('[Contentstorage] Screenshot mode detected');
|
|
512
523
|
}
|
|
513
524
|
// Initialize memory map for translation tracking
|
|
514
525
|
initializeMemoryMap();
|
|
@@ -526,8 +537,35 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
526
537
|
// Load live-editor.js script
|
|
527
538
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
528
539
|
if (this.options.debug) {
|
|
529
|
-
console.log('[
|
|
530
|
-
console.log(`[
|
|
540
|
+
console.log('[Contentstorage] Screenshot mode initialized');
|
|
541
|
+
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Expose refresh function on window for live-editor.js to call
|
|
546
|
+
* Only exposed in live mode (live editor or screenshot mode)
|
|
547
|
+
*/
|
|
548
|
+
exposeRefreshFunction() {
|
|
549
|
+
if (!this.isLiveMode)
|
|
550
|
+
return;
|
|
551
|
+
const win = getContentstorageWindow();
|
|
552
|
+
if (!win)
|
|
553
|
+
return;
|
|
554
|
+
win.__contentstorageRefresh = () => {
|
|
555
|
+
var _a;
|
|
556
|
+
// Clear memoryMap
|
|
557
|
+
clearMemoryMap();
|
|
558
|
+
// Trigger re-render by emitting languageChanged event
|
|
559
|
+
// This causes useTranslation hooks to re-render
|
|
560
|
+
if ((_a = this.i18nextInstance) === null || _a === void 0 ? void 0 : _a.emit) {
|
|
561
|
+
this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);
|
|
562
|
+
}
|
|
563
|
+
if (this.options.debug) {
|
|
564
|
+
console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
if (this.options.debug) {
|
|
568
|
+
console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');
|
|
531
569
|
}
|
|
532
570
|
}
|
|
533
571
|
/**
|
|
@@ -540,6 +578,11 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
540
578
|
if (!this.isLiveMode) {
|
|
541
579
|
return value;
|
|
542
580
|
}
|
|
581
|
+
// Store i18next reference on first call and expose refresh function
|
|
582
|
+
if (!this.i18nextInstance && translator) {
|
|
583
|
+
this.i18nextInstance = translator;
|
|
584
|
+
this.exposeRefreshFunction();
|
|
585
|
+
}
|
|
543
586
|
// Handle array of keys (fallback keys)
|
|
544
587
|
const translationKey = Array.isArray(key) ? key[0] : key;
|
|
545
588
|
// Only extract namespace if key explicitly uses colon notation
|
|
@@ -656,23 +699,23 @@ class ContentstorageBackend {
|
|
|
656
699
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {
|
|
657
700
|
if (loaded) {
|
|
658
701
|
if (this.options.debug) {
|
|
659
|
-
console.log('[
|
|
702
|
+
console.log('[Contentstorage] Live editor ready');
|
|
660
703
|
}
|
|
661
704
|
}
|
|
662
705
|
else {
|
|
663
|
-
console.warn('[
|
|
706
|
+
console.warn('[Contentstorage] Failed to load live editor script');
|
|
664
707
|
}
|
|
665
708
|
});
|
|
666
709
|
// Auto-register the post-processor for live editor tracking
|
|
667
710
|
this.registerPostProcessor(services, i18nextOptions);
|
|
668
711
|
if (this.options.debug) {
|
|
669
|
-
console.log('[
|
|
670
|
-
console.log('[
|
|
671
|
-
console.log('[
|
|
712
|
+
console.log('[Contentstorage] Live editor mode enabled');
|
|
713
|
+
console.log('[Contentstorage] Post-processor auto-registered');
|
|
714
|
+
console.log('[Contentstorage] Plugin initialized with options:', this.options);
|
|
672
715
|
}
|
|
673
716
|
}
|
|
674
717
|
else if (this.options.debug) {
|
|
675
|
-
console.log('[
|
|
718
|
+
console.log('[Contentstorage] Running in normal mode (not live editor)');
|
|
676
719
|
}
|
|
677
720
|
// Check for screenshot mode (works in local dev without iframe)
|
|
678
721
|
this.initializeScreenshotMode();
|
|
@@ -686,7 +729,7 @@ class ContentstorageBackend {
|
|
|
686
729
|
if (!screenshotConfig)
|
|
687
730
|
return;
|
|
688
731
|
if (this.options.debug) {
|
|
689
|
-
console.log('[
|
|
732
|
+
console.log('[Contentstorage] Screenshot mode detected');
|
|
690
733
|
}
|
|
691
734
|
// Initialize memory map for translation tracking
|
|
692
735
|
initializeMemoryMap();
|
|
@@ -701,7 +744,7 @@ class ContentstorageBackend {
|
|
|
701
744
|
// Load live-editor.js script (handles screenshot UI)
|
|
702
745
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
703
746
|
if (this.options.debug) {
|
|
704
|
-
console.log('[
|
|
747
|
+
console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');
|
|
705
748
|
}
|
|
706
749
|
}
|
|
707
750
|
/**
|
|
@@ -734,7 +777,7 @@ class ContentstorageBackend {
|
|
|
734
777
|
*/
|
|
735
778
|
read(language, namespace, callback) {
|
|
736
779
|
if (this.options.debug) {
|
|
737
|
-
console.log(`[
|
|
780
|
+
console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);
|
|
738
781
|
}
|
|
739
782
|
this.loadTranslations(language, namespace)
|
|
740
783
|
.then((translations) => {
|
|
@@ -750,7 +793,7 @@ class ContentstorageBackend {
|
|
|
750
793
|
})
|
|
751
794
|
.catch((error) => {
|
|
752
795
|
if (this.options.debug) {
|
|
753
|
-
console.error('[
|
|
796
|
+
console.error('[Contentstorage] Failed to load translations:', error);
|
|
754
797
|
}
|
|
755
798
|
callback(error, false);
|
|
756
799
|
});
|
|
@@ -761,7 +804,7 @@ class ContentstorageBackend {
|
|
|
761
804
|
async loadTranslations(language, namespace) {
|
|
762
805
|
const url = this.getLoadPath(language, namespace);
|
|
763
806
|
if (this.options.debug) {
|
|
764
|
-
console.log(`[
|
|
807
|
+
console.log(`[Contentstorage] Fetching from: ${url}`);
|
|
765
808
|
}
|
|
766
809
|
try {
|
|
767
810
|
const fetchFn = this.options.request || this.defaultFetch.bind(this);
|
|
@@ -774,7 +817,7 @@ class ContentstorageBackend {
|
|
|
774
817
|
}
|
|
775
818
|
catch (error) {
|
|
776
819
|
if (this.options.debug) {
|
|
777
|
-
console.error('[
|
|
820
|
+
console.error('[Contentstorage] Fetch error:', error);
|
|
778
821
|
}
|
|
779
822
|
throw error;
|
|
780
823
|
}
|
|
@@ -806,7 +849,7 @@ class ContentstorageBackend {
|
|
|
806
849
|
}
|
|
807
850
|
// Default CDN path
|
|
808
851
|
if (!contentKey) {
|
|
809
|
-
throw new Error('[
|
|
852
|
+
throw new Error('[Contentstorage] contentKey is required when using default CDN path');
|
|
810
853
|
}
|
|
811
854
|
// Default: Always use uppercase language code
|
|
812
855
|
const lng = language.toUpperCase();
|
|
@@ -841,7 +884,7 @@ class ContentstorageBackend {
|
|
|
841
884
|
language, this.options.debug);
|
|
842
885
|
}
|
|
843
886
|
if (this.options.debug) {
|
|
844
|
-
console.log(`[
|
|
887
|
+
console.log(`[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`);
|
|
845
888
|
}
|
|
846
889
|
}
|
|
847
890
|
}
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/screenshot.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import { isBrowser, getContentstorageWindow } from './utils';\n\n/**\n * Decodes and validates the contentstorage key\n * Just decodes URL encoding and checks non-empty (backend validates format)\n *\n * @param key - The raw key from URL params\n * @returns Decoded key if valid, null if empty/invalid\n */\nexport function decodeContentstorageKey(key: string | null): string | null {\n if (!key) return null;\n\n try {\n const decoded = decodeURIComponent(key);\n return decoded.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detects if screenshot mode should be activated\n * Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key\n *\n * NOTE: Unlike live editor mode, screenshot mode does NOT require iframe\n *\n * @returns Object with contentstorageKey if active, null otherwise\n */\nexport function detectScreenshotMode(): { contentstorageKey: string } | null {\n if (!isBrowser()) return null;\n\n const win = getContentstorageWindow();\n if (!win) return null;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n // Check required params\n const liveEditorParam = urlParams.get('contentstorage_live_editor');\n const screenshotModeParam = urlParams.get('screenshot_mode');\n const contentstorageKey = urlParams.get('contentstorage_key');\n\n // All three must be present and valid\n if (liveEditorParam !== 'true') return null;\n if (screenshotModeParam !== 'true') return null;\n\n const decodedKey = decodeContentstorageKey(contentstorageKey);\n if (!decodedKey) return null;\n\n return {\n contentstorageKey: decodedKey,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Removes screenshot-related params from URL without page reload\n * Uses History API to update URL bar\n */\nexport function cleanScreenshotUrlParams(): void {\n if (!isBrowser()) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n try {\n const url = new URL(win.location.href);\n const paramsToRemove = [\n 'contentstorage_live_editor',\n 'screenshot_mode',\n 'contentstorage_key',\n ];\n\n paramsToRemove.forEach((param) => {\n url.searchParams.delete(param);\n });\n\n // Use replaceState to update URL without reload\n win.history.replaceState({}, '', url.toString());\n } catch (e) {\n console.warn('[ContentStorage] Failed to clean URL params:', e);\n }\n}\n\n/**\n * Exposes the API key on window for live-editor.js to use\n * Uses a non-enumerable property for security\n *\n * @param key - The validated contentstorage API key\n */\nexport function exposeApiKey(key: string): void {\n const win = getContentstorageWindow();\n if (!win) return;\n\n // Store as non-enumerable property for security\n Object.defineProperty(win, '__contentstorageApiKey', {\n value: key,\n writable: false,\n enumerable: false,\n configurable: true, // Allow cleanup later\n });\n}\n\n/**\n * Gets the exposed API key (if any)\n */\nexport function getApiKey(): string | null {\n const win = getContentstorageWindow();\n return win?.__contentstorageApiKey || null;\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\nimport { detectScreenshotMode, cleanScreenshotUrlParams, exposeApiKey } from './screenshot';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n // Check for screenshot mode (works without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Works without iframe, unlike live editor mode\n */\n private initializeScreenshotMode(): void {\n // Skip if already in live mode (already initialized)\n if (this.isLiveMode) return;\n\n const screenshotConfig = detectScreenshotMode();\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Initialize current language code\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Enable tracking (reuse existing flag so process() tracks translations)\n this.isLiveMode = true;\n\n // Load live-editor.js script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode initialized');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport {\n detectScreenshotMode,\n cleanScreenshotUrlParams,\n exposeApiKey,\n} from './screenshot';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n private services?: Services;\n private i18nextOptions?: InitOptions;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n // Store for use in initializeScreenshotMode\n this.services = services;\n this.i18nextOptions = i18nextOptions;\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n\n // Check for screenshot mode (works in local dev without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Exposes the API key for live-editor.js to use\n */\n private initializeScreenshotMode(): void {\n const screenshotConfig = detectScreenshotMode();\n\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Register post-processor for translation tracking\n if (this.services && this.i18nextOptions) {\n this.registerPostProcessor(this.services, this.i18nextOptions);\n }\n\n // Load live-editor.js script (handles screenshot UI)\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode initialized: memory map, post-processor, API key exposed');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/screenshot.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[Contentstorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Clears all entries from the memory map\n * Used by live editor to refresh tracking\n */\nexport function clearMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (memoryMap) {\n memoryMap.clear();\n }\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[Contentstorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[Contentstorage] Memory map not initialized');\n return;\n }\n\n console.log('[Contentstorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import { isBrowser, getContentstorageWindow } from './utils';\n\n/**\n * Decodes and validates the contentstorage key\n * Just decodes URL encoding and checks non-empty (backend validates format)\n *\n * @param key - The raw key from URL params\n * @returns Decoded key if valid, null if empty/invalid\n */\nexport function decodeContentstorageKey(key: string | null): string | null {\n if (!key) return null;\n\n try {\n const decoded = decodeURIComponent(key);\n return decoded.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detects if screenshot mode should be activated\n * Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key\n *\n * NOTE: Unlike live editor mode, screenshot mode does NOT require iframe\n *\n * @returns Object with contentstorageKey if active, null otherwise\n */\nexport function detectScreenshotMode(): { contentstorageKey: string } | null {\n if (!isBrowser()) return null;\n\n const win = getContentstorageWindow();\n if (!win) return null;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n // Check required params\n const liveEditorParam = urlParams.get('contentstorage_live_editor');\n const screenshotModeParam = urlParams.get('screenshot_mode');\n const contentstorageKey = urlParams.get('contentstorage_key');\n\n // All three must be present and valid\n if (liveEditorParam !== 'true') return null;\n if (screenshotModeParam !== 'true') return null;\n\n const decodedKey = decodeContentstorageKey(contentstorageKey);\n if (!decodedKey) return null;\n\n return {\n contentstorageKey: decodedKey,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Removes screenshot-related params from URL without page reload\n * Uses History API to update URL bar\n */\nexport function cleanScreenshotUrlParams(): void {\n if (!isBrowser()) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n try {\n const url = new URL(win.location.href);\n const paramsToRemove = [\n 'contentstorage_live_editor',\n 'screenshot_mode',\n 'contentstorage_key',\n ];\n\n paramsToRemove.forEach((param) => {\n url.searchParams.delete(param);\n });\n\n // Use replaceState to update URL without reload\n win.history.replaceState({}, '', url.toString());\n } catch (e) {\n console.warn('[Contentstorage] Failed to clean URL params:', e);\n }\n}\n\n/**\n * Exposes the API key on window for live-editor.js to use\n * Uses a non-enumerable property for security\n *\n * @param key - The validated contentstorage API key\n */\nexport function exposeApiKey(key: string): void {\n const win = getContentstorageWindow();\n if (!win) return;\n\n // Store as non-enumerable property for security\n Object.defineProperty(win, '__contentstorageApiKey', {\n value: key,\n writable: false,\n enumerable: false,\n configurable: true, // Allow cleanup later\n });\n}\n\n/**\n * Gets the exposed API key (if any)\n */\nexport function getApiKey(): string | null {\n const win = getContentstorageWindow();\n return win?.__contentstorageApiKey || null;\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode, clearMemoryMap, getContentstorageWindow } from './utils';\nimport { detectScreenshotMode, cleanScreenshotUrlParams, exposeApiKey } from './screenshot';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private i18nextInstance: any = null;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Post-processor initialized in live mode');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n // Check for screenshot mode (works without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Works without iframe, unlike live editor mode\n */\n private initializeScreenshotMode(): void {\n // Skip if already in live mode (already initialized)\n if (this.isLiveMode) return;\n\n const screenshotConfig = detectScreenshotMode();\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Initialize current language code\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Enable tracking (reuse existing flag so process() tracks translations)\n this.isLiveMode = true;\n\n // Load live-editor.js script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n /**\n * Expose refresh function on window for live-editor.js to call\n * Only exposed in live mode (live editor or screenshot mode)\n */\n private exposeRefreshFunction(): void {\n if (!this.isLiveMode) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n win.__contentstorageRefresh = () => {\n // Clear memoryMap\n clearMemoryMap();\n\n // Trigger re-render by emitting languageChanged event\n // This causes useTranslation hooks to re-render\n if (this.i18nextInstance?.emit) {\n this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);\n }\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');\n }\n };\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Store i18next reference on first call and expose refresh function\n if (!this.i18nextInstance && translator) {\n this.i18nextInstance = translator;\n this.exposeRefreshFunction();\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport {\n detectScreenshotMode,\n cleanScreenshotUrlParams,\n exposeApiKey,\n} from './screenshot';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n private services?: Services;\n private i18nextOptions?: InitOptions;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n // Store for use in initializeScreenshotMode\n this.services = services;\n this.i18nextOptions = i18nextOptions;\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor ready');\n }\n } else {\n console.warn('[Contentstorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor mode enabled');\n console.log('[Contentstorage] Post-processor auto-registered');\n console.log('[Contentstorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[Contentstorage] Running in normal mode (not live editor)');\n }\n\n // Check for screenshot mode (works in local dev without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Exposes the API key for live-editor.js to use\n */\n private initializeScreenshotMode(): void {\n const screenshotConfig = detectScreenshotMode();\n\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Register post-processor for translation tracking\n if (this.services && this.i18nextOptions) {\n this.registerPostProcessor(this.services, this.i18nextOptions);\n }\n\n // Load live-editor.js script (handles screenshot UI)\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[Contentstorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[Contentstorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[Contentstorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[Contentstorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -76,14 +76,14 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customSc
|
|
|
76
76
|
const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';
|
|
77
77
|
const loadScript = (attempt = 1) => {
|
|
78
78
|
if (debug) {
|
|
79
|
-
console.log(`[
|
|
79
|
+
console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);
|
|
80
80
|
}
|
|
81
81
|
const scriptElement = win.document.createElement('script');
|
|
82
82
|
scriptElement.type = 'text/javascript';
|
|
83
83
|
scriptElement.src = cdnScriptUrl;
|
|
84
84
|
scriptElement.onload = () => {
|
|
85
85
|
if (debug) {
|
|
86
|
-
console.log(`[
|
|
86
|
+
console.log(`[Contentstorage] Live editor script loaded successfully`);
|
|
87
87
|
}
|
|
88
88
|
resolve(true);
|
|
89
89
|
};
|
|
@@ -91,13 +91,13 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false, customSc
|
|
|
91
91
|
// Clean up the failed script element
|
|
92
92
|
scriptElement.remove();
|
|
93
93
|
if (debug) {
|
|
94
|
-
console.error(`[
|
|
94
|
+
console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);
|
|
95
95
|
}
|
|
96
96
|
if (attempt < retries) {
|
|
97
97
|
setTimeout(() => loadScript(attempt + 1), delay);
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
|
-
console.error(`[
|
|
100
|
+
console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);
|
|
101
101
|
resolve(false);
|
|
102
102
|
}
|
|
103
103
|
};
|
|
@@ -114,6 +114,16 @@ function getMemoryMap() {
|
|
|
114
114
|
const win = getContentstorageWindow();
|
|
115
115
|
return (win === null || win === void 0 ? void 0 : win.memoryMap) || null;
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Clears all entries from the memory map
|
|
119
|
+
* Used by live editor to refresh tracking
|
|
120
|
+
*/
|
|
121
|
+
function clearMemoryMap() {
|
|
122
|
+
const memoryMap = getMemoryMap();
|
|
123
|
+
if (memoryMap) {
|
|
124
|
+
memoryMap.clear();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
117
127
|
/**
|
|
118
128
|
* Sets the current language code on the window object
|
|
119
129
|
* This is used by the live editor to know which language is currently active
|
|
@@ -253,7 +263,7 @@ function trackTranslation(translationValue, translationKey, namespace, language,
|
|
|
253
263
|
};
|
|
254
264
|
memoryMap.set(translationValue, entry);
|
|
255
265
|
if (debug) {
|
|
256
|
-
console.log('[
|
|
266
|
+
console.log('[Contentstorage] Tracked translation:', {
|
|
257
267
|
value: translationValue,
|
|
258
268
|
key: normalizedKey,
|
|
259
269
|
namespace,
|
|
@@ -320,10 +330,10 @@ function flattenTranslations(obj, prefix = '') {
|
|
|
320
330
|
function debugMemoryMap() {
|
|
321
331
|
const memoryMap = getMemoryMap();
|
|
322
332
|
if (!memoryMap) {
|
|
323
|
-
console.log('[
|
|
333
|
+
console.log('[Contentstorage] Memory map not initialized');
|
|
324
334
|
return;
|
|
325
335
|
}
|
|
326
|
-
console.log('[
|
|
336
|
+
console.log('[Contentstorage] Memory map contents:');
|
|
327
337
|
console.log(`Total entries: ${memoryMap.size}`);
|
|
328
338
|
const entries = Array.from(memoryMap.entries()).slice(0, 10);
|
|
329
339
|
console.table(entries.map(([value, entry]) => {
|
|
@@ -417,7 +427,7 @@ function cleanScreenshotUrlParams() {
|
|
|
417
427
|
win.history.replaceState({}, '', url.toString());
|
|
418
428
|
}
|
|
419
429
|
catch (e) {
|
|
420
|
-
console.warn('[
|
|
430
|
+
console.warn('[Contentstorage] Failed to clean URL params:', e);
|
|
421
431
|
}
|
|
422
432
|
}
|
|
423
433
|
/**
|
|
@@ -474,6 +484,7 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
474
484
|
this.type = 'postProcessor';
|
|
475
485
|
this.name = 'contentstorage';
|
|
476
486
|
this.isLiveMode = false;
|
|
487
|
+
this.i18nextInstance = null;
|
|
477
488
|
this.options = {
|
|
478
489
|
debug: false,
|
|
479
490
|
liveEditorParam: 'contentstorage_live_editor',
|
|
@@ -493,8 +504,8 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
493
504
|
// Load the live editor script
|
|
494
505
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
495
506
|
if (this.options.debug) {
|
|
496
|
-
console.log('[
|
|
497
|
-
console.log(`[
|
|
507
|
+
console.log('[Contentstorage] Post-processor initialized in live mode');
|
|
508
|
+
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
498
509
|
}
|
|
499
510
|
}
|
|
500
511
|
// Check for screenshot mode (works without iframe)
|
|
@@ -512,7 +523,7 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
512
523
|
if (!screenshotConfig)
|
|
513
524
|
return;
|
|
514
525
|
if (this.options.debug) {
|
|
515
|
-
console.log('[
|
|
526
|
+
console.log('[Contentstorage] Screenshot mode detected');
|
|
516
527
|
}
|
|
517
528
|
// Initialize memory map for translation tracking
|
|
518
529
|
initializeMemoryMap();
|
|
@@ -530,8 +541,35 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
530
541
|
// Load live-editor.js script
|
|
531
542
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
532
543
|
if (this.options.debug) {
|
|
533
|
-
console.log('[
|
|
534
|
-
console.log(`[
|
|
544
|
+
console.log('[Contentstorage] Screenshot mode initialized');
|
|
545
|
+
console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Expose refresh function on window for live-editor.js to call
|
|
550
|
+
* Only exposed in live mode (live editor or screenshot mode)
|
|
551
|
+
*/
|
|
552
|
+
exposeRefreshFunction() {
|
|
553
|
+
if (!this.isLiveMode)
|
|
554
|
+
return;
|
|
555
|
+
const win = getContentstorageWindow();
|
|
556
|
+
if (!win)
|
|
557
|
+
return;
|
|
558
|
+
win.__contentstorageRefresh = () => {
|
|
559
|
+
var _a;
|
|
560
|
+
// Clear memoryMap
|
|
561
|
+
clearMemoryMap();
|
|
562
|
+
// Trigger re-render by emitting languageChanged event
|
|
563
|
+
// This causes useTranslation hooks to re-render
|
|
564
|
+
if ((_a = this.i18nextInstance) === null || _a === void 0 ? void 0 : _a.emit) {
|
|
565
|
+
this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);
|
|
566
|
+
}
|
|
567
|
+
if (this.options.debug) {
|
|
568
|
+
console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
if (this.options.debug) {
|
|
572
|
+
console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');
|
|
535
573
|
}
|
|
536
574
|
}
|
|
537
575
|
/**
|
|
@@ -544,6 +582,11 @@ class ContentstorageLiveEditorPostProcessor {
|
|
|
544
582
|
if (!this.isLiveMode) {
|
|
545
583
|
return value;
|
|
546
584
|
}
|
|
585
|
+
// Store i18next reference on first call and expose refresh function
|
|
586
|
+
if (!this.i18nextInstance && translator) {
|
|
587
|
+
this.i18nextInstance = translator;
|
|
588
|
+
this.exposeRefreshFunction();
|
|
589
|
+
}
|
|
547
590
|
// Handle array of keys (fallback keys)
|
|
548
591
|
const translationKey = Array.isArray(key) ? key[0] : key;
|
|
549
592
|
// Only extract namespace if key explicitly uses colon notation
|
|
@@ -660,23 +703,23 @@ class ContentstorageBackend {
|
|
|
660
703
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {
|
|
661
704
|
if (loaded) {
|
|
662
705
|
if (this.options.debug) {
|
|
663
|
-
console.log('[
|
|
706
|
+
console.log('[Contentstorage] Live editor ready');
|
|
664
707
|
}
|
|
665
708
|
}
|
|
666
709
|
else {
|
|
667
|
-
console.warn('[
|
|
710
|
+
console.warn('[Contentstorage] Failed to load live editor script');
|
|
668
711
|
}
|
|
669
712
|
});
|
|
670
713
|
// Auto-register the post-processor for live editor tracking
|
|
671
714
|
this.registerPostProcessor(services, i18nextOptions);
|
|
672
715
|
if (this.options.debug) {
|
|
673
|
-
console.log('[
|
|
674
|
-
console.log('[
|
|
675
|
-
console.log('[
|
|
716
|
+
console.log('[Contentstorage] Live editor mode enabled');
|
|
717
|
+
console.log('[Contentstorage] Post-processor auto-registered');
|
|
718
|
+
console.log('[Contentstorage] Plugin initialized with options:', this.options);
|
|
676
719
|
}
|
|
677
720
|
}
|
|
678
721
|
else if (this.options.debug) {
|
|
679
|
-
console.log('[
|
|
722
|
+
console.log('[Contentstorage] Running in normal mode (not live editor)');
|
|
680
723
|
}
|
|
681
724
|
// Check for screenshot mode (works in local dev without iframe)
|
|
682
725
|
this.initializeScreenshotMode();
|
|
@@ -690,7 +733,7 @@ class ContentstorageBackend {
|
|
|
690
733
|
if (!screenshotConfig)
|
|
691
734
|
return;
|
|
692
735
|
if (this.options.debug) {
|
|
693
|
-
console.log('[
|
|
736
|
+
console.log('[Contentstorage] Screenshot mode detected');
|
|
694
737
|
}
|
|
695
738
|
// Initialize memory map for translation tracking
|
|
696
739
|
initializeMemoryMap();
|
|
@@ -705,7 +748,7 @@ class ContentstorageBackend {
|
|
|
705
748
|
// Load live-editor.js script (handles screenshot UI)
|
|
706
749
|
loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);
|
|
707
750
|
if (this.options.debug) {
|
|
708
|
-
console.log('[
|
|
751
|
+
console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');
|
|
709
752
|
}
|
|
710
753
|
}
|
|
711
754
|
/**
|
|
@@ -738,7 +781,7 @@ class ContentstorageBackend {
|
|
|
738
781
|
*/
|
|
739
782
|
read(language, namespace, callback) {
|
|
740
783
|
if (this.options.debug) {
|
|
741
|
-
console.log(`[
|
|
784
|
+
console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);
|
|
742
785
|
}
|
|
743
786
|
this.loadTranslations(language, namespace)
|
|
744
787
|
.then((translations) => {
|
|
@@ -754,7 +797,7 @@ class ContentstorageBackend {
|
|
|
754
797
|
})
|
|
755
798
|
.catch((error) => {
|
|
756
799
|
if (this.options.debug) {
|
|
757
|
-
console.error('[
|
|
800
|
+
console.error('[Contentstorage] Failed to load translations:', error);
|
|
758
801
|
}
|
|
759
802
|
callback(error, false);
|
|
760
803
|
});
|
|
@@ -765,7 +808,7 @@ class ContentstorageBackend {
|
|
|
765
808
|
async loadTranslations(language, namespace) {
|
|
766
809
|
const url = this.getLoadPath(language, namespace);
|
|
767
810
|
if (this.options.debug) {
|
|
768
|
-
console.log(`[
|
|
811
|
+
console.log(`[Contentstorage] Fetching from: ${url}`);
|
|
769
812
|
}
|
|
770
813
|
try {
|
|
771
814
|
const fetchFn = this.options.request || this.defaultFetch.bind(this);
|
|
@@ -778,7 +821,7 @@ class ContentstorageBackend {
|
|
|
778
821
|
}
|
|
779
822
|
catch (error) {
|
|
780
823
|
if (this.options.debug) {
|
|
781
|
-
console.error('[
|
|
824
|
+
console.error('[Contentstorage] Fetch error:', error);
|
|
782
825
|
}
|
|
783
826
|
throw error;
|
|
784
827
|
}
|
|
@@ -810,7 +853,7 @@ class ContentstorageBackend {
|
|
|
810
853
|
}
|
|
811
854
|
// Default CDN path
|
|
812
855
|
if (!contentKey) {
|
|
813
|
-
throw new Error('[
|
|
856
|
+
throw new Error('[Contentstorage] contentKey is required when using default CDN path');
|
|
814
857
|
}
|
|
815
858
|
// Default: Always use uppercase language code
|
|
816
859
|
const lng = language.toUpperCase();
|
|
@@ -845,7 +888,7 @@ class ContentstorageBackend {
|
|
|
845
888
|
language, this.options.debug);
|
|
846
889
|
}
|
|
847
890
|
if (this.options.debug) {
|
|
848
|
-
console.log(`[
|
|
891
|
+
console.log(`[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`);
|
|
849
892
|
}
|
|
850
893
|
}
|
|
851
894
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/screenshot.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[ContentStorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[ContentStorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[ContentStorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[ContentStorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[ContentStorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[ContentStorage] Memory map not initialized');\n return;\n }\n\n console.log('[ContentStorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import { isBrowser, getContentstorageWindow } from './utils';\n\n/**\n * Decodes and validates the contentstorage key\n * Just decodes URL encoding and checks non-empty (backend validates format)\n *\n * @param key - The raw key from URL params\n * @returns Decoded key if valid, null if empty/invalid\n */\nexport function decodeContentstorageKey(key: string | null): string | null {\n if (!key) return null;\n\n try {\n const decoded = decodeURIComponent(key);\n return decoded.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detects if screenshot mode should be activated\n * Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key\n *\n * NOTE: Unlike live editor mode, screenshot mode does NOT require iframe\n *\n * @returns Object with contentstorageKey if active, null otherwise\n */\nexport function detectScreenshotMode(): { contentstorageKey: string } | null {\n if (!isBrowser()) return null;\n\n const win = getContentstorageWindow();\n if (!win) return null;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n // Check required params\n const liveEditorParam = urlParams.get('contentstorage_live_editor');\n const screenshotModeParam = urlParams.get('screenshot_mode');\n const contentstorageKey = urlParams.get('contentstorage_key');\n\n // All three must be present and valid\n if (liveEditorParam !== 'true') return null;\n if (screenshotModeParam !== 'true') return null;\n\n const decodedKey = decodeContentstorageKey(contentstorageKey);\n if (!decodedKey) return null;\n\n return {\n contentstorageKey: decodedKey,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Removes screenshot-related params from URL without page reload\n * Uses History API to update URL bar\n */\nexport function cleanScreenshotUrlParams(): void {\n if (!isBrowser()) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n try {\n const url = new URL(win.location.href);\n const paramsToRemove = [\n 'contentstorage_live_editor',\n 'screenshot_mode',\n 'contentstorage_key',\n ];\n\n paramsToRemove.forEach((param) => {\n url.searchParams.delete(param);\n });\n\n // Use replaceState to update URL without reload\n win.history.replaceState({}, '', url.toString());\n } catch (e) {\n console.warn('[ContentStorage] Failed to clean URL params:', e);\n }\n}\n\n/**\n * Exposes the API key on window for live-editor.js to use\n * Uses a non-enumerable property for security\n *\n * @param key - The validated contentstorage API key\n */\nexport function exposeApiKey(key: string): void {\n const win = getContentstorageWindow();\n if (!win) return;\n\n // Store as non-enumerable property for security\n Object.defineProperty(win, '__contentstorageApiKey', {\n value: key,\n writable: false,\n enumerable: false,\n configurable: true, // Allow cleanup later\n });\n}\n\n/**\n * Gets the exposed API key (if any)\n */\nexport function getApiKey(): string | null {\n const win = getContentstorageWindow();\n return win?.__contentstorageApiKey || null;\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode } from './utils';\nimport { detectScreenshotMode, cleanScreenshotUrlParams, exposeApiKey } from './screenshot';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n // Check for screenshot mode (works without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Works without iframe, unlike live editor mode\n */\n private initializeScreenshotMode(): void {\n // Skip if already in live mode (already initialized)\n if (this.isLiveMode) return;\n\n const screenshotConfig = detectScreenshotMode();\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Initialize current language code\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Enable tracking (reuse existing flag so process() tracks translations)\n this.isLiveMode = true;\n\n // Load live-editor.js script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode initialized');\n console.log(`[ContentStorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport {\n detectScreenshotMode,\n cleanScreenshotUrlParams,\n exposeApiKey,\n} from './screenshot';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n private services?: Services;\n private i18nextOptions?: InitOptions;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n // Store for use in initializeScreenshotMode\n this.services = services;\n this.i18nextOptions = i18nextOptions;\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor ready');\n }\n } else {\n console.warn('[ContentStorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\n console.log('[ContentStorage] Post-processor auto-registered');\n console.log('[ContentStorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[ContentStorage] Running in normal mode (not live editor)');\n }\n\n // Check for screenshot mode (works in local dev without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Exposes the API key for live-editor.js to use\n */\n private initializeScreenshotMode(): void {\n const screenshotConfig = detectScreenshotMode();\n\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Register post-processor for translation tracking\n if (this.services && this.i18nextOptions) {\n this.registerPostProcessor(this.services, this.i18nextOptions);\n }\n\n // Load live-editor.js script (handles screenshot UI)\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Screenshot mode initialized: memory map, post-processor, API key exposed');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[ContentStorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[ContentStorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[ContentStorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[ContentStorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[ContentStorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[ContentStorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils.ts","../src/screenshot.ts","../src/post-processor.ts","../src/plugin.ts"],"sourcesContent":["import type { ContentstorageWindow, MemoryMap, MemoryMapEntry } from './types';\n\n/**\n * Checks if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Gets the Contentstorage window object with type safety\n */\nexport function getContentstorageWindow(): ContentstorageWindow | null {\n if (!isBrowser()) return null;\n return window as ContentstorageWindow;\n}\n\n/**\n * Detects if the application is running in ContentStorage live editor mode\n *\n * @param liveEditorParam - Query parameter name to check\n * @param forceLiveMode - Force live mode regardless of environment\n * @returns true if in live editor mode\n */\nexport function detectLiveEditorMode(\n liveEditorParam: string = 'contentstorage_live_editor',\n forceLiveMode: boolean = false\n): boolean {\n if (forceLiveMode) return true;\n if (!isBrowser()) return false;\n\n try {\n const win = getContentstorageWindow();\n if (!win) return false;\n\n // Check 1: Running in an iframe\n const inIframe = win.self !== win.top;\n\n // Check 2: URL has the live editor marker\n const urlParams = new URLSearchParams(win.location.search);\n const hasMarker = urlParams.has(liveEditorParam);\n\n return !!(inIframe && hasMarker);\n } catch (e) {\n // Cross-origin restrictions might block window.top access\n // This is expected when not in live editor mode\n return false;\n }\n}\n\n/**\n * Initializes the global memory map if it doesn't exist\n */\nexport function initializeMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n if (!win) return null;\n\n if (!win.memoryMap) {\n win.memoryMap = new Map<string, MemoryMapEntry>();\n }\n\n return win.memoryMap;\n}\n\n/**\n * Load the ContentStorage live editor script\n * This script enables the click-to-edit functionality in the live editor\n */\nlet liveEditorReadyPromise: Promise<boolean> | null = null;\n\nexport function loadLiveEditorScript(\n retries: number = 2,\n delay: number = 3000,\n debug: boolean = false,\n customScriptUrl?: string\n): Promise<boolean> {\n // Return existing promise if already loading\n if (liveEditorReadyPromise) {\n return liveEditorReadyPromise;\n }\n\n liveEditorReadyPromise = new Promise<boolean>((resolve) => {\n const win = getContentstorageWindow();\n if (!win) {\n resolve(false);\n return;\n }\n\n const cdnScriptUrl = customScriptUrl || 'https://cdn.contentstorage.app/live-editor.js?contentstorage-live-editor=true';\n\n const loadScript = (attempt: number = 1) => {\n if (debug) {\n console.log(`[Contentstorage] Attempting to load live editor script (attempt ${attempt}/${retries})`);\n }\n\n const scriptElement = win.document.createElement('script');\n scriptElement.type = 'text/javascript';\n scriptElement.src = cdnScriptUrl;\n\n scriptElement.onload = () => {\n if (debug) {\n console.log(`[Contentstorage] Live editor script loaded successfully`);\n }\n resolve(true);\n };\n\n scriptElement.onerror = (error) => {\n // Clean up the failed script element\n scriptElement.remove();\n\n if (debug) {\n console.error(`[Contentstorage] Failed to load live editor script (attempt ${attempt}/${retries})`, error);\n }\n\n if (attempt < retries) {\n setTimeout(() => loadScript(attempt + 1), delay);\n } else {\n console.error(`[Contentstorage] All ${retries} attempts to load live editor script failed`);\n resolve(false);\n }\n };\n\n win.document.head.appendChild(scriptElement);\n };\n\n loadScript();\n });\n\n return liveEditorReadyPromise;\n}\n\n/**\n * Gets the global memory map\n */\nexport function getMemoryMap(): MemoryMap | null {\n const win = getContentstorageWindow();\n return win?.memoryMap || null;\n}\n\n/**\n * Clears all entries from the memory map\n * Used by live editor to refresh tracking\n */\nexport function clearMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (memoryMap) {\n memoryMap.clear();\n }\n}\n\n/**\n * Sets the current language code on the window object\n * This is used by the live editor to know which language is currently active\n *\n * @param languageCode - The language code to set (e.g., 'en', 'es', 'fr')\n */\nexport function setCurrentLanguageCode(languageCode: string): void {\n const win = getContentstorageWindow();\n if (win) {\n win.currentLanguageCode = languageCode;\n }\n}\n\n/**\n * Gets the current language code from the window object\n *\n * @returns The current language code, or null if not set\n */\nexport function getCurrentLanguageCode(): string | null {\n const win = getContentstorageWindow();\n return win?.currentLanguageCode || null;\n}\n\n/**\n * Normalizes i18next key format to consistent dot notation\n * Converts namespace:key format to namespace.key\n * Only adds namespace prefix if explicitly present in the key (colon notation)\n *\n * @param key - The translation key\n * @param namespace - Optional namespace (only used if not already in key)\n * @returns Normalized key in dot notation\n */\nexport function normalizeKey(key: string, namespace?: string): string {\n // namespace parameter kept for backward compatibility but not used\n void namespace;\n\n let normalizedKey = key;\n\n // Convert colon notation to dot notation (e.g., \"common:welcome\" -> \"common.welcome\")\n if (normalizedKey.includes(':')) {\n normalizedKey = normalizedKey.replace(':', '.');\n }\n\n // Don't automatically prepend namespace - only if key already had it via colon notation\n // This ensures keys match ContentStorage content IDs by default\n\n return normalizedKey;\n}\n\n/**\n * Extracts the base translation key without interpolation context\n * Handles plural forms, contexts, and other i18next features\n *\n * Examples:\n * - 'welcome' -> 'welcome'\n * - 'items_plural' -> 'items'\n * - 'friend_male' -> 'friend'\n *\n * @param key - The translation key\n * @returns Base key without suffixes\n */\nexport function extractBaseKey(key: string): string {\n // Remove plural suffixes (_zero, _one, _two, _few, _many, _other, _plural)\n let baseKey = key.replace(/_(zero|one|two|few|many|other|plural)$/, '');\n\n // Remove context suffixes (anything after last underscore that's not a nested key)\n // Be careful not to remove underscores that are part of the actual key\n // This is a heuristic - contexts usually come at the end\n const lastUnderscore = baseKey.lastIndexOf('_');\n if (lastUnderscore > 0) {\n // Only remove if it looks like a context (short suffix, typically lowercase)\n const suffix = baseKey.substring(lastUnderscore + 1);\n if (suffix.length < 10 && suffix.toLowerCase() === suffix) {\n // This might be a context, but we'll keep it for now to avoid false positives\n // Real context handling should be done at a higher level\n }\n }\n\n return baseKey;\n}\n\n/**\n * Removes interpolation variables from a translated string\n *\n * Examples:\n * - 'Hello {{name}}!' -> 'Hello !'\n * - 'You have {{count}} items' -> 'You have items'\n *\n * @param value - The translated string\n * @returns String with interpolations removed\n */\nexport function removeInterpolation(value: string): string {\n // Remove i18next interpolation syntax: {{variable}}\n return value.replace(/\\{\\{[^}]+\\}\\}/g, '').trim();\n}\n\n/**\n * i18next internal option keys that should not be treated as user variables\n * Note: 'count' and 'context' are included as they are often used in interpolation\n */\nconst I18NEXT_INTERNAL_KEYS = new Set([\n 'defaultValue',\n 'replace',\n 'lng',\n 'lngs',\n 'fallbackLng',\n 'ns',\n 'keySeparator',\n 'nsSeparator',\n 'returnObjects',\n 'returnDetails',\n 'returnedObjectHandler',\n 'joinArrays',\n 'postProcess',\n 'interpolation',\n 'skipInterpolation',\n 'appendNamespaceToMissingKey',\n 'missingKeyHandler',\n 'parseMissingKeyHandler',\n 'overloadTranslationOptionHandler',\n 'saveMissing',\n 'saveMissingTo',\n 'missingKeyNoValueFallbackToKey',\n 'missingInterpolationHandler',\n 'formatSeparator',\n 'ignoreJSONStructure',\n]);\n\n/**\n * Extracts user-provided variables from i18next options\n * Filters out i18next internal options to return only interpolation variables\n *\n * @param options - i18next options object\n * @returns Object containing only user variables, or undefined if none\n */\nexport function extractUserVariables(options?: any): Record<string, any> | undefined {\n if (!options || typeof options !== 'object') {\n return undefined;\n }\n\n const variables: Record<string, any> = {};\n let hasVariables = false;\n\n for (const key in options) {\n if (!Object.prototype.hasOwnProperty.call(options, key)) continue;\n\n // Skip i18next internal keys\n if (I18NEXT_INTERNAL_KEYS.has(key)) continue;\n\n // Skip keys starting with underscore (private i18next properties)\n if (key.startsWith('_')) continue;\n\n // Skip undefined values\n if (options[key] === undefined) continue;\n\n // This is a user variable\n variables[key] = options[key];\n hasVariables = true;\n }\n\n return hasVariables ? variables : undefined;\n}\n\n/**\n * Tracks a translation in the memory map\n *\n * @param translationValue - The actual translated text\n * @param translationKey - The content ID (i18next key)\n * @param namespace - Optional namespace\n * @param language - Optional language code\n * @param debug - Enable debug logging\n * @param variables - Optional interpolation variables used in the translation\n */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false,\n variables?: Record<string, any>\n): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) return;\n\n // Normalize the key\n const normalizedKey = normalizeKey(translationKey, namespace);\n\n // Get or create entry\n const existingEntry = memoryMap.get(translationValue);\n const idSet = existingEntry ? existingEntry.ids : new Set<string>();\n idSet.add(normalizedKey);\n\n // Merge variables: prefer new variables if provided, otherwise keep existing\n // This ensures variables are preserved when backend tracks without them\n const mergedVariables = variables && Object.keys(variables).length > 0\n ? variables\n : existingEntry?.variables;\n\n const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\n ...(mergedVariables && Object.keys(mergedVariables).length > 0 && { variables: mergedVariables }),\n metadata: {\n namespace,\n language,\n trackedAt: Date.now(),\n },\n };\n\n memoryMap.set(translationValue, entry);\n\n if (debug) {\n console.log('[Contentstorage] Tracked translation:', {\n value: translationValue,\n key: normalizedKey,\n namespace,\n language,\n variables,\n });\n }\n}\n\n/**\n * Cleans up old entries from memory map when size exceeds limit\n * Removes oldest entries first (based on trackedAt timestamp)\n *\n * @param maxSize - Maximum number of entries to keep\n */\nexport function cleanupMemoryMap(maxSize: number): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap || memoryMap.size <= maxSize) return;\n\n // Convert to array with timestamps\n const entries = Array.from(memoryMap.entries()).map(([key, value]) => ({\n key,\n value,\n timestamp: value.metadata?.trackedAt || 0,\n }));\n\n // Sort by timestamp (oldest first)\n entries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Calculate how many to remove\n const toRemove = memoryMap.size - maxSize;\n\n // Remove oldest entries\n for (let i = 0; i < toRemove; i++) {\n memoryMap.delete(entries[i].key);\n }\n}\n\n/**\n * Deeply traverses a translation object and extracts all string values with their keys\n *\n * @param obj - Translation object to traverse\n * @param prefix - Current key prefix (for nested objects)\n * @returns Array of [key, value] pairs\n */\nexport function flattenTranslations(\n obj: any,\n prefix: string = ''\n): Array<[string, string]> {\n const results: Array<[string, string]> = [];\n\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'string') {\n results.push([fullKey, value]);\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recurse into nested objects\n results.push(...flattenTranslations(value, fullKey));\n }\n }\n\n return results;\n}\n\n/**\n * Debug helper to log memory map contents\n */\nexport function debugMemoryMap(): void {\n const memoryMap = getMemoryMap();\n if (!memoryMap) {\n console.log('[Contentstorage] Memory map not initialized');\n return;\n }\n\n console.log('[Contentstorage] Memory map contents:');\n console.log(`Total entries: ${memoryMap.size}`);\n\n const entries = Array.from(memoryMap.entries()).slice(0, 10);\n console.table(\n entries.map(([value, entry]) => ({\n value: value.substring(0, 50),\n keys: Array.from(entry.ids).join(', '),\n namespace: entry.metadata?.namespace || 'N/A',\n }))\n );\n\n if (memoryMap.size > 10) {\n console.log(`... and ${memoryMap.size - 10} more entries`);\n }\n}\n","import { isBrowser, getContentstorageWindow } from './utils';\n\n/**\n * Decodes and validates the contentstorage key\n * Just decodes URL encoding and checks non-empty (backend validates format)\n *\n * @param key - The raw key from URL params\n * @returns Decoded key if valid, null if empty/invalid\n */\nexport function decodeContentstorageKey(key: string | null): string | null {\n if (!key) return null;\n\n try {\n const decoded = decodeURIComponent(key);\n return decoded.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Detects if screenshot mode should be activated\n * Requires: contentstorage_live_editor=true AND screenshot_mode=true AND valid contentstorage_key\n *\n * NOTE: Unlike live editor mode, screenshot mode does NOT require iframe\n *\n * @returns Object with contentstorageKey if active, null otherwise\n */\nexport function detectScreenshotMode(): { contentstorageKey: string } | null {\n if (!isBrowser()) return null;\n\n const win = getContentstorageWindow();\n if (!win) return null;\n\n try {\n const urlParams = new URLSearchParams(win.location.search);\n\n // Check required params\n const liveEditorParam = urlParams.get('contentstorage_live_editor');\n const screenshotModeParam = urlParams.get('screenshot_mode');\n const contentstorageKey = urlParams.get('contentstorage_key');\n\n // All three must be present and valid\n if (liveEditorParam !== 'true') return null;\n if (screenshotModeParam !== 'true') return null;\n\n const decodedKey = decodeContentstorageKey(contentstorageKey);\n if (!decodedKey) return null;\n\n return {\n contentstorageKey: decodedKey,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Removes screenshot-related params from URL without page reload\n * Uses History API to update URL bar\n */\nexport function cleanScreenshotUrlParams(): void {\n if (!isBrowser()) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n try {\n const url = new URL(win.location.href);\n const paramsToRemove = [\n 'contentstorage_live_editor',\n 'screenshot_mode',\n 'contentstorage_key',\n ];\n\n paramsToRemove.forEach((param) => {\n url.searchParams.delete(param);\n });\n\n // Use replaceState to update URL without reload\n win.history.replaceState({}, '', url.toString());\n } catch (e) {\n console.warn('[Contentstorage] Failed to clean URL params:', e);\n }\n}\n\n/**\n * Exposes the API key on window for live-editor.js to use\n * Uses a non-enumerable property for security\n *\n * @param key - The validated contentstorage API key\n */\nexport function exposeApiKey(key: string): void {\n const win = getContentstorageWindow();\n if (!win) return;\n\n // Store as non-enumerable property for security\n Object.defineProperty(win, '__contentstorageApiKey', {\n value: key,\n writable: false,\n enumerable: false,\n configurable: true, // Allow cleanup later\n });\n}\n\n/**\n * Gets the exposed API key (if any)\n */\nexport function getApiKey(): string | null {\n const win = getContentstorageWindow();\n return win?.__contentstorageApiKey || null;\n}\n","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript, extractUserVariables, setCurrentLanguageCode, clearMemoryMap, getContentstorageWindow } from './utils';\nimport { detectScreenshotMode, cleanScreenshotUrlParams, exposeApiKey } from './screenshot';\n\n/**\n * Contentstorage Live Editor Post-Processor\n *\n * This post-processor enables live editor functionality by tracking translations\n * at the point of resolution, capturing the actual values returned by i18next\n * including interpolations and plural forms.\n *\n * Use this to enable click-to-edit functionality in the Contentstorage live editor.\n * It works in addition to or instead of the backend plugin for more comprehensive\n * tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))\n * .init({\n * postProcess: ['contentstorage']\n * });\n * ```\n */\nexport class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentstorage';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private i18nextInstance: any = null;\n\n constructor(options: ContentstoragePluginOptions = {}) {\n this.options = {\n debug: false,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...options,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n initializeMemoryMap();\n\n // Initialize current language code with browser language or fallback\n // This ensures window.currentLanguageCode is never undefined\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Post-processor initialized in live mode');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n // Check for screenshot mode (works without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Works without iframe, unlike live editor mode\n */\n private initializeScreenshotMode(): void {\n // Skip if already in live mode (already initialized)\n if (this.isLiveMode) return;\n\n const screenshotConfig = detectScreenshotMode();\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Initialize current language code\n const browserLanguage = typeof navigator !== 'undefined' && navigator.language\n ? navigator.language.split('-')[0]\n : 'en';\n setCurrentLanguageCode(browserLanguage);\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Enable tracking (reuse existing flag so process() tracks translations)\n this.isLiveMode = true;\n\n // Load live-editor.js script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized');\n console.log(`[Contentstorage] Initial language code set to: ${browserLanguage}`);\n }\n }\n\n /**\n * Expose refresh function on window for live-editor.js to call\n * Only exposed in live mode (live editor or screenshot mode)\n */\n private exposeRefreshFunction(): void {\n if (!this.isLiveMode) return;\n\n const win = getContentstorageWindow();\n if (!win) return;\n\n win.__contentstorageRefresh = () => {\n // Clear memoryMap\n clearMemoryMap();\n\n // Trigger re-render by emitting languageChanged event\n // This causes useTranslation hooks to re-render\n if (this.i18nextInstance?.emit) {\n this.i18nextInstance.emit('languageChanged', this.i18nextInstance.language);\n }\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh triggered: memoryMap cleared, languageChanged emitted');\n }\n };\n\n if (this.options.debug) {\n console.log('[Contentstorage] Refresh function exposed on window.__contentstorageRefresh');\n }\n }\n\n /**\n * Process the translated value\n * Called by i18next after translation resolution\n */\n process(\n value: string,\n key: string | string[],\n options: any,\n translator: any\n ): string {\n // Only track in live mode\n if (!this.isLiveMode) {\n return value;\n }\n\n // Store i18next reference on first call and expose refresh function\n if (!this.i18nextInstance && translator) {\n this.i18nextInstance = translator;\n this.exposeRefreshFunction();\n }\n\n // Handle array of keys (fallback keys)\n const translationKey = Array.isArray(key) ? key[0] : key;\n\n // Only extract namespace if key explicitly uses colon notation\n // Don't pass namespace from options - let keys be clean by default\n let namespace: string | undefined;\n if (translationKey.includes(':')) {\n [namespace] = translationKey.split(':');\n }\n console.log('[Contentstorage plugin] ', {\n options,\n translator\n })\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Set current language code for live editor\n if (language) {\n setCurrentLanguageCode(language);\n }\n\n // Extract user variables from options\n const variables = extractUserVariables(options);\n\n // Try to get the template (non-interpolated value) from the translator\n // This allows us to track the template with {{placeholders}} instead of resolved values\n let template = value;\n try {\n if (translator?.resourceStore) {\n const ns = namespace || options?.ns || translator.options?.defaultNS || 'translation';\n const lng = language || translator.language;\n\n // Try to get the raw translation template from the resource store\n const rawTranslation = translator.resourceStore.getResource(lng, ns, translationKey);\n if (rawTranslation && typeof rawTranslation === 'string') {\n template = rawTranslation;\n }\n }\n } catch (e) {\n // If we can't get the template, fall back to using the resolved value\n if (this.options.debug) {\n console.warn('[Contentstorage plugin] Could not retrieve template for:', translationKey, e);\n }\n }\n\n // Track the translation with the template\n trackTranslation(\n template,\n translationKey,\n namespace,\n language,\n this.options.debug,\n variables\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the Contentstorage Live Editor post-processor\n */\nexport function createContentstorageLiveEditorPostProcessor(\n options?: ContentstoragePluginOptions\n): ContentstorageLiveEditorPostProcessor {\n return new ContentstorageLiveEditorPostProcessor(options);\n}\n","import type {\n BackendModule,\n ReadCallback,\n Services,\n InitOptions,\n} from 'i18next';\nimport type {\n ContentstoragePluginOptions,\n TranslationData,\n} from './types';\nimport {\n detectLiveEditorMode,\n initializeMemoryMap,\n trackTranslation,\n cleanupMemoryMap,\n flattenTranslations,\n isBrowser,\n loadLiveEditorScript,\n} from './utils';\nimport {\n detectScreenshotMode,\n cleanScreenshotUrlParams,\n exposeApiKey,\n} from './screenshot';\nimport { ContentstorageLiveEditorPostProcessor } from './post-processor';\n\n/**\n * Contentstorage i18next Backend Plugin\n *\n * This plugin enables translation tracking for the Contentstorage live editor\n * by maintaining a memory map of translations and their keys.\n *\n * Features:\n * - Automatic live editor mode detection\n * - Translation tracking with memory map\n * - Support for nested translations\n * - Memory management with size limits\n * - Custom CDN or load path support\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import ContentstorageBackend from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(ContentstorageBackend)\n * .init({\n * backend: {\n * contentKey: 'your-content-key',\n * debug: true\n * }\n * });\n * ```\n */\nexport class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {\n static type: 'backend' = 'backend';\n type: 'backend' = 'backend';\n\n private options: ContentstoragePluginOptions;\n private isLiveMode: boolean = false;\n private postProcessor?: ContentstorageLiveEditorPostProcessor;\n private services?: Services;\n private i18nextOptions?: InitOptions;\n\n constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions) {\n this.options = options || {};\n\n // Initialize if services and i18nextOptions are provided\n // This allows i18next to initialize the plugin automatically\n if (_services && _i18nextOptions) {\n this.init(_services, options, _i18nextOptions);\n }\n }\n\n /**\n * Initialize the plugin\n * Called by i18next during initialization\n */\n init(\n services: Services,\n backendOptions: ContentstoragePluginOptions = {},\n i18nextOptions: InitOptions = {}\n ): void {\n // Store for use in initializeScreenshotMode\n this.services = services;\n this.i18nextOptions = i18nextOptions;\n\n this.options = {\n debug: false,\n maxMemoryMapSize: 10000,\n liveEditorParam: 'contentstorage_live_editor',\n forceLiveMode: false,\n ...backendOptions,\n };\n\n // Detect live editor mode\n this.isLiveMode = detectLiveEditorMode(\n this.options.liveEditorParam,\n this.options.forceLiveMode\n );\n\n if (this.isLiveMode) {\n // Initialize memory map\n initializeMemoryMap();\n\n // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl).then((loaded) => {\n if (loaded) {\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor ready');\n }\n } else {\n console.warn('[Contentstorage] Failed to load live editor script');\n }\n });\n\n // Auto-register the post-processor for live editor tracking\n this.registerPostProcessor(services, i18nextOptions);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Live editor mode enabled');\n console.log('[Contentstorage] Post-processor auto-registered');\n console.log('[Contentstorage] Plugin initialized with options:', this.options);\n }\n } else if (this.options.debug) {\n console.log('[Contentstorage] Running in normal mode (not live editor)');\n }\n\n // Check for screenshot mode (works in local dev without iframe)\n this.initializeScreenshotMode();\n }\n\n /**\n * Initialize screenshot mode if URL params indicate it\n * Exposes the API key for live-editor.js to use\n */\n private initializeScreenshotMode(): void {\n const screenshotConfig = detectScreenshotMode();\n\n if (!screenshotConfig) return;\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode detected');\n }\n\n // Initialize memory map for translation tracking\n initializeMemoryMap();\n\n // Expose API key for live-editor.js to use\n exposeApiKey(screenshotConfig.contentstorageKey);\n\n // Clean URL params for security\n cleanScreenshotUrlParams();\n\n // Register post-processor for translation tracking\n if (this.services && this.i18nextOptions) {\n this.registerPostProcessor(this.services, this.i18nextOptions);\n }\n\n // Load live-editor.js script (handles screenshot UI)\n loadLiveEditorScript(2, 3000, this.options.debug, this.options.customLiveEditorScriptUrl);\n\n if (this.options.debug) {\n console.log('[Contentstorage] Screenshot mode initialized: memory map, post-processor, API key exposed');\n }\n }\n\n /**\n * Auto-register the live editor post-processor\n * This allows dynamic translation tracking without requiring explicit postProcess config\n */\n private registerPostProcessor(services: Services, i18nextOptions: InitOptions): void {\n // Create post-processor instance\n this.postProcessor = new ContentstorageLiveEditorPostProcessor(this.options);\n\n // Register with i18next\n services.languageUtils?.addPostProcessor(this.postProcessor);\n\n // Add to postProcess array if it exists, otherwise create it\n const initOptions = i18nextOptions as any;\n if (!initOptions.postProcess) {\n initOptions.postProcess = [];\n }\n\n // Ensure postProcess is an array\n if (!Array.isArray(initOptions.postProcess)) {\n initOptions.postProcess = [initOptions.postProcess];\n }\n\n // Add our post-processor if not already present\n if (!initOptions.postProcess.includes('contentstorage')) {\n initOptions.postProcess.push('contentstorage');\n }\n }\n\n /**\n * Read translations for a given language and namespace\n * This is the main method called by i18next to load translations\n */\n read(\n language: string,\n namespace: string,\n callback: ReadCallback\n ): void {\n if (this.options.debug) {\n console.log(`[Contentstorage] Loading translations: ${language}/${namespace}`);\n }\n\n this.loadTranslations(language, namespace)\n .then((translations) => {\n // Track translations if in live mode\n if (this.isLiveMode && this.shouldTrackNamespace(namespace)) {\n this.trackTranslations(translations, namespace, language);\n\n // Cleanup if needed\n if (this.options.maxMemoryMapSize) {\n cleanupMemoryMap(this.options.maxMemoryMapSize);\n }\n }\n\n callback(null, translations);\n })\n .catch((error) => {\n if (this.options.debug) {\n console.error('[Contentstorage] Failed to load translations:', error);\n }\n callback(error, false);\n });\n }\n\n /**\n * Load translations from CDN or custom source\n */\n private async loadTranslations(\n language: string,\n namespace: string\n ): Promise<TranslationData> {\n const url = this.getLoadPath(language, namespace);\n\n if (this.options.debug) {\n console.log(`[Contentstorage] Fetching from: ${url}`);\n }\n\n try {\n const fetchFn = this.options.request || this.defaultFetch.bind(this);\n return await fetchFn(url, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n } catch (error) {\n if (this.options.debug) {\n console.error('[Contentstorage] Fetch error:', error);\n }\n throw error;\n }\n }\n\n /**\n * Default fetch implementation\n */\n private async defaultFetch(url: string, options: RequestInit): Promise<any> {\n const response = await fetch(url, options);\n\n if (!response.ok) {\n throw new Error(\n `Failed to load translations: ${response.status} ${response.statusText}`\n );\n }\n\n return response.json();\n }\n\n /**\n * Get the URL to load translations from\n */\n private getLoadPath(language: string, namespace: string): string {\n const { loadPath, contentKey } = this.options;\n\n // Custom load path function\n if (typeof loadPath === 'function') {\n return loadPath(language, namespace);\n }\n\n // Custom load path string with interpolation\n if (typeof loadPath === 'string') {\n return loadPath\n .replace('{{lng}}', language)\n .replace('{{ns}}', namespace);\n }\n\n // Default CDN path\n if (!contentKey) {\n throw new Error(\n '[Contentstorage] contentKey is required when using default CDN path'\n );\n }\n\n // Default: Always use uppercase language code\n const lng = language.toUpperCase();\n\n // Default: https://cdn.contentstorage.app/{contentKey}/content/{LNG}.json\n return `https://cdn.contentstorage.app/${contentKey}/content/${lng}.json`;\n }\n\n /**\n * Check if a namespace should be tracked\n */\n private shouldTrackNamespace(namespace: string): boolean {\n const { trackNamespaces } = this.options;\n\n // If no filter specified, track all namespaces\n if (!trackNamespaces || trackNamespaces.length === 0) {\n return true;\n }\n\n return trackNamespaces.includes(namespace);\n }\n\n /**\n * Track all translations in the loaded data\n */\n private trackTranslations(\n translations: TranslationData,\n namespace: string,\n language: string\n ): void {\n if (!isBrowser()) return;\n\n const flatTranslations = flattenTranslations(translations);\n\n for (const [key, value] of flatTranslations) {\n // Skip empty values\n if (!value) continue;\n\n // Don't pass namespace - let keys be tracked without prefix by default\n // Only keys with explicit colon notation (e.g., \"common:welcome\") will have namespace\n trackTranslation(\n value,\n key,\n undefined, // namespace not passed by default\n language,\n this.options.debug\n );\n }\n\n if (this.options.debug) {\n console.log(\n `[Contentstorage] Tracked ${flatTranslations.length} translations for ${namespace}`\n );\n }\n }\n}\n\n/**\n * Create a new instance of the Contentstorage backend\n */\nexport function createContentstorageBackend(\n options?: ContentstoragePluginOptions\n): ContentstorageBackend {\n return new ContentstorageBackend(undefined, options);\n}\n\n// Default export\nexport default ContentstorageBackend;\n"],"names":[],"mappings":"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"}
|
package/dist/post-processor.d.ts
CHANGED
|
@@ -29,12 +29,18 @@ export declare class ContentstorageLiveEditorPostProcessor implements PostProces
|
|
|
29
29
|
name: string;
|
|
30
30
|
private options;
|
|
31
31
|
private isLiveMode;
|
|
32
|
+
private i18nextInstance;
|
|
32
33
|
constructor(options?: ContentstoragePluginOptions);
|
|
33
34
|
/**
|
|
34
35
|
* Initialize screenshot mode if URL params indicate it
|
|
35
36
|
* Works without iframe, unlike live editor mode
|
|
36
37
|
*/
|
|
37
38
|
private initializeScreenshotMode;
|
|
39
|
+
/**
|
|
40
|
+
* Expose refresh function on window for live-editor.js to call
|
|
41
|
+
* Only exposed in live mode (live editor or screenshot mode)
|
|
42
|
+
*/
|
|
43
|
+
private exposeRefreshFunction;
|
|
38
44
|
/**
|
|
39
45
|
* Process the translated value
|
|
40
46
|
* Called by i18next after translation resolution
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-processor.d.ts","sourceRoot":"","sources":["../src/post-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,qCAAsC,YAAW,mBAAmB;IAC/E,MAAM,CAAC,IAAI,EAAE,eAAe,CAAmB;IAC/C,IAAI,EAAE,eAAe,CAAmB;IACxC,IAAI,EAAE,MAAM,CAAoB;IAEhC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,UAAU,CAAkB;gBAExB,OAAO,GAAE,2BAAgC;IAqCrD;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAsChC;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,EACtB,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,GAAG,GACd,MAAM;
|
|
1
|
+
{"version":3,"file":"post-processor.d.ts","sourceRoot":"","sources":["../src/post-processor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAI3D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,qCAAsC,YAAW,mBAAmB;IAC/E,MAAM,CAAC,IAAI,EAAE,eAAe,CAAmB;IAC/C,IAAI,EAAE,eAAe,CAAmB;IACxC,IAAI,EAAE,MAAM,CAAoB;IAEhC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,eAAe,CAAa;gBAExB,OAAO,GAAE,2BAAgC;IAqCrD;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAsChC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA0B7B;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,EACtB,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,GAAG,GACd,MAAM;CAqEV;AAED;;GAEG;AACH,wBAAgB,2CAA2C,CACzD,OAAO,CAAC,EAAE,2BAA2B,GACpC,qCAAqC,CAEvC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export interface ContentstorageWindow extends Window {
|
|
|
32
32
|
currentLanguageCode?: string;
|
|
33
33
|
/** API key exposed for live-editor.js to use for screenshot uploads */
|
|
34
34
|
__contentstorageApiKey?: string;
|
|
35
|
+
/** Refresh function to clear memoryMap and trigger re-render */
|
|
36
|
+
__contentstorageRefresh?: () => void;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* Plugin configuration options
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,sCAAsC;IACtC,QAAQ,CAAC,EAAE;QACT,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,oBAAoB;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,6BAA6B;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,MAAM;IAClD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,sBAAsB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,sCAAsC;IACtC,QAAQ,CAAC,EAAE;QACT,iDAAiD;QACjD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,oBAAoB;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,6BAA6B;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,MAAM;IAClD,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEtE;;;OAGG;IACH,OAAO,CAAC,EAAE,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,GAAG,CAAC,CAAC;IAElB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAEnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC;CACzC,CAAC"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -24,6 +24,11 @@ export declare function loadLiveEditorScript(retries?: number, delay?: number, d
|
|
|
24
24
|
* Gets the global memory map
|
|
25
25
|
*/
|
|
26
26
|
export declare function getMemoryMap(): MemoryMap | null;
|
|
27
|
+
/**
|
|
28
|
+
* Clears all entries from the memory map
|
|
29
|
+
* Used by live editor to refresh tracking
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearMemoryMap(): void;
|
|
27
32
|
/**
|
|
28
33
|
* Sets the current language code on the window object
|
|
29
34
|
* This is used by the live editor to know which language is currently active
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAkB,MAAM,SAAS,CAAC;AAE/E;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,IAAI,CAGrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,GAAE,MAAqC,EACtD,aAAa,GAAE,OAAe,GAC7B,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,GAAG,IAAI,CAStD;AAQD,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAa,EACpB,KAAK,GAAE,OAAe,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAsDlB;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAGtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAepE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAkCD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0BnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,IAAI,CAwCN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAqBtD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,MAAM,GAAE,MAAW,GAClB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBzB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAkB,MAAM,SAAS,CAAC;AAE/E;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,IAAI,CAGrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,GAAE,MAAqC,EACtD,aAAa,GAAE,OAAe,GAC7B,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,GAAG,IAAI,CAStD;AAQD,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAa,EACpB,KAAK,GAAE,OAAe,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CAsDlB;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAG/C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAKjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAGtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAepE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD;AAkCD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CA0BnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,IAAI,CAwCN;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAqBtD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,GAAG,EACR,MAAM,GAAE,MAAW,GAClB,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkBzB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
|
package/package.json
CHANGED