@intlayer/cli 9.5.4 → 9.5.6

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
@@ -188,7 +188,8 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
188
188
  <li><a href="https://intlayer.org/doc/environment/create-react-app" rel=''>React CRA</a></li>
189
189
  <li><a href="https://intlayer.org/doc/environment/vite-and-react" rel=''>Vite + React</a></li>
190
190
  <li><a href="https://intlayer.org/doc/environment/vite-and-react" rel=''>Vite + React using Compiler</a></li>
191
- <li><a href="https://intlayer.org/doc/environment/vite-and-react/compiler" rel=''>React-router-v7</a></li>
191
+ <li><a href="https://intlayer.org/doc/environment/vite-and-react/react-router-v7" rel=''>React-router-v7</a></li>
192
+ <li><a href="https://intlayer.org/doc/environment/remix-3" rel=''>Remix 3</a></li>
192
193
  <li><a href="https://intlayer.org/doc/environment/tanstack-start" rel=''>Tanstack start</a>
193
194
  <ul>
194
195
  <li><a href="https://intlayer.org/doc/environment/tanstack-start/solid" rel=''>Solid</a></li>
@@ -200,7 +201,6 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
200
201
  <li><a href="https://intlayer.org/doc/environment/astro/vue" rel=''>Vue</a></li>
201
202
  <li><a href="https://intlayer.org/doc/environment/astro/svelte" rel=''>Svelte</a></li>
202
203
  <li><a href="https://intlayer.org/doc/environment/astro/solid" rel=''>Solid</a></li>
203
- <li><a href="https://intlayer.org/doc/environment/astro/vanilla" rel=''>Vanilla JS</a></li>
204
204
  <li><a href="https://intlayer.org/doc/environment/astro/lit" rel=''>Lit</a></li>
205
205
  </ul>
206
206
  </li>
@@ -48,7 +48,7 @@ const liveSync = async (options) => {
48
48
  appLogger("Failed to initialize IntlayerEventListener:", { level: "error" });
49
49
  appLogger(`Error: ${error instanceof Error ? error.message : String(error)}`, { level: "error" });
50
50
  }
51
- } else if (!configuration.editor.liveSync) appLogger(`Hot reload is ${(0, _intlayer_config_logger.colorize)("disabled", _intlayer_config_colors.RED)}. Please enable it in the configuration (editor.liveSync).`);
51
+ } else if (!configuration.editor.liveSync) appLogger(`Hot reload is ${(0, _intlayer_config_logger.colorize)("disabled", _intlayer_config_colors.RED)}. Please enable it in the configuration (${(0, _intlayer_config_logger.colorize)("editor.liveSync", _intlayer_config_colors.BLUE)}).`);
52
52
  else if (!configuration.editor.clientId || !configuration.editor.clientSecret) appLogger("Missing client credentials for hot reload. Please configure clientId and clientSecret");
53
53
  const server = (0, node_http.createServer)(async (req, res) => {
54
54
  if (req.method === "OPTIONS") {
@@ -1 +1 @@
1
- {"version":3,"file":"liveSync.cjs","names":["getAppLogger","buildDictionary","getConfiguration","runParallel","IntlayerEventListener","colorize","ANSIColors","createServer","getDictionaries","getLocalizedContent","getUnmergedDictionaries","packageJson"],"sources":["../../src/liveSync.ts"],"sourcesContent":["import { createServer } from 'node:http';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport packageJson from '@intlayer/config/package.json' with { type: 'json' };\nimport { getLocalizedContent } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/dictionaries-entry/unmerged';\nimport { buildDictionary } from '@intlayer/engine/build';\nimport { type ParallelHandle, runParallel } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { IntlayerEventListener } from './IntlayerEventListener';\n\ntype LiveSyncOptions = {\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let parallelProcess: ParallelHandle | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let _isHotReloadConnected = false;\n let _connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n _connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n _connectionStatus = 'connected';\n _isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n _connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n `Hot reload is ${colorize('disabled', ANSIColors.RED)}. Please enable it in the configuration (editor.liveSync).`\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries(configuration);\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n if (!key) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const dictionary = dictionaries[key] ?? null;\n\n if (!dictionary) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n if (locale) {\n // @ts-ignore Type instantiation is excessively deep and possibly infinite\n const sourceLocaleContent = getLocalizedContent(\n dictionary.content,\n locale,\n {\n dictionaryKey: key,\n keyPath: [],\n }\n );\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.with ? `\\x1b[90m${Array.isArray(options.with) ? options.with.join(' ') : options.with}\\x1b[0m` : '-'}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n if (parallelProcess) {\n parallelProcess.kill();\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"liveSync.cjs","names":["getAppLogger","buildDictionary","getConfiguration","runParallel","IntlayerEventListener","colorize","ANSIColors","createServer","getDictionaries","getLocalizedContent","getUnmergedDictionaries","packageJson"],"sources":["../../src/liveSync.ts"],"sourcesContent":["import { createServer } from 'node:http';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport packageJson from '@intlayer/config/package.json' with { type: 'json' };\nimport { getLocalizedContent } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/dictionaries-entry/unmerged';\nimport { buildDictionary } from '@intlayer/engine/build';\nimport { type ParallelHandle, runParallel } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { IntlayerEventListener } from './IntlayerEventListener';\n\ntype LiveSyncOptions = {\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let parallelProcess: ParallelHandle | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let _isHotReloadConnected = false;\n let _connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n _connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n _connectionStatus = 'connected';\n _isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n _connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n `Hot reload is ${colorize('disabled', ANSIColors.RED)}. Please enable it in the configuration (${colorize('editor.liveSync', ANSIColors.BLUE)}).`\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries(configuration);\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n if (!key) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const dictionary = dictionaries[key] ?? null;\n\n if (!dictionary) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n if (locale) {\n // @ts-ignore Type instantiation is excessively deep and possibly infinite\n const sourceLocaleContent = getLocalizedContent(\n dictionary.content,\n locale,\n {\n dictionaryKey: key,\n keyPath: [],\n }\n );\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.with ? `\\x1b[90m${Array.isArray(options.with) ? options.with.join(' ') : options.with}\\x1b[0m` : '-'}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n if (parallelProcess) {\n parallelProcess.kill();\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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"}
@@ -44,7 +44,7 @@ const liveSync = async (options) => {
44
44
  appLogger("Failed to initialize IntlayerEventListener:", { level: "error" });
45
45
  appLogger(`Error: ${error instanceof Error ? error.message : String(error)}`, { level: "error" });
46
46
  }
47
- } else if (!configuration.editor.liveSync) appLogger(`Hot reload is ${colorize("disabled", ANSIColors.RED)}. Please enable it in the configuration (editor.liveSync).`);
47
+ } else if (!configuration.editor.liveSync) appLogger(`Hot reload is ${colorize("disabled", ANSIColors.RED)}. Please enable it in the configuration (${colorize("editor.liveSync", ANSIColors.BLUE)}).`);
48
48
  else if (!configuration.editor.clientId || !configuration.editor.clientSecret) appLogger("Missing client credentials for hot reload. Please configure clientId and clientSecret");
49
49
  const server = createServer(async (req, res) => {
50
50
  if (req.method === "OPTIONS") {
@@ -1 +1 @@
1
- {"version":3,"file":"liveSync.mjs","names":[],"sources":["../../src/liveSync.ts"],"sourcesContent":["import { createServer } from 'node:http';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport packageJson from '@intlayer/config/package.json' with { type: 'json' };\nimport { getLocalizedContent } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/dictionaries-entry/unmerged';\nimport { buildDictionary } from '@intlayer/engine/build';\nimport { type ParallelHandle, runParallel } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { IntlayerEventListener } from './IntlayerEventListener';\n\ntype LiveSyncOptions = {\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let parallelProcess: ParallelHandle | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let _isHotReloadConnected = false;\n let _connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n _connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n _connectionStatus = 'connected';\n _isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n _connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n `Hot reload is ${colorize('disabled', ANSIColors.RED)}. Please enable it in the configuration (editor.liveSync).`\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries(configuration);\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n if (!key) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const dictionary = dictionaries[key] ?? null;\n\n if (!dictionary) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n if (locale) {\n // @ts-ignore Type instantiation is excessively deep and possibly infinite\n const sourceLocaleContent = getLocalizedContent(\n dictionary.content,\n locale,\n {\n dictionaryKey: key,\n keyPath: [],\n }\n );\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.with ? `\\x1b[90m${Array.isArray(options.with) ? options.with.join(' ') : options.with}\\x1b[0m` : '-'}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n if (parallelProcess) {\n parallelProcess.kill();\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"liveSync.mjs","names":[],"sources":["../../src/liveSync.ts"],"sourcesContent":["import { createServer } from 'node:http';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport packageJson from '@intlayer/config/package.json' with { type: 'json' };\nimport { getLocalizedContent } from '@intlayer/core/plugins';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/dictionaries-entry/unmerged';\nimport { buildDictionary } from '@intlayer/engine/build';\nimport { type ParallelHandle, runParallel } from '@intlayer/engine/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { IntlayerEventListener } from './IntlayerEventListener';\n\ntype LiveSyncOptions = {\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let parallelProcess: ParallelHandle | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let _isHotReloadConnected = false;\n let _connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n _connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n _connectionStatus = 'connected';\n _isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n _connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n _connectionStatus = 'error';\n _isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n `Hot reload is ${colorize('disabled', ANSIColors.RED)}. Please enable it in the configuration (${colorize('editor.liveSync', ANSIColors.BLUE)}).`\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries(configuration);\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n if (!key) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n const dictionary = dictionaries[key] ?? null;\n\n if (!dictionary) {\n res.writeHead(404);\n res.end('Not Found');\n return;\n }\n\n if (locale) {\n // @ts-ignore Type instantiation is excessively deep and possibly infinite\n const sourceLocaleContent = getLocalizedContent(\n dictionary.content,\n locale,\n {\n dictionaryKey: key,\n keyPath: [],\n }\n );\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.with ? `\\x1b[90m${Array.isArray(options.with) ? options.with.join(' ') : options.with}\\x1b[0m` : '-'}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n if (parallelProcess) {\n parallelProcess.kill();\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/cli",
3
- "version": "9.5.4",
3
+ "version": "9.5.6",
4
4
  "private": false,
5
5
  "description": "Provides uniform command-line interface scripts for Intlayer, used in packages like intlayer-cli and intlayer.",
6
6
  "keywords": [
@@ -68,20 +68,20 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@clack/prompts": "1.7.0",
71
- "@intlayer/api": "9.5.4",
72
- "@intlayer/babel": "9.5.4",
73
- "@intlayer/config": "9.5.4",
74
- "@intlayer/core": "9.5.4",
75
- "@intlayer/dictionaries-entry": "9.5.4",
76
- "@intlayer/engine": "9.5.4",
77
- "@intlayer/types": "9.5.4",
71
+ "@intlayer/api": "9.5.6",
72
+ "@intlayer/babel": "9.5.6",
73
+ "@intlayer/config": "9.5.6",
74
+ "@intlayer/core": "9.5.6",
75
+ "@intlayer/dictionaries-entry": "9.5.6",
76
+ "@intlayer/engine": "9.5.6",
77
+ "@intlayer/types": "9.5.6",
78
78
  "commander": "15.0.0",
79
79
  "enquirer": "2.4.1",
80
80
  "eventsource": "5.1.1",
81
81
  "fast-glob": "3.3.3"
82
82
  },
83
83
  "devDependencies": {
84
- "@intlayer/ai": "9.5.4",
84
+ "@intlayer/ai": "9.5.6",
85
85
  "@types/node": "^22",
86
86
  "@utils/ts-config": "1.0.4",
87
87
  "@utils/ts-config-types": "1.0.4",
@@ -92,7 +92,7 @@
92
92
  "vitest": "5.0.1"
93
93
  },
94
94
  "peerDependencies": {
95
- "@intlayer/ai": "9.5.4"
95
+ "@intlayer/ai": "9.5.6"
96
96
  },
97
97
  "peerDependenciesMeta": {
98
98
  "@intlayer/ai": {