@contentstorage/i18next-plugin 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,16 +1,16 @@
1
- # ContentStorage i18next Plugin
1
+ # Contentstorage i18next Plugin
2
2
 
3
- Official i18next plugin for [ContentStorage](https://contentstorage.app) live editor translation tracking.
3
+ Official i18next plugin for [Contentstorage](https://contentstorage.app) live editor translation tracking.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Live Editor Integration** - Automatically detects and enables tracking when running in ContentStorage live editor
7
+ - **Live Editor Integration** - Automatically detects and enables tracking when running in Contentstorage live editor
8
8
  - **Translation Tracking** - Maps translation values to their keys for click-to-edit functionality
9
9
  - **Zero Production Overhead** - Tracking only activates in live editor mode
10
10
  - **TypeScript Support** - Full type definitions included
11
11
  - **Memory Management** - Automatic cleanup of old entries to prevent memory leaks
12
12
  - **Flexible Loading** - Support for CDN, custom URLs, or custom fetch functions
13
- - **Post-Processor Support** - Track translations at resolution time for dynamic content
13
+ - **Live Editor Post-Processor** - Track translations at resolution time for click-to-edit functionality
14
14
 
15
15
  ## Installation
16
16
 
@@ -24,13 +24,13 @@ npm install @contentstorage/i18next-plugin
24
24
 
25
25
  ```typescript
26
26
  import i18next from 'i18next';
27
- import ContentStorageBackend from '@contentstorage/i18next-plugin';
27
+ import ContentstorageBackend from '@contentstorage/i18next-plugin';
28
28
 
29
29
  i18next
30
- .use(ContentStorageBackend)
30
+ .use(ContentstorageBackend)
31
31
  .init({
32
32
  backend: {
33
- contentKey: 'your-content-key-here', // Get this from ContentStorage dashboard
33
+ contentKey: 'your-content-key-here', // Get this from Contentstorage dashboard
34
34
  debug: false,
35
35
  },
36
36
  lng: 'en',
@@ -43,17 +43,17 @@ i18next
43
43
  i18next.t('common:welcome'); // "Welcome to our site"
44
44
  ```
45
45
 
46
- ### With Post-Processor (Recommended)
46
+ ### With Live Editor Post-Processor (Recommended)
47
47
 
48
48
  For better tracking of dynamic translations with interpolations:
49
49
 
50
50
  ```typescript
51
51
  import i18next from 'i18next';
52
- import ContentStorageBackend, { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';
52
+ import ContentstorageBackend, { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';
53
53
 
54
54
  i18next
55
- .use(ContentStorageBackend)
56
- .use(new ContentStoragePostProcessor({ debug: false }))
55
+ .use(ContentstorageBackend)
56
+ .use(new ContentstorageLiveEditorPostProcessor({ debug: false }))
57
57
  .init({
58
58
  backend: {
59
59
  contentKey: 'your-content-key',
@@ -71,9 +71,9 @@ i18next.t('greeting', { name: 'John' }); // "Hello John"
71
71
  ### Backend Options
72
72
 
73
73
  ```typescript
74
- interface ContentStoragePluginOptions {
74
+ interface ContentstoragePluginOptions {
75
75
  /**
76
- * Your ContentStorage content key (required for default CDN)
76
+ * Your Contentstorage content key (required for default CDN)
77
77
  */
78
78
  contentKey?: string;
79
79
 
@@ -131,7 +131,7 @@ interface ContentStoragePluginOptions {
131
131
  ### Custom CDN URL
132
132
 
133
133
  ```typescript
134
- i18next.use(ContentStorageBackend).init({
134
+ i18next.use(ContentstorageBackend).init({
135
135
  backend: {
136
136
  contentKey: 'your-key',
137
137
  cdnBaseUrl: 'https://your-custom-cdn.com',
@@ -142,14 +142,14 @@ i18next.use(ContentStorageBackend).init({
142
142
  ### Custom Load Path
143
143
 
144
144
  ```typescript
145
- i18next.use(ContentStorageBackend).init({
145
+ i18next.use(ContentstorageBackend).init({
146
146
  backend: {
147
147
  loadPath: '/locales/{{lng}}/{{ns}}.json',
148
148
  },
149
149
  });
150
150
 
151
151
  // Or with a function
152
- i18next.use(ContentStorageBackend).init({
152
+ i18next.use(ContentstorageBackend).init({
153
153
  backend: {
154
154
  loadPath: (lng, ns) => {
155
155
  return `https://api.example.com/translations/${lng}/${ns}`;
@@ -161,7 +161,7 @@ i18next.use(ContentStorageBackend).init({
161
161
  ### Custom Fetch with Authentication
162
162
 
163
163
  ```typescript
164
- i18next.use(ContentStorageBackend).init({
164
+ i18next.use(ContentstorageBackend).init({
165
165
  backend: {
166
166
  contentKey: 'your-key',
167
167
  request: async (url, options) => {
@@ -186,7 +186,7 @@ i18next.use(ContentStorageBackend).init({
186
186
  ### Track Only Specific Namespaces
187
187
 
188
188
  ```typescript
189
- i18next.use(ContentStorageBackend).init({
189
+ i18next.use(ContentstorageBackend).init({
190
190
  backend: {
191
191
  contentKey: 'your-key',
192
192
  trackNamespaces: ['common', 'marketing'], // Only track these
@@ -199,8 +199,8 @@ i18next.use(ContentStorageBackend).init({
199
199
 
200
200
  ```typescript
201
201
  i18next
202
- .use(ContentStorageBackend)
203
- .use(new ContentStoragePostProcessor({ debug: true }))
202
+ .use(ContentstorageBackend)
203
+ .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))
204
204
  .init({
205
205
  backend: {
206
206
  contentKey: 'your-key',
@@ -209,16 +209,16 @@ i18next
209
209
  });
210
210
 
211
211
  // Console output:
212
- // [ContentStorage] Live editor mode enabled
213
- // [ContentStorage] Loading translations: en/common
214
- // [ContentStorage] Tracked 42 translations for common
212
+ // [Contentstorage] Live editor mode enabled
213
+ // [Contentstorage] Loading translations: en/common
214
+ // [Contentstorage] Tracked 42 translations for common
215
215
  ```
216
216
 
217
217
  ## How It Works
218
218
 
219
219
  ### Live Editor Detection
220
220
 
221
- The plugin automatically detects when your app is running in the ContentStorage live editor by checking:
221
+ The plugin automatically detects when your app is running in the Contentstorage live editor by checking:
222
222
 
223
223
  1. The app is running in an iframe (`window.self !== window.top`)
224
224
  2. The URL contains the query parameter `?contentstorage_live_editor=true`
@@ -244,7 +244,7 @@ window.memoryMap = new Map([
244
244
  ]);
245
245
  ```
246
246
 
247
- This allows the ContentStorage live editor to:
247
+ This allows the Contentstorage live editor to:
248
248
  1. Find which translation keys produced a given text
249
249
  2. Enable click-to-edit functionality
250
250
  3. Highlight translatable content on the page
@@ -264,10 +264,10 @@ The plugin automatically limits the size of `window.memoryMap` to prevent memory
264
264
  ```typescript
265
265
  import i18next from 'i18next';
266
266
  import { initReactI18next } from 'react-i18next';
267
- import ContentStorageBackend from '@contentstorage/i18next-plugin';
267
+ import ContentstorageBackend from '@contentstorage/i18next-plugin';
268
268
 
269
269
  i18next
270
- .use(ContentStorageBackend)
270
+ .use(ContentstorageBackend)
271
271
  .use(initReactI18next)
272
272
  .init({
273
273
  backend: {
@@ -297,9 +297,9 @@ function MyComponent() {
297
297
  ```typescript
298
298
  // app/i18n.ts
299
299
  import i18next from 'i18next';
300
- import ContentStorageBackend from '@contentstorage/i18next-plugin';
300
+ import ContentstorageBackend from '@contentstorage/i18next-plugin';
301
301
 
302
- i18next.use(ContentStorageBackend).init({
302
+ i18next.use(ContentstorageBackend).init({
303
303
  backend: {
304
304
  contentKey: process.env.NEXT_PUBLIC_CONTENTSTORAGE_KEY,
305
305
  },
@@ -343,7 +343,7 @@ export default function RootLayout({
343
343
  For testing purposes, you can force live mode:
344
344
 
345
345
  ```typescript
346
- i18next.use(ContentStorageBackend).init({
346
+ i18next.use(ContentstorageBackend).init({
347
347
  backend: {
348
348
  contentKey: 'your-key',
349
349
  forceLiveMode: true, // Always enable tracking
@@ -360,7 +360,7 @@ import { debugMemoryMap } from '@contentstorage/i18next-plugin';
360
360
  debugMemoryMap();
361
361
 
362
362
  // Output:
363
- // [ContentStorage] Memory map contents:
363
+ // [Contentstorage] Memory map contents:
364
364
  // Total entries: 156
365
365
  // ┌─────────┬──────────────────────────────┬─────────────────────┐
366
366
  // │ (index) │ value │ keys │
@@ -383,10 +383,10 @@ Full TypeScript support included with type definitions:
383
383
 
384
384
  ```typescript
385
385
  import type {
386
- ContentStoragePluginOptions,
386
+ ContentstoragePluginOptions,
387
387
  MemoryMap,
388
388
  MemoryMapEntry,
389
- ContentStorageWindow,
389
+ ContentstorageWindow,
390
390
  } from '@contentstorage/i18next-plugin';
391
391
  ```
392
392
 
@@ -435,7 +435,7 @@ import type {
435
435
  **Solutions**:
436
436
  - Verify your contentKey is correct
437
437
  - Check CDN URL in network tab
438
- - Ensure ContentStorage CDN allows your domain
438
+ - Ensure Contentstorage CDN allows your domain
439
439
  - Use custom `request` function to debug
440
440
 
441
441
  ## Contributing
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @contentstorage/i18next-plugin
3
3
  *
4
- * i18next backend plugin for ContentStorage live editor translation tracking
4
+ * i18next backend plugin for Contentstorage live editor translation tracking
5
5
  */
6
- export { ContentStorageBackend, createContentStorageBackend } from './plugin';
7
- export { ContentStoragePostProcessor, createContentStoragePostProcessor } from './post-processor';
6
+ export { ContentstorageBackend, createContentstorageBackend } from './plugin';
7
+ export { ContentstorageLiveEditorPostProcessor, createContentstorageLiveEditorPostProcessor, } from './post-processor';
8
8
  export { debugMemoryMap, loadLiveEditorScript } from './utils';
9
- export type { ContentStoragePluginOptions, MemoryMap, MemoryMapEntry, ContentStorageWindow, TranslationData, } from './types';
9
+ export type { ContentstoragePluginOptions, MemoryMap, MemoryMapEntry, ContentstorageWindow, TranslationData, } from './types';
10
10
  export { default } from './plugin';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,iCAAiC,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/D,YAAY,EACV,2BAA2B,EAC3B,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EACL,qCAAqC,EACrC,2CAA2C,GAC5C,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/D,YAAY,EACV,2BAA2B,EAC3B,SAAS,EACT,cAAc,EACd,oBAAoB,EACpB,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.esm.js CHANGED
@@ -5,9 +5,9 @@ function isBrowser() {
5
5
  return typeof window !== 'undefined' && typeof document !== 'undefined';
6
6
  }
7
7
  /**
8
- * Gets the ContentStorage window object with type safety
8
+ * Gets the Contentstorage window object with type safety
9
9
  */
10
- function getContentStorageWindow() {
10
+ function getContentstorageWindow() {
11
11
  if (!isBrowser())
12
12
  return null;
13
13
  return window;
@@ -25,7 +25,7 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
25
25
  if (!isBrowser())
26
26
  return false;
27
27
  try {
28
- const win = getContentStorageWindow();
28
+ const win = getContentstorageWindow();
29
29
  if (!win)
30
30
  return false;
31
31
  // Check 1: Running in an iframe
@@ -45,7 +45,7 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
45
45
  * Initializes the global memory map if it doesn't exist
46
46
  */
47
47
  function initializeMemoryMap() {
48
- const win = getContentStorageWindow();
48
+ const win = getContentstorageWindow();
49
49
  if (!win)
50
50
  return null;
51
51
  if (!win.memoryMap) {
@@ -64,7 +64,7 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false) {
64
64
  return liveEditorReadyPromise;
65
65
  }
66
66
  liveEditorReadyPromise = new Promise((resolve) => {
67
- const win = getContentStorageWindow();
67
+ const win = getContentstorageWindow();
68
68
  if (!win) {
69
69
  resolve(false);
70
70
  return;
@@ -107,7 +107,7 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false) {
107
107
  * Gets the global memory map
108
108
  */
109
109
  function getMemoryMap() {
110
- const win = getContentStorageWindow();
110
+ const win = getContentstorageWindow();
111
111
  return (win === null || win === void 0 ? void 0 : win.memoryMap) || null;
112
112
  }
113
113
  /**
@@ -245,9 +245,9 @@ function debugMemoryMap() {
245
245
  }
246
246
 
247
247
  /**
248
- * ContentStorage i18next Backend Plugin
248
+ * Contentstorage i18next Backend Plugin
249
249
  *
250
- * This plugin enables translation tracking for the ContentStorage live editor
250
+ * This plugin enables translation tracking for the Contentstorage live editor
251
251
  * by maintaining a memory map of translations and their keys.
252
252
  *
253
253
  * Features:
@@ -260,10 +260,10 @@ function debugMemoryMap() {
260
260
  * @example
261
261
  * ```typescript
262
262
  * import i18next from 'i18next';
263
- * import ContentStorageBackend from '@contentstorage/i18next-plugin';
263
+ * import ContentstorageBackend from '@contentstorage/i18next-plugin';
264
264
  *
265
265
  * i18next
266
- * .use(ContentStorageBackend)
266
+ * .use(ContentstorageBackend)
267
267
  * .init({
268
268
  * backend: {
269
269
  * contentKey: 'your-content-key',
@@ -272,7 +272,7 @@ function debugMemoryMap() {
272
272
  * });
273
273
  * ```
274
274
  */
275
- class ContentStorageBackend {
275
+ class ContentstorageBackend {
276
276
  constructor(_services, options, _i18nextOptions) {
277
277
  this.type = 'backend';
278
278
  this.isLiveMode = false;
@@ -437,40 +437,41 @@ class ContentStorageBackend {
437
437
  }
438
438
  }
439
439
  }
440
- ContentStorageBackend.type = 'backend';
440
+ ContentstorageBackend.type = 'backend';
441
441
  /**
442
- * Create a new instance of the ContentStorage backend
442
+ * Create a new instance of the Contentstorage backend
443
443
  */
444
- function createContentStorageBackend(options) {
445
- return new ContentStorageBackend(undefined, options);
444
+ function createContentstorageBackend(options) {
445
+ return new ContentstorageBackend(undefined, options);
446
446
  }
447
447
 
448
448
  /**
449
- * ContentStorage Post-Processor
449
+ * Contentstorage Live Editor Post-Processor
450
450
  *
451
- * This post-processor tracks translations at the point of resolution,
452
- * capturing the actual values returned by i18next including interpolations
453
- * and plural forms.
451
+ * This post-processor enables live editor functionality by tracking translations
452
+ * at the point of resolution, capturing the actual values returned by i18next
453
+ * including interpolations and plural forms.
454
454
  *
455
- * Use this in addition to or instead of the backend plugin for more
456
- * comprehensive tracking, especially for dynamic translations.
455
+ * Use this to enable click-to-edit functionality in the Contentstorage live editor.
456
+ * It works in addition to or instead of the backend plugin for more comprehensive
457
+ * tracking, especially for dynamic translations.
457
458
  *
458
459
  * @example
459
460
  * ```typescript
460
461
  * import i18next from 'i18next';
461
- * import { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';
462
+ * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';
462
463
  *
463
464
  * i18next
464
- * .use(new ContentStoragePostProcessor({ debug: true }))
465
+ * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))
465
466
  * .init({
466
- * // ... your config
467
+ * postProcess: ['contentstorage']
467
468
  * });
468
469
  * ```
469
470
  */
470
- class ContentStoragePostProcessor {
471
+ class ContentstorageLiveEditorPostProcessor {
471
472
  constructor(options = {}) {
472
473
  this.type = 'postProcessor';
473
- this.name = 'contentStorageTracker';
474
+ this.name = 'contentstorage';
474
475
  this.isLiveMode = false;
475
476
  this.options = {
476
477
  debug: false,
@@ -513,13 +514,13 @@ class ContentStoragePostProcessor {
513
514
  return value;
514
515
  }
515
516
  }
516
- ContentStoragePostProcessor.type = 'postProcessor';
517
+ ContentstorageLiveEditorPostProcessor.type = 'postProcessor';
517
518
  /**
518
- * Create a new instance of the ContentStorage post-processor
519
+ * Create a new instance of the Contentstorage Live Editor post-processor
519
520
  */
520
- function createContentStoragePostProcessor(options) {
521
- return new ContentStoragePostProcessor(options);
521
+ function createContentstorageLiveEditorPostProcessor(options) {
522
+ return new ContentstorageLiveEditorPostProcessor(options);
522
523
  }
523
524
 
524
- export { ContentStorageBackend, ContentStoragePostProcessor, createContentStorageBackend, createContentStoragePostProcessor, debugMemoryMap, ContentStorageBackend as default, loadLiveEditorScript };
525
+ export { ContentstorageBackend, ContentstorageLiveEditorPostProcessor, createContentstorageBackend, createContentstorageLiveEditorPostProcessor, debugMemoryMap, ContentstorageBackend as default, loadLiveEditorScript };
525
526
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/plugin.ts","../src/post-processor.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): 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 = '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 * 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 * 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 */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false\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 const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\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 });\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 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';\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\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 services and i18nextOptions for potential future use\n // Note: Currently not used but kept in signature for i18next compatibility\n void services;\n void 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).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 if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\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\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","import type { PostProcessorModule } from 'i18next';\nimport type { ContentStoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript } from './utils';\n\n/**\n * ContentStorage Post-Processor\n *\n * This post-processor tracks translations at the point of resolution,\n * capturing the actual values returned by i18next including interpolations\n * and plural forms.\n *\n * Use this in addition to or instead of the backend plugin for more\n * comprehensive tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentStoragePostProcessor({ debug: true }))\n * .init({\n * // ... your config\n * });\n * ```\n */\nexport class ContentStoragePostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentStorageTracker';\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 // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n }\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\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Track the translation\n trackTranslation(\n value,\n translationKey,\n namespace,\n language,\n this.options.debug\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the ContentStorage post-processor\n */\nexport function createContentStoragePostProcessor(\n options?: ContentStoragePluginOptions\n): ContentStoragePostProcessor {\n return new ContentStoragePostProcessor(options);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/utils.ts","../src/plugin.ts","../src/post-processor.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): 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 = '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 * 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 * 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 */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false\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 const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\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 });\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 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';\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\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 services and i18nextOptions for potential future use\n // Note: Currently not used but kept in signature for i18next compatibility\n void services;\n void 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).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 if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\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\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","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript } from './utils';\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 // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n }\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\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Track the translation\n trackTranslation(\n value,\n translationKey,\n namespace,\n language,\n this.options.debug\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"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,9 +9,9 @@ function isBrowser() {
9
9
  return typeof window !== 'undefined' && typeof document !== 'undefined';
10
10
  }
11
11
  /**
12
- * Gets the ContentStorage window object with type safety
12
+ * Gets the Contentstorage window object with type safety
13
13
  */
14
- function getContentStorageWindow() {
14
+ function getContentstorageWindow() {
15
15
  if (!isBrowser())
16
16
  return null;
17
17
  return window;
@@ -29,7 +29,7 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
29
29
  if (!isBrowser())
30
30
  return false;
31
31
  try {
32
- const win = getContentStorageWindow();
32
+ const win = getContentstorageWindow();
33
33
  if (!win)
34
34
  return false;
35
35
  // Check 1: Running in an iframe
@@ -49,7 +49,7 @@ function detectLiveEditorMode(liveEditorParam = 'contentstorage_live_editor', fo
49
49
  * Initializes the global memory map if it doesn't exist
50
50
  */
51
51
  function initializeMemoryMap() {
52
- const win = getContentStorageWindow();
52
+ const win = getContentstorageWindow();
53
53
  if (!win)
54
54
  return null;
55
55
  if (!win.memoryMap) {
@@ -68,7 +68,7 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false) {
68
68
  return liveEditorReadyPromise;
69
69
  }
70
70
  liveEditorReadyPromise = new Promise((resolve) => {
71
- const win = getContentStorageWindow();
71
+ const win = getContentstorageWindow();
72
72
  if (!win) {
73
73
  resolve(false);
74
74
  return;
@@ -111,7 +111,7 @@ function loadLiveEditorScript(retries = 2, delay = 3000, debug = false) {
111
111
  * Gets the global memory map
112
112
  */
113
113
  function getMemoryMap() {
114
- const win = getContentStorageWindow();
114
+ const win = getContentstorageWindow();
115
115
  return (win === null || win === void 0 ? void 0 : win.memoryMap) || null;
116
116
  }
117
117
  /**
@@ -249,9 +249,9 @@ function debugMemoryMap() {
249
249
  }
250
250
 
251
251
  /**
252
- * ContentStorage i18next Backend Plugin
252
+ * Contentstorage i18next Backend Plugin
253
253
  *
254
- * This plugin enables translation tracking for the ContentStorage live editor
254
+ * This plugin enables translation tracking for the Contentstorage live editor
255
255
  * by maintaining a memory map of translations and their keys.
256
256
  *
257
257
  * Features:
@@ -264,10 +264,10 @@ function debugMemoryMap() {
264
264
  * @example
265
265
  * ```typescript
266
266
  * import i18next from 'i18next';
267
- * import ContentStorageBackend from '@contentstorage/i18next-plugin';
267
+ * import ContentstorageBackend from '@contentstorage/i18next-plugin';
268
268
  *
269
269
  * i18next
270
- * .use(ContentStorageBackend)
270
+ * .use(ContentstorageBackend)
271
271
  * .init({
272
272
  * backend: {
273
273
  * contentKey: 'your-content-key',
@@ -276,7 +276,7 @@ function debugMemoryMap() {
276
276
  * });
277
277
  * ```
278
278
  */
279
- class ContentStorageBackend {
279
+ class ContentstorageBackend {
280
280
  constructor(_services, options, _i18nextOptions) {
281
281
  this.type = 'backend';
282
282
  this.isLiveMode = false;
@@ -441,40 +441,41 @@ class ContentStorageBackend {
441
441
  }
442
442
  }
443
443
  }
444
- ContentStorageBackend.type = 'backend';
444
+ ContentstorageBackend.type = 'backend';
445
445
  /**
446
- * Create a new instance of the ContentStorage backend
446
+ * Create a new instance of the Contentstorage backend
447
447
  */
448
- function createContentStorageBackend(options) {
449
- return new ContentStorageBackend(undefined, options);
448
+ function createContentstorageBackend(options) {
449
+ return new ContentstorageBackend(undefined, options);
450
450
  }
451
451
 
452
452
  /**
453
- * ContentStorage Post-Processor
453
+ * Contentstorage Live Editor Post-Processor
454
454
  *
455
- * This post-processor tracks translations at the point of resolution,
456
- * capturing the actual values returned by i18next including interpolations
457
- * and plural forms.
455
+ * This post-processor enables live editor functionality by tracking translations
456
+ * at the point of resolution, capturing the actual values returned by i18next
457
+ * including interpolations and plural forms.
458
458
  *
459
- * Use this in addition to or instead of the backend plugin for more
460
- * comprehensive tracking, especially for dynamic translations.
459
+ * Use this to enable click-to-edit functionality in the Contentstorage live editor.
460
+ * It works in addition to or instead of the backend plugin for more comprehensive
461
+ * tracking, especially for dynamic translations.
461
462
  *
462
463
  * @example
463
464
  * ```typescript
464
465
  * import i18next from 'i18next';
465
- * import { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';
466
+ * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';
466
467
  *
467
468
  * i18next
468
- * .use(new ContentStoragePostProcessor({ debug: true }))
469
+ * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))
469
470
  * .init({
470
- * // ... your config
471
+ * postProcess: ['contentstorage']
471
472
  * });
472
473
  * ```
473
474
  */
474
- class ContentStoragePostProcessor {
475
+ class ContentstorageLiveEditorPostProcessor {
475
476
  constructor(options = {}) {
476
477
  this.type = 'postProcessor';
477
- this.name = 'contentStorageTracker';
478
+ this.name = 'contentstorage';
478
479
  this.isLiveMode = false;
479
480
  this.options = {
480
481
  debug: false,
@@ -517,19 +518,19 @@ class ContentStoragePostProcessor {
517
518
  return value;
518
519
  }
519
520
  }
520
- ContentStoragePostProcessor.type = 'postProcessor';
521
+ ContentstorageLiveEditorPostProcessor.type = 'postProcessor';
521
522
  /**
522
- * Create a new instance of the ContentStorage post-processor
523
+ * Create a new instance of the Contentstorage Live Editor post-processor
523
524
  */
524
- function createContentStoragePostProcessor(options) {
525
- return new ContentStoragePostProcessor(options);
525
+ function createContentstorageLiveEditorPostProcessor(options) {
526
+ return new ContentstorageLiveEditorPostProcessor(options);
526
527
  }
527
528
 
528
- exports.ContentStorageBackend = ContentStorageBackend;
529
- exports.ContentStoragePostProcessor = ContentStoragePostProcessor;
530
- exports.createContentStorageBackend = createContentStorageBackend;
531
- exports.createContentStoragePostProcessor = createContentStoragePostProcessor;
529
+ exports.ContentstorageBackend = ContentstorageBackend;
530
+ exports.ContentstorageLiveEditorPostProcessor = ContentstorageLiveEditorPostProcessor;
531
+ exports.createContentstorageBackend = createContentstorageBackend;
532
+ exports.createContentstorageLiveEditorPostProcessor = createContentstorageLiveEditorPostProcessor;
532
533
  exports.debugMemoryMap = debugMemoryMap;
533
- exports.default = ContentStorageBackend;
534
+ exports.default = ContentstorageBackend;
534
535
  exports.loadLiveEditorScript = loadLiveEditorScript;
535
536
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/plugin.ts","../src/post-processor.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): 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 = '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 * 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 * 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 */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false\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 const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\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 });\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 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';\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\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 services and i18nextOptions for potential future use\n // Note: Currently not used but kept in signature for i18next compatibility\n void services;\n void 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).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 if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\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\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","import type { PostProcessorModule } from 'i18next';\nimport type { ContentStoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript } from './utils';\n\n/**\n * ContentStorage Post-Processor\n *\n * This post-processor tracks translations at the point of resolution,\n * capturing the actual values returned by i18next including interpolations\n * and plural forms.\n *\n * Use this in addition to or instead of the backend plugin for more\n * comprehensive tracking, especially for dynamic translations.\n *\n * @example\n * ```typescript\n * import i18next from 'i18next';\n * import { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';\n *\n * i18next\n * .use(new ContentStoragePostProcessor({ debug: true }))\n * .init({\n * // ... your config\n * });\n * ```\n */\nexport class ContentStoragePostProcessor implements PostProcessorModule {\n static type: 'postProcessor' = 'postProcessor';\n type: 'postProcessor' = 'postProcessor';\n name: string = 'contentStorageTracker';\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 // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n }\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\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Track the translation\n trackTranslation(\n value,\n translationKey,\n namespace,\n language,\n this.options.debug\n );\n\n return value;\n }\n}\n\n/**\n * Create a new instance of the ContentStorage post-processor\n */\nexport function createContentStoragePostProcessor(\n options?: ContentStoragePluginOptions\n): ContentStoragePostProcessor {\n return new ContentStoragePostProcessor(options);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils.ts","../src/plugin.ts","../src/post-processor.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): 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 = '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 * 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 * 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 */\nexport function trackTranslation(\n translationValue: string,\n translationKey: string,\n namespace?: string,\n language?: string,\n debug: boolean = false\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 const entry: MemoryMapEntry = {\n ids: idSet,\n type: 'text',\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 });\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 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';\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\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 services and i18nextOptions for potential future use\n // Note: Currently not used but kept in signature for i18next compatibility\n void services;\n void 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).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 if (this.options.debug) {\n console.log('[ContentStorage] Live editor mode enabled');\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\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","import type { PostProcessorModule } from 'i18next';\nimport type { ContentstoragePluginOptions } from './types';\nimport { trackTranslation, detectLiveEditorMode, initializeMemoryMap, loadLiveEditorScript } from './utils';\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 // Load the live editor script\n loadLiveEditorScript(2, 3000, this.options.debug);\n\n if (this.options.debug) {\n console.log('[ContentStorage] Post-processor initialized in live mode');\n }\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\n // Extract language\n const language = options?.lng || translator?.language;\n\n // Track the translation\n trackTranslation(\n value,\n translationKey,\n namespace,\n language,\n this.options.debug\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"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { BackendModule, ReadCallback, Services, InitOptions } from 'i18next';
2
- import type { ContentStoragePluginOptions } from './types';
2
+ import type { ContentstoragePluginOptions } from './types';
3
3
  /**
4
- * ContentStorage i18next Backend Plugin
4
+ * Contentstorage i18next Backend Plugin
5
5
  *
6
- * This plugin enables translation tracking for the ContentStorage live editor
6
+ * This plugin enables translation tracking for the Contentstorage live editor
7
7
  * by maintaining a memory map of translations and their keys.
8
8
  *
9
9
  * Features:
@@ -16,10 +16,10 @@ import type { ContentStoragePluginOptions } from './types';
16
16
  * @example
17
17
  * ```typescript
18
18
  * import i18next from 'i18next';
19
- * import ContentStorageBackend from '@contentstorage/i18next-plugin';
19
+ * import ContentstorageBackend from '@contentstorage/i18next-plugin';
20
20
  *
21
21
  * i18next
22
- * .use(ContentStorageBackend)
22
+ * .use(ContentstorageBackend)
23
23
  * .init({
24
24
  * backend: {
25
25
  * contentKey: 'your-content-key',
@@ -28,17 +28,17 @@ import type { ContentStoragePluginOptions } from './types';
28
28
  * });
29
29
  * ```
30
30
  */
31
- export declare class ContentStorageBackend implements BackendModule<ContentStoragePluginOptions> {
31
+ export declare class ContentstorageBackend implements BackendModule<ContentstoragePluginOptions> {
32
32
  static type: 'backend';
33
33
  type: 'backend';
34
34
  private options;
35
35
  private isLiveMode;
36
- constructor(_services?: Services, options?: ContentStoragePluginOptions, _i18nextOptions?: InitOptions);
36
+ constructor(_services?: Services, options?: ContentstoragePluginOptions, _i18nextOptions?: InitOptions);
37
37
  /**
38
38
  * Initialize the plugin
39
39
  * Called by i18next during initialization
40
40
  */
41
- init(services: Services, backendOptions?: ContentStoragePluginOptions, i18nextOptions?: InitOptions): void;
41
+ init(services: Services, backendOptions?: ContentstoragePluginOptions, i18nextOptions?: InitOptions): void;
42
42
  /**
43
43
  * Read translations for a given language and namespace
44
44
  * This is the main method called by i18next to load translations
@@ -66,8 +66,8 @@ export declare class ContentStorageBackend implements BackendModule<ContentStora
66
66
  private trackTranslations;
67
67
  }
68
68
  /**
69
- * Create a new instance of the ContentStorage backend
69
+ * Create a new instance of the Contentstorage backend
70
70
  */
71
- export declare function createContentStorageBackend(options?: ContentStoragePluginOptions): ContentStorageBackend;
72
- export default ContentStorageBackend;
71
+ export declare function createContentstorageBackend(options?: ContentstoragePluginOptions): ContentstorageBackend;
72
+ export default ContentstorageBackend;
73
73
  //# sourceMappingURL=plugin.d.ts.map
@@ -1,34 +1,35 @@
1
1
  import type { PostProcessorModule } from 'i18next';
2
- import type { ContentStoragePluginOptions } from './types';
2
+ import type { ContentstoragePluginOptions } from './types';
3
3
  /**
4
- * ContentStorage Post-Processor
4
+ * Contentstorage Live Editor Post-Processor
5
5
  *
6
- * This post-processor tracks translations at the point of resolution,
7
- * capturing the actual values returned by i18next including interpolations
8
- * and plural forms.
6
+ * This post-processor enables live editor functionality by tracking translations
7
+ * at the point of resolution, capturing the actual values returned by i18next
8
+ * including interpolations and plural forms.
9
9
  *
10
- * Use this in addition to or instead of the backend plugin for more
11
- * comprehensive tracking, especially for dynamic translations.
10
+ * Use this to enable click-to-edit functionality in the Contentstorage live editor.
11
+ * It works in addition to or instead of the backend plugin for more comprehensive
12
+ * tracking, especially for dynamic translations.
12
13
  *
13
14
  * @example
14
15
  * ```typescript
15
16
  * import i18next from 'i18next';
16
- * import { ContentStoragePostProcessor } from '@contentstorage/i18next-plugin';
17
+ * import { ContentstorageLiveEditorPostProcessor } from '@contentstorage/i18next-plugin';
17
18
  *
18
19
  * i18next
19
- * .use(new ContentStoragePostProcessor({ debug: true }))
20
+ * .use(new ContentstorageLiveEditorPostProcessor({ debug: true }))
20
21
  * .init({
21
- * // ... your config
22
+ * postProcess: ['contentstorage']
22
23
  * });
23
24
  * ```
24
25
  */
25
- export declare class ContentStoragePostProcessor implements PostProcessorModule {
26
+ export declare class ContentstorageLiveEditorPostProcessor implements PostProcessorModule {
26
27
  static type: 'postProcessor';
27
28
  type: 'postProcessor';
28
29
  name: string;
29
30
  private options;
30
31
  private isLiveMode;
31
- constructor(options?: ContentStoragePluginOptions);
32
+ constructor(options?: ContentstoragePluginOptions);
32
33
  /**
33
34
  * Process the translated value
34
35
  * Called by i18next after translation resolution
@@ -36,7 +37,7 @@ export declare class ContentStoragePostProcessor implements PostProcessorModule
36
37
  process(value: string, key: string | string[], options: any, translator: any): string;
37
38
  }
38
39
  /**
39
- * Create a new instance of the ContentStorage post-processor
40
+ * Create a new instance of the Contentstorage Live Editor post-processor
40
41
  */
41
- export declare function createContentStoragePostProcessor(options?: ContentStoragePluginOptions): ContentStoragePostProcessor;
42
+ export declare function createContentstorageLiveEditorPostProcessor(options?: ContentstoragePluginOptions): ContentstorageLiveEditorPostProcessor;
42
43
  //# sourceMappingURL=post-processor.d.ts.map
@@ -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;AAG3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,2BAA4B,YAAW,mBAAmB;IACrE,MAAM,CAAC,IAAI,EAAE,eAAe,CAAmB;IAC/C,IAAI,EAAE,eAAe,CAAmB;IACxC,IAAI,EAAE,MAAM,CAA2B;IAEvC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,UAAU,CAAkB;gBAExB,OAAO,GAAE,2BAAgC;IA0BrD;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,EACtB,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,GAAG,GACd,MAAM;CA8BV;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,CAAC,EAAE,2BAA2B,GACpC,2BAA2B,CAE7B"}
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;AAG3D;;;;;;;;;;;;;;;;;;;;;;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;IA0BrD;;;OAGG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,EACtB,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,GAAG,GACd,MAAM;CA8BV;AAED;;GAEG;AACH,wBAAgB,2CAA2C,CACzD,OAAO,CAAC,EAAE,2BAA2B,GACpC,qCAAqC,CAEvC"}
package/dist/types.d.ts CHANGED
@@ -22,16 +22,16 @@ export interface MemoryMapEntry {
22
22
  */
23
23
  export type MemoryMap = Map<string, MemoryMapEntry>;
24
24
  /**
25
- * Window interface extended with ContentStorage properties
25
+ * Window interface extended with Contentstorage properties
26
26
  */
27
- export interface ContentStorageWindow extends Window {
27
+ export interface ContentstorageWindow extends Window {
28
28
  memoryMap?: MemoryMap;
29
29
  __contentStorageDebug?: boolean;
30
30
  }
31
31
  /**
32
32
  * Plugin configuration options
33
33
  */
34
- export interface ContentStoragePluginOptions {
34
+ export interface ContentstoragePluginOptions {
35
35
  /**
36
36
  * Your ContentStorage content key
37
37
  * Used to construct CDN URLs for fetching translations
package/dist/utils.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import type { ContentStorageWindow, MemoryMap } from './types';
1
+ import type { ContentstorageWindow, MemoryMap } from './types';
2
2
  /**
3
3
  * Checks if the code is running in a browser environment
4
4
  */
5
5
  export declare function isBrowser(): boolean;
6
6
  /**
7
- * Gets the ContentStorage window object with type safety
7
+ * Gets the Contentstorage window object with type safety
8
8
  */
9
- export declare function getContentStorageWindow(): ContentStorageWindow | null;
9
+ export declare function getContentstorageWindow(): ContentstorageWindow | null;
10
10
  /**
11
11
  * Detects if the application is running in ContentStorage live editor mode
12
12
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstorage/i18next-plugin",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "i18next plugin for Contentstorage live editor translation tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",