@lingo.dev/compiler 0.3.10 → 0.3.12
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/build/metadata/manager.cjs +7 -4
- package/build/metadata/manager.mjs +6 -3
- package/build/metadata/manager.mjs.map +1 -1
- package/build/plugin/next.cjs +4 -1
- package/build/plugin/next.mjs +4 -1
- package/build/plugin/next.mjs.map +1 -1
- package/build/react/server/ServerLingoProvider.d.cts +2 -2
- package/build/react/shared/LingoContext.d.mts +0 -1
- package/build/react/shared/LingoContext.d.mts.map +1 -1
- package/build/react/shared/LingoProvider.d.mts +2 -2
- package/build/react/shared/LocaleSwitcher.d.cts +2 -2
- package/build/react/shared/LocaleSwitcher.d.mts +2 -2
- package/build/types.d.cts +3 -0
- package/build/types.d.cts.map +1 -1
- package/build/types.d.mts +3 -0
- package/build/types.d.mts.map +1 -1
- package/build/utils/config-factory.cjs +18 -9
- package/build/utils/config-factory.mjs +18 -9
- package/build/utils/config-factory.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -5,7 +5,6 @@ let path = require("path");
|
|
|
5
5
|
path = require_rolldown_runtime.__toESM(path);
|
|
6
6
|
let fs = require("fs");
|
|
7
7
|
fs = require_rolldown_runtime.__toESM(fs);
|
|
8
|
-
let lmdb = require("lmdb");
|
|
9
8
|
|
|
10
9
|
//#region src/metadata/manager.ts
|
|
11
10
|
const METADATA_DIR_DEV = "metadata-dev";
|
|
@@ -15,11 +14,15 @@ const METADATA_DIR_BUILD = "metadata-build";
|
|
|
15
14
|
*
|
|
16
15
|
* lmdb-js deduplicates open() calls to the same path (ref-counted at C++ level),
|
|
17
16
|
* so this is cheap. Each open() also clears stale readers from terminated workers.
|
|
17
|
+
*
|
|
18
|
+
* lmdb is loaded via dynamic import() to prevent bundlers and require hooks
|
|
19
|
+
* from transforming its CJS bundle, which contains syntax they can't handle.
|
|
18
20
|
*/
|
|
19
|
-
function openDatabaseConnection(dbPath, noSync) {
|
|
21
|
+
async function openDatabaseConnection(dbPath, noSync) {
|
|
20
22
|
try {
|
|
21
23
|
fs.default.mkdirSync(dbPath, { recursive: true });
|
|
22
|
-
|
|
24
|
+
const { open } = await import("lmdb");
|
|
25
|
+
return open({
|
|
23
26
|
path: dbPath,
|
|
24
27
|
compression: true,
|
|
25
28
|
noSync
|
|
@@ -45,7 +48,7 @@ async function closeDatabaseConnection(db, dbPath) {
|
|
|
45
48
|
* is closed afterwards.
|
|
46
49
|
*/
|
|
47
50
|
async function runWithDbConnection(dbPath, noSync, fn) {
|
|
48
|
-
const db = openDatabaseConnection(dbPath, noSync);
|
|
51
|
+
const db = await openDatabaseConnection(dbPath, noSync);
|
|
49
52
|
try {
|
|
50
53
|
return fn(db);
|
|
51
54
|
} finally {
|
|
@@ -2,7 +2,6 @@ import { logger } from "../utils/logger.mjs";
|
|
|
2
2
|
import { getLingoDir } from "../utils/path-helpers.mjs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
|
-
import { open } from "lmdb";
|
|
6
5
|
|
|
7
6
|
//#region src/metadata/manager.ts
|
|
8
7
|
const METADATA_DIR_DEV = "metadata-dev";
|
|
@@ -12,10 +11,14 @@ const METADATA_DIR_BUILD = "metadata-build";
|
|
|
12
11
|
*
|
|
13
12
|
* lmdb-js deduplicates open() calls to the same path (ref-counted at C++ level),
|
|
14
13
|
* so this is cheap. Each open() also clears stale readers from terminated workers.
|
|
14
|
+
*
|
|
15
|
+
* lmdb is loaded via dynamic import() to prevent bundlers and require hooks
|
|
16
|
+
* from transforming its CJS bundle, which contains syntax they can't handle.
|
|
15
17
|
*/
|
|
16
|
-
function openDatabaseConnection(dbPath, noSync) {
|
|
18
|
+
async function openDatabaseConnection(dbPath, noSync) {
|
|
17
19
|
try {
|
|
18
20
|
fs.mkdirSync(dbPath, { recursive: true });
|
|
21
|
+
const { open } = await import("lmdb");
|
|
19
22
|
return open({
|
|
20
23
|
path: dbPath,
|
|
21
24
|
compression: true,
|
|
@@ -42,7 +45,7 @@ async function closeDatabaseConnection(db, dbPath) {
|
|
|
42
45
|
* is closed afterwards.
|
|
43
46
|
*/
|
|
44
47
|
async function runWithDbConnection(dbPath, noSync, fn) {
|
|
45
|
-
const db = openDatabaseConnection(dbPath, noSync);
|
|
48
|
+
const db = await openDatabaseConnection(dbPath, noSync);
|
|
46
49
|
try {
|
|
47
50
|
return fn(db);
|
|
48
51
|
} finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.mjs","names":["entries: MetadataSchema"],"sources":["../../src/metadata/manager.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport {
|
|
1
|
+
{"version":3,"file":"manager.mjs","names":["entries: MetadataSchema"],"sources":["../../src/metadata/manager.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport type { RootDatabase } from \"lmdb\";\nimport type { MetadataSchema, PathConfig, TranslationEntry } from \"../types\";\nimport { getLingoDir } from \"../utils/path-helpers\";\nimport { logger } from \"../utils/logger\";\n\nconst METADATA_DIR_DEV = \"metadata-dev\";\nconst METADATA_DIR_BUILD = \"metadata-build\";\n\n/**\n * Opens an LMDB connection for a single operation.\n *\n * lmdb-js deduplicates open() calls to the same path (ref-counted at C++ level),\n * so this is cheap. Each open() also clears stale readers from terminated workers.\n *\n * lmdb is loaded via dynamic import() to prevent bundlers and require hooks\n * from transforming its CJS bundle, which contains syntax they can't handle.\n */\nasync function openDatabaseConnection(dbPath: string, noSync: boolean): Promise<RootDatabase> {\n try {\n fs.mkdirSync(dbPath, { recursive: true });\n const { open } = await import(\"lmdb\");\n return open({\n path: dbPath,\n compression: true,\n noSync,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to open LMDB at ${dbPath}: ${message}`);\n }\n}\n\n/**\n * Closes the LMDB connection. Also prevents EBUSY/EPERM on Windows during\n * directory cleanup.\n */\nasync function closeDatabaseConnection(\n db: RootDatabase,\n dbPath: string,\n): Promise<void> {\n try {\n await db.close();\n } catch (e) {\n logger.debug(`Error closing database at ${dbPath}: ${e}`);\n }\n}\n\n/**\n * Opens a database connection, runs the callback, and ensures the connection\n * is closed afterwards.\n */\nasync function runWithDbConnection<T>(\n dbPath: string,\n noSync: boolean,\n fn: (db: RootDatabase) => T,\n): Promise<T> {\n const db = await openDatabaseConnection(dbPath, noSync);\n try {\n return fn(db);\n } finally {\n await closeDatabaseConnection(db, dbPath);\n }\n}\n\nfunction readEntriesFromDb(db: RootDatabase): MetadataSchema {\n const entries: MetadataSchema = {};\n\n for (const { key, value } of db.getRange()) {\n entries[key as string] = value as TranslationEntry;\n }\n\n return entries;\n}\n\nexport async function loadMetadata(\n dbPath: string,\n noSync = false,\n): Promise<MetadataSchema> {\n return runWithDbConnection(dbPath, noSync, readEntriesFromDb);\n}\n\n/**\n * Persists translation entries to LMDB in a single atomic transaction.\n */\nexport async function saveMetadata(\n dbPath: string,\n entries: TranslationEntry[],\n noSync = false,\n): Promise<void> {\n return runWithDbConnection(dbPath, noSync, (db) => {\n db.transactionSync(() => {\n for (const entry of entries) {\n db.putSync(entry.hash, entry);\n }\n });\n });\n}\n\nexport function cleanupExistingMetadata(metadataDbPath: string): void {\n logger.debug(`Cleaning up metadata database: ${metadataDbPath}`);\n\n try {\n fs.rmSync(metadataDbPath, { recursive: true, force: true });\n logger.info(`🧹 Cleaned up metadata database: ${metadataDbPath}`);\n } catch (error) {\n const code =\n error instanceof Error && \"code\" in error\n ? (error as NodeJS.ErrnoException).code\n : undefined;\n const message = error instanceof Error ? error.message : String(error);\n\n if (code === \"ENOENT\") {\n logger.debug(\n `Metadata database already deleted or doesn't exist: ${metadataDbPath}`,\n );\n return;\n }\n\n logger.warn(`Failed to cleanup metadata database: ${message}`);\n }\n}\n\nexport function getMetadataPath(config: PathConfig): string {\n const dirname =\n config.environment === \"development\"\n ? METADATA_DIR_DEV\n : METADATA_DIR_BUILD;\n return path.join(getLingoDir(config), dirname);\n}\n"],"mappings":";;;;;;AAOA,MAAM,mBAAmB;AACzB,MAAM,qBAAqB;;;;;;;;;;AAW3B,eAAe,uBAAuB,QAAgB,QAAwC;AAC5F,KAAI;AACF,KAAG,UAAU,QAAQ,EAAE,WAAW,MAAM,CAAC;EACzC,MAAM,EAAE,SAAS,MAAM,OAAO;AAC9B,SAAO,KAAK;GACV,MAAM;GACN,aAAa;GACb;GACD,CAAC;UACK,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAM,IAAI,MAAM,0BAA0B,OAAO,IAAI,UAAU;;;;;;;AAQnE,eAAe,wBACb,IACA,QACe;AACf,KAAI;AACF,QAAM,GAAG,OAAO;UACT,GAAG;AACV,SAAO,MAAM,6BAA6B,OAAO,IAAI,IAAI;;;;;;;AAQ7D,eAAe,oBACb,QACA,QACA,IACY;CACZ,MAAM,KAAK,MAAM,uBAAuB,QAAQ,OAAO;AACvD,KAAI;AACF,SAAO,GAAG,GAAG;WACL;AACR,QAAM,wBAAwB,IAAI,OAAO;;;AAI7C,SAAS,kBAAkB,IAAkC;CAC3D,MAAMA,UAA0B,EAAE;AAElC,MAAK,MAAM,EAAE,KAAK,WAAW,GAAG,UAAU,CACxC,SAAQ,OAAiB;AAG3B,QAAO;;AAGT,eAAsB,aACpB,QACA,SAAS,OACgB;AACzB,QAAO,oBAAoB,QAAQ,QAAQ,kBAAkB;;;;;AAM/D,eAAsB,aACpB,QACA,SACA,SAAS,OACM;AACf,QAAO,oBAAoB,QAAQ,SAAS,OAAO;AACjD,KAAG,sBAAsB;AACvB,QAAK,MAAM,SAAS,QAClB,IAAG,QAAQ,MAAM,MAAM,MAAM;IAE/B;GACF;;AAGJ,SAAgB,wBAAwB,gBAA8B;AACpE,QAAO,MAAM,kCAAkC,iBAAiB;AAEhE,KAAI;AACF,KAAG,OAAO,gBAAgB;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AAC3D,SAAO,KAAK,oCAAoC,iBAAiB;UAC1D,OAAO;EACd,MAAM,OACJ,iBAAiB,SAAS,UAAU,QAC/B,MAAgC,OACjC;EACN,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAEtE,MAAI,SAAS,UAAU;AACrB,UAAO,MACL,uDAAuD,iBACxD;AACD;;AAGF,SAAO,KAAK,wCAAwC,UAAU;;;AAIlE,SAAgB,gBAAgB,QAA4B;CAC1D,MAAM,UACJ,OAAO,gBAAgB,gBACnB,mBACA;AACN,QAAO,KAAK,KAAK,YAAY,OAAO,EAAE,QAAQ"}
|
package/build/plugin/next.cjs
CHANGED
|
@@ -133,7 +133,10 @@ async function withLingo(nextConfig = {}, lingoOptions) {
|
|
|
133
133
|
let metadataFilePath = require_manager.getMetadataPath(lingoConfig);
|
|
134
134
|
const isDev = lingoConfig.environment === "development";
|
|
135
135
|
require_logger.logger.debug(`Initializing Lingo.dev compiler. Is dev mode: ${isDev}. Is main runner: ${isMainRunner()}`);
|
|
136
|
-
if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) {
|
|
136
|
+
if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) if (lingoConfig.dev.translationServerUrl) {
|
|
137
|
+
require_logger.logger.info(`Using existing translation server URL (${lingoConfig.dev.translationServerUrl}) from config`);
|
|
138
|
+
process.env.LINGO_TRANSLATION_SERVER_URL = lingoConfig.dev.translationServerUrl;
|
|
139
|
+
} else {
|
|
137
140
|
const translationServer = await require_translation_server.startOrGetTranslationServer({
|
|
138
141
|
translationService: new require_translation_service.TranslationService(lingoConfig, require_logger.logger),
|
|
139
142
|
onError: (err) => {
|
package/build/plugin/next.mjs
CHANGED
|
@@ -134,7 +134,10 @@ async function withLingo(nextConfig = {}, lingoOptions) {
|
|
|
134
134
|
let metadataFilePath = getMetadataPath(lingoConfig);
|
|
135
135
|
const isDev = lingoConfig.environment === "development";
|
|
136
136
|
logger.debug(`Initializing Lingo.dev compiler. Is dev mode: ${isDev}. Is main runner: ${isMainRunner()}`);
|
|
137
|
-
if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) {
|
|
137
|
+
if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) if (lingoConfig.dev.translationServerUrl) {
|
|
138
|
+
logger.info(`Using existing translation server URL (${lingoConfig.dev.translationServerUrl}) from config`);
|
|
139
|
+
process.env.LINGO_TRANSLATION_SERVER_URL = lingoConfig.dev.translationServerUrl;
|
|
140
|
+
} else {
|
|
138
141
|
const translationServer = await startOrGetTranslationServer({
|
|
139
142
|
translationService: new TranslationService(lingoConfig, logger),
|
|
140
143
|
onError: (err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next.mjs","names":["turbopackConfig: Partial<NextConfig>","webpack: NextJsWebpackConfig"],"sources":["../../src/plugin/next.ts"],"sourcesContent":["import type { NextConfig } from \"next\";\nimport type {\n NextJsWebpackConfig,\n TurbopackOptions,\n WebpackConfigContext,\n} from \"next/dist/server/config-shared\";\nimport { createLingoConfig } from \"../utils/config-factory\";\nimport { logger } from \"../utils/logger\";\nimport type { LingoConfig, PartialLingoConfig } from \"../types\";\nimport { processBuildTranslations } from \"./build-translator\";\nimport { startOrGetTranslationServer } from \"../translation-server/translation-server\";\nimport { cleanupExistingMetadata, getMetadataPath } from \"../metadata/manager\";\nimport { registerCleanupOnCurrentProcess } from \"./cleanup\";\nimport { useI18nRegex } from \"./transform/use-i18n\";\nimport { TranslationService } from \"../translators\";\n\nexport type LingoNextPluginOptions = PartialLingoConfig;\n\ntype RuleKey = \"compiler\" | \"devConfig\" | \"localeServer\" | \"localeClient\";\n\nfunction loaders({\n lingoConfig,\n metadataFilePath,\n translationServerUrl,\n}: {\n lingoConfig: LingoConfig;\n metadataFilePath: string;\n translationServerUrl?: string;\n}): Record<RuleKey, { turbopack?: any; webpack?: any }> {\n const common = {\n sourceRoot: lingoConfig.sourceRoot,\n lingoDir: lingoConfig.lingoDir,\n sourceLocale: lingoConfig.sourceLocale,\n };\n\n // TODO (AleksandrSl 14/12/2025): Type options.\n const compilerLoader = {\n loader: \"@lingo.dev/compiler/next-compiler-loader\",\n options: {\n ...common,\n useDirective: lingoConfig.useDirective,\n metadataFilePath,\n },\n };\n\n const configLoader = {\n loader: \"@lingo.dev/compiler/next-config-loader\",\n options: {\n ...common,\n dev: {\n translationServerUrl,\n ...lingoConfig.dev,\n },\n },\n };\n const localeServerLoader = {\n loader: \"@lingo.dev/compiler/next-locale-server-loader\",\n options: {\n ...common,\n localePersistence: lingoConfig.localePersistence,\n },\n };\n\n const localeClientLoader = {\n loader: \"@lingo.dev/compiler/next-locale-client-loader\",\n options: {\n ...common,\n localePersistence: lingoConfig.localePersistence,\n },\n };\n\n return {\n compiler: {\n turbopack: {\n pattern: \"*.{tsx,jsx}\",\n config: {\n condition: {\n content: lingoConfig.useDirective ? useI18nRegex : undefined,\n },\n loaders: [compilerLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /\\.(tsx|jsx)$/i,\n exclude: /node_modules/,\n use: [compilerLoader],\n },\n },\n\n devConfig: translationServerUrl\n ? {\n turbopack: {\n pattern: \"**/virtual/config.mjs\",\n config: {\n loaders: [configLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/config\\.mjs$/i,\n use: [configLoader],\n },\n }\n : {},\n\n localeServer: {\n turbopack: {\n pattern: \"**/virtual/locale/server.mjs\",\n config: {\n loaders: [localeServerLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/locale[\\\\/]server\\.mjs$/i,\n use: [localeServerLoader],\n },\n },\n\n localeClient: {\n turbopack: {\n pattern: \"**/virtual/locale/client.mjs\",\n config: {\n loaders: [localeClientLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/locale[\\\\/]client\\.mjs$/i,\n use: [localeClientLoader],\n },\n },\n };\n}\n\n/**\n * Check if Next.js supports stable turbopack config (Next.js 16+)\n */\nfunction hasStableTurboConfig(): boolean {\n try {\n const nextPackage = require(\"next/package.json\");\n const majorVersion = parseInt(nextPackage.version.split(\".\")[0], 10);\n return majorVersion >= 16;\n } catch {\n return false;\n }\n}\n\nfunction getTurbopackConfig(userConfig: NextConfig): TurbopackOptions {\n return (\n (hasStableTurboConfig()\n ? userConfig?.turbopack?.rules\n : // @ts-expect-error - experimental.turbo for Next.js <16\n userConfig?.experimental?.turbo) || {}\n );\n}\n\n/**\n * Merge Turbopack rules without mutating original\n */\nfunction mergeTurbopackRules(\n existingRules: Record<string, any>,\n newRules: ({ pattern: string; config: any } | undefined)[],\n): Record<string, any> {\n const mergedRules = { ...existingRules };\n\n for (const newRule of newRules) {\n if (!newRule) continue;\n const { pattern, config } = newRule;\n\n if (mergedRules[pattern]) {\n if (Array.isArray(mergedRules[pattern])) {\n mergedRules[pattern] = [...mergedRules[pattern], config];\n } else {\n mergedRules[pattern] = [mergedRules[pattern], config];\n }\n } else {\n mergedRules[pattern] = config;\n }\n }\n\n return mergedRules;\n}\n\n// Next read config several times. Once in the main runner,\n// and ~ twice in the build workers which cannot get the config otherwise, because it's not serializable.\n// Workers start in separate processed by get most of the env from the main loader\nfunction isMainRunner() {\n return (\n !process.env.NEXT_PRIVATE_BUILD_WORKER &&\n !process.env.IS_NEXT_WORKER &&\n !process.env.NEXT_PRIVATE_WORKER\n );\n}\n\nexport async function withLingo(\n nextConfig: NextConfig = {},\n lingoOptions: LingoNextPluginOptions,\n): Promise<NextConfig> {\n const lingoConfig = createLingoConfig(lingoOptions);\n let metadataFilePath = getMetadataPath(lingoConfig);\n const isDev = lingoConfig.environment === \"development\";\n\n logger.debug(\n `Initializing Lingo.dev compiler. Is dev mode: ${isDev}. Is main runner: ${isMainRunner()}`,\n );\n\n // Try to start up the translation server once.\n // We have two barriers, a simple one here and a more complex one inside the startTranslationServer which doesn't start the server if it can find one running.\n // We do not use isMainRunner here, because we need to start the server as early as possible, so the loaders get the translation server url. The main runner in dev mode runs after a dev server process is started.\n if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) {\n const translationServer = await startOrGetTranslationServer({\n translationService: new TranslationService(lingoConfig, logger),\n onError: (err) => {\n logger.error(\"Translation server error:\", err);\n },\n onReady: (port) => {\n logger.info(`Translation server started successfully on port: ${port}`);\n },\n config: lingoConfig,\n });\n process.env.LINGO_TRANSLATION_SERVER_URL = translationServer.url;\n if (translationServer.server) {\n // We start the server in the same process, so we should be fine without any sync cleanup. Server should be killed with the process.\n registerCleanupOnCurrentProcess({\n asyncCleanup: async () => {\n await translationServer.server.stop();\n },\n });\n }\n }\n\n const translationServerUrl = process.env.LINGO_TRANSLATION_SERVER_URL;\n\n if (isMainRunner()) {\n // We need to cleaup the file only once, to avoid having extra translation introduced into the build, or old translation to pile up.\n cleanupExistingMetadata(metadataFilePath);\n\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n }\n\n const existingTurbopackConfig = getTurbopackConfig(nextConfig);\n let mergedRules = mergeTurbopackRules(\n existingTurbopackConfig.rules ?? {},\n Object.values(\n loaders({ lingoConfig, metadataFilePath, translationServerUrl }),\n ).map((rules) => rules.turbopack),\n );\n\n const existingResolveAlias = existingTurbopackConfig.resolveAlias;\n const mergedResolveAlias = {\n ...existingResolveAlias,\n // TODO (AleksandrSl 08/12/2025): Describe what have to be done to support custom resolvers\n };\n\n let turbopackConfig: Partial<NextConfig>;\n if (hasStableTurboConfig()) {\n turbopackConfig = {\n turbopack: {\n ...nextConfig.turbopack, // Preserve existing turbopack options\n rules: mergedRules,\n resolveAlias: mergedResolveAlias,\n },\n };\n } else {\n turbopackConfig = {\n experimental: {\n ...nextConfig.experimental, // Preserve ALL experimental options\n // @ts-expect-error - turbo for Next.js <16\n turbo: {\n // @ts-expect-error - turbo for Next.js <16\n ...nextConfig.experimental?.turbo, // Preserve existing turbo options\n rules: mergedRules,\n resolveAlias: mergedResolveAlias,\n },\n },\n };\n }\n\n const runAfterProductionCompile = async ({\n distDir,\n projectDir,\n }: {\n distDir: string;\n projectDir: string;\n }) => {\n if (typeof nextConfig.compiler?.runAfterProductionCompile === \"function\") {\n await nextConfig.compiler.runAfterProductionCompile({\n distDir,\n projectDir,\n });\n }\n\n logger.info(\"Running post-build translation generation...\");\n\n try {\n await processBuildTranslations({\n config: lingoConfig,\n publicOutputPath: distDir,\n metadataFilePath,\n });\n } catch (error) {\n logger.error(\n \"Translation generation failed:\",\n error instanceof Error ? error.message : error,\n );\n throw error;\n }\n };\n\n const webpack: NextJsWebpackConfig = (\n config: any,\n options: WebpackConfigContext,\n ) => {\n // Apply user's webpack config first if it exists\n let modifiedConfig = config;\n if (typeof nextConfig.webpack === \"function\") {\n modifiedConfig = nextConfig.webpack(config, options);\n }\n\n const lingoRules = Object.values(\n loaders({ lingoConfig, metadataFilePath, translationServerUrl }),\n )\n .map((rules) => rules.webpack)\n .filter(Boolean);\n\n // I tried using plugin from unplugin, but with all the loaders stuff it works poorly.\n // Failing with weird errors which appear on the later compilations, probably something with the cache and virtual modules\n modifiedConfig.module.rules.unshift(...lingoRules);\n\n return modifiedConfig;\n };\n\n return {\n ...nextConfig,\n ...turbopackConfig,\n compiler: {\n ...nextConfig.compiler,\n runAfterProductionCompile,\n },\n webpack,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"next.mjs","names":["turbopackConfig: Partial<NextConfig>","webpack: NextJsWebpackConfig"],"sources":["../../src/plugin/next.ts"],"sourcesContent":["import type { NextConfig } from \"next\";\nimport type {\n NextJsWebpackConfig,\n TurbopackOptions,\n WebpackConfigContext,\n} from \"next/dist/server/config-shared\";\nimport { createLingoConfig } from \"../utils/config-factory\";\nimport { logger } from \"../utils/logger\";\nimport type { LingoConfig, PartialLingoConfig } from \"../types\";\nimport { processBuildTranslations } from \"./build-translator\";\nimport { startOrGetTranslationServer } from \"../translation-server/translation-server\";\nimport { cleanupExistingMetadata, getMetadataPath } from \"../metadata/manager\";\nimport { registerCleanupOnCurrentProcess } from \"./cleanup\";\nimport { useI18nRegex } from \"./transform/use-i18n\";\nimport { TranslationService } from \"../translators\";\n\nexport type LingoNextPluginOptions = PartialLingoConfig;\n\ntype RuleKey = \"compiler\" | \"devConfig\" | \"localeServer\" | \"localeClient\";\n\nfunction loaders({\n lingoConfig,\n metadataFilePath,\n translationServerUrl,\n}: {\n lingoConfig: LingoConfig;\n metadataFilePath: string;\n translationServerUrl?: string;\n}): Record<RuleKey, { turbopack?: any; webpack?: any }> {\n const common = {\n sourceRoot: lingoConfig.sourceRoot,\n lingoDir: lingoConfig.lingoDir,\n sourceLocale: lingoConfig.sourceLocale,\n };\n\n // TODO (AleksandrSl 14/12/2025): Type options.\n const compilerLoader = {\n loader: \"@lingo.dev/compiler/next-compiler-loader\",\n options: {\n ...common,\n useDirective: lingoConfig.useDirective,\n metadataFilePath,\n },\n };\n\n const configLoader = {\n loader: \"@lingo.dev/compiler/next-config-loader\",\n options: {\n ...common,\n dev: {\n translationServerUrl,\n ...lingoConfig.dev,\n },\n },\n };\n const localeServerLoader = {\n loader: \"@lingo.dev/compiler/next-locale-server-loader\",\n options: {\n ...common,\n localePersistence: lingoConfig.localePersistence,\n },\n };\n\n const localeClientLoader = {\n loader: \"@lingo.dev/compiler/next-locale-client-loader\",\n options: {\n ...common,\n localePersistence: lingoConfig.localePersistence,\n },\n };\n\n return {\n compiler: {\n turbopack: {\n pattern: \"*.{tsx,jsx}\",\n config: {\n condition: {\n content: lingoConfig.useDirective ? useI18nRegex : undefined,\n },\n loaders: [compilerLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /\\.(tsx|jsx)$/i,\n exclude: /node_modules/,\n use: [compilerLoader],\n },\n },\n\n devConfig: translationServerUrl\n ? {\n turbopack: {\n pattern: \"**/virtual/config.mjs\",\n config: {\n loaders: [configLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/config\\.mjs$/i,\n use: [configLoader],\n },\n }\n : {},\n\n localeServer: {\n turbopack: {\n pattern: \"**/virtual/locale/server.mjs\",\n config: {\n loaders: [localeServerLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/locale[\\\\/]server\\.mjs$/i,\n use: [localeServerLoader],\n },\n },\n\n localeClient: {\n turbopack: {\n pattern: \"**/virtual/locale/client.mjs\",\n config: {\n loaders: [localeClientLoader],\n },\n },\n webpack: {\n enforce: \"pre\",\n test: /virtual\\/locale[\\\\/]client\\.mjs$/i,\n use: [localeClientLoader],\n },\n },\n };\n}\n\n/**\n * Check if Next.js supports stable turbopack config (Next.js 16+)\n */\nfunction hasStableTurboConfig(): boolean {\n try {\n const nextPackage = require(\"next/package.json\");\n const majorVersion = parseInt(nextPackage.version.split(\".\")[0], 10);\n return majorVersion >= 16;\n } catch {\n return false;\n }\n}\n\nfunction getTurbopackConfig(userConfig: NextConfig): TurbopackOptions {\n return (\n (hasStableTurboConfig()\n ? userConfig?.turbopack?.rules\n : // @ts-expect-error - experimental.turbo for Next.js <16\n userConfig?.experimental?.turbo) || {}\n );\n}\n\n/**\n * Merge Turbopack rules without mutating original\n */\nfunction mergeTurbopackRules(\n existingRules: Record<string, any>,\n newRules: ({ pattern: string; config: any } | undefined)[],\n): Record<string, any> {\n const mergedRules = { ...existingRules };\n\n for (const newRule of newRules) {\n if (!newRule) continue;\n const { pattern, config } = newRule;\n\n if (mergedRules[pattern]) {\n if (Array.isArray(mergedRules[pattern])) {\n mergedRules[pattern] = [...mergedRules[pattern], config];\n } else {\n mergedRules[pattern] = [mergedRules[pattern], config];\n }\n } else {\n mergedRules[pattern] = config;\n }\n }\n\n return mergedRules;\n}\n\n// Next read config several times. Once in the main runner,\n// and ~ twice in the build workers which cannot get the config otherwise, because it's not serializable.\n// Workers start in separate processed by get most of the env from the main loader\nfunction isMainRunner() {\n return (\n !process.env.NEXT_PRIVATE_BUILD_WORKER &&\n !process.env.IS_NEXT_WORKER &&\n !process.env.NEXT_PRIVATE_WORKER\n );\n}\n\nexport async function withLingo(\n nextConfig: NextConfig = {},\n lingoOptions: LingoNextPluginOptions,\n): Promise<NextConfig> {\n const lingoConfig = createLingoConfig(lingoOptions);\n let metadataFilePath = getMetadataPath(lingoConfig);\n const isDev = lingoConfig.environment === \"development\";\n\n logger.debug(\n `Initializing Lingo.dev compiler. Is dev mode: ${isDev}. Is main runner: ${isMainRunner()}`,\n );\n\n // Try to start up the translation server once.\n // We have two barriers, a simple one here and a more complex one inside the startTranslationServer which doesn't start the server if it can find one running.\n // We do not use isMainRunner here, because we need to start the server as early as possible, so the loaders get the translation server url. The main runner in dev mode runs after a dev server process is started.\n if (isDev && !process.env.LINGO_TRANSLATION_SERVER_URL) {\n if (lingoConfig.dev.translationServerUrl) {\n logger.info(`Using existing translation server URL (${lingoConfig.dev.translationServerUrl}) from config`);\n process.env.LINGO_TRANSLATION_SERVER_URL =\n lingoConfig.dev.translationServerUrl;\n } else {\n const translationServer = await startOrGetTranslationServer({\n translationService: new TranslationService(lingoConfig, logger),\n onError: (err) => {\n logger.error(\"Translation server error:\", err);\n },\n onReady: (port) => {\n logger.info(\n `Translation server started successfully on port: ${port}`,\n );\n },\n config: lingoConfig,\n });\n process.env.LINGO_TRANSLATION_SERVER_URL = translationServer.url;\n if (translationServer.server) {\n // We start the server in the same process, so we should be fine without any sync cleanup. Server should be killed with the process.\n registerCleanupOnCurrentProcess({\n asyncCleanup: async () => {\n await translationServer.server.stop();\n },\n });\n }\n }\n }\n\n const translationServerUrl = process.env.LINGO_TRANSLATION_SERVER_URL;\n\n if (isMainRunner()) {\n // We need to clean up the file only once to avoid having extra translation introduced into the build, or old translation to pile up.\n cleanupExistingMetadata(metadataFilePath);\n\n registerCleanupOnCurrentProcess({\n cleanup: () => cleanupExistingMetadata(metadataFilePath),\n });\n }\n\n const existingTurbopackConfig = getTurbopackConfig(nextConfig);\n let mergedRules = mergeTurbopackRules(\n existingTurbopackConfig.rules ?? {},\n Object.values(\n loaders({ lingoConfig, metadataFilePath, translationServerUrl }),\n ).map((rules) => rules.turbopack),\n );\n\n const existingResolveAlias = existingTurbopackConfig.resolveAlias;\n const mergedResolveAlias = {\n ...existingResolveAlias,\n // TODO (AleksandrSl 08/12/2025): Describe what have to be done to support custom resolvers\n };\n\n let turbopackConfig: Partial<NextConfig>;\n if (hasStableTurboConfig()) {\n turbopackConfig = {\n turbopack: {\n ...nextConfig.turbopack, // Preserve existing turbopack options\n rules: mergedRules,\n resolveAlias: mergedResolveAlias,\n },\n };\n } else {\n turbopackConfig = {\n experimental: {\n ...nextConfig.experimental, // Preserve ALL experimental options\n // @ts-expect-error - turbo for Next.js <16\n turbo: {\n // @ts-expect-error - turbo for Next.js <16\n ...nextConfig.experimental?.turbo, // Preserve existing turbo options\n rules: mergedRules,\n resolveAlias: mergedResolveAlias,\n },\n },\n };\n }\n\n const runAfterProductionCompile = async ({\n distDir,\n projectDir,\n }: {\n distDir: string;\n projectDir: string;\n }) => {\n if (typeof nextConfig.compiler?.runAfterProductionCompile === \"function\") {\n await nextConfig.compiler.runAfterProductionCompile({\n distDir,\n projectDir,\n });\n }\n\n logger.info(\"Running post-build translation generation...\");\n\n try {\n await processBuildTranslations({\n config: lingoConfig,\n publicOutputPath: distDir,\n metadataFilePath,\n });\n } catch (error) {\n logger.error(\n \"Translation generation failed:\",\n error instanceof Error ? error.message : error,\n );\n throw error;\n }\n };\n\n const webpack: NextJsWebpackConfig = (\n config: any,\n options: WebpackConfigContext,\n ) => {\n // Apply user's webpack config first if it exists\n let modifiedConfig = config;\n if (typeof nextConfig.webpack === \"function\") {\n modifiedConfig = nextConfig.webpack(config, options);\n }\n\n const lingoRules = Object.values(\n loaders({ lingoConfig, metadataFilePath, translationServerUrl }),\n )\n .map((rules) => rules.webpack)\n .filter(Boolean);\n\n // I tried using plugin from unplugin, but with all the loaders stuff it works poorly.\n // Failing with weird errors which appear on the later compilations, probably something with the cache and virtual modules\n modifiedConfig.module.rules.unshift(...lingoRules);\n\n return modifiedConfig;\n };\n\n return {\n ...nextConfig,\n ...turbopackConfig,\n compiler: {\n ...nextConfig.compiler,\n runAfterProductionCompile,\n },\n webpack,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { LingoProviderProps } from "../shared/LingoProvider.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/react/server/ServerLingoProvider.d.ts
|
|
5
5
|
declare function LingoProvider({
|
|
6
6
|
initialLocale,
|
|
7
7
|
initialTranslations,
|
|
8
8
|
...rest
|
|
9
|
-
}: LingoProviderProps): Promise<
|
|
9
|
+
}: LingoProviderProps): Promise<react_jsx_runtime1.JSX.Element>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { LingoProvider };
|
|
12
12
|
//# sourceMappingURL=ServerLingoProvider.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LingoContext.d.mts","names":[],"sources":["../../../src/react/shared/LingoContext.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LingoContext.d.mts","names":[],"sources":["../../../src/react/shared/LingoContext.ts"],"sourcesContent":[],"mappings":";;;UAGU,gBAAA;;AAFuC;;EAWvC,YAAA,EALM,UAKN;EAKY;;;EAKA,MAAA,EAVZ,UAUY;EAwBN;;;sBA7BM,eAAe;;;;gBAKrB;;;;;;;;;;;;;;;;;;iBAwBA,eAAA,CAAA,GAAmB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PropsWithChildren } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime2 from "react/jsx-runtime";
|
|
3
3
|
import { LocaleCode } from "lingo.dev/spec";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LingoProvider.d.ts
|
|
@@ -70,7 +70,7 @@ declare function LingoProvider__Dev({
|
|
|
70
70
|
router,
|
|
71
71
|
devWidget,
|
|
72
72
|
children
|
|
73
|
-
}: LingoProviderProps):
|
|
73
|
+
}: LingoProviderProps): react_jsx_runtime2.JSX.Element;
|
|
74
74
|
//#endregion
|
|
75
75
|
export { LingoProvider, LingoProviderProps };
|
|
76
76
|
//# sourceMappingURL=LingoProvider.d.mts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LocaleCode } from "lingo.dev/spec";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
3
3
|
import { CSSProperties } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LocaleSwitcher.d.ts
|
|
@@ -65,7 +65,7 @@ declare function LocaleSwitcher({
|
|
|
65
65
|
style,
|
|
66
66
|
className,
|
|
67
67
|
showLoadingState
|
|
68
|
-
}: LocaleSwitcherProps):
|
|
68
|
+
}: LocaleSwitcherProps): react_jsx_runtime3.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
export { LocaleSwitcher };
|
|
71
71
|
//# sourceMappingURL=LocaleSwitcher.d.cts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CSSProperties } from "react";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
3
3
|
import { LocaleCode } from "lingo.dev/spec";
|
|
4
4
|
|
|
5
5
|
//#region src/react/shared/LocaleSwitcher.d.ts
|
|
@@ -65,7 +65,7 @@ declare function LocaleSwitcher({
|
|
|
65
65
|
style,
|
|
66
66
|
className,
|
|
67
67
|
showLoadingState
|
|
68
|
-
}: LocaleSwitcherProps):
|
|
68
|
+
}: LocaleSwitcherProps): react_jsx_runtime1.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
export { LocaleSwitcher };
|
|
71
71
|
//# sourceMappingURL=LocaleSwitcher.d.mts.map
|
package/build/types.d.cts
CHANGED
package/build/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4BA;AAKA;AAEA;AAEY,UA3BK,YAAA,CA2BL;EACL;;;;EAMK,IAAA,EAAA,MAAA;EAA0B;;;;EAIhC,MAAA,EAAA,MAAA;;;;;;AAHJ,KAjBU,uBAAA,GAiBV;EAAO,IAAA,EAAA,QAAA;EAUG,MAAA,EA3BoD,YA2BpC;AAK5B,CAAA;;;;AAsEwB,KAjGZ,yBAAA,GAiGY,cAAA,GAAA,eAAA;AAYF,KA3GV,mBAAA,GA2GU,aAAA,GAAA,WAAA;AAAL,KAzGL,0BAAA,GAA6B,OAyGxB,CAxGf,IAwGe,CAxGV,mBAwGU,EAAA,cAAA,CAAA,CAAA;;;;KAlGL,kBAAA,GAAqB,KAAK,aAAa,6BACjD,QACE,KACE,aACA,oCAAoC;OAE/B,QAAQ;iBACE;;KAIT,gBAAA;;;;KAKA,WAAA;;;;;;;;;;;;;;;;eAkBG;;;;;;;;;;;;;;;;;;;;gBAsBC;;;;;;;;;;;iBAYC;;;;;;;;;;;;;;;;wBAkBO;;;;;;;;;;iBAYP,KAAK
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4BA;AAKA;AAEA;AAEY,UA3BK,YAAA,CA2BL;EACL;;;;EAMK,IAAA,EAAA,MAAA;EAA0B;;;;EAIhC,MAAA,EAAA,MAAA;;;;;;AAHJ,KAjBU,uBAAA,GAiBV;EAAO,IAAA,EAAA,QAAA;EAUG,MAAA,EA3BoD,YA2BpC;AAK5B,CAAA;;;;AAsEwB,KAjGZ,yBAAA,GAiGY,cAAA,GAAA,eAAA;AAYF,KA3GV,mBAAA,GA2GU,aAAA,GAAA,WAAA;AAAL,KAzGL,0BAAA,GAA6B,OAyGxB,CAxGf,IAwGe,CAxGV,mBAwGU,EAAA,cAAA,CAAA,CAAA;;;;KAlGL,kBAAA,GAAqB,KAAK,aAAa,6BACjD,QACE,KACE,aACA,oCAAoC;OAE/B,QAAQ;iBACE;;KAIT,gBAAA;;;;KAKA,WAAA;;;;;;;;;;;;;;;;eAkBG;;;;;;;;;;;;;;;;;;;;gBAsBC;;;;;;;;;;;iBAYC;;;;;;;;;;;;;;;;wBAkBO;;;;;;;;;;iBAYP,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAqCD"}
|
package/build/types.d.mts
CHANGED
package/build/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4BA;AAKA;AAEA;AAEY,UA3BK,YAAA,CA2BL;EACL;;;;EAMK,IAAA,EAAA,MAAA;EAA0B;;;;EAIhC,MAAA,EAAA,MAAA;;;;;;AAHJ,KAjBU,uBAAA,GAiBV;EAAO,IAAA,EAAA,QAAA;EAUG,MAAA,EA3BoD,YA2BpC;AAK5B,CAAA;;;;AAsEwB,KAjGZ,yBAAA,GAiGY,cAAA,GAAA,eAAA;AAYF,KA3GV,mBAAA,GA2GU,aAAA,GAAA,WAAA;AAAL,KAzGL,0BAAA,GAA6B,OAyGxB,CAxGf,IAwGe,CAxGV,mBAwGU,EAAA,cAAA,CAAA,CAAA;;;;KAlGL,kBAAA,GAAqB,KAAK,aAAa,6BACjD,QACE,KACE,aACA,oCAAoC;OAE/B,QAAQ;iBACE;;KAIT,gBAAA;;;;KAKA,WAAA;;;;;;;;;;;;;;;;eAkBG;;;;;;;;;;;;;;;;;;;;gBAsBC;;;;;;;;;;;iBAYC;;;;;;;;;;;;;;;;wBAkBO;;;;;;;;;;iBAYP,KAAK
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4BA;AAKA;AAEA;AAEY,UA3BK,YAAA,CA2BL;EACL;;;;EAMK,IAAA,EAAA,MAAA;EAA0B;;;;EAIhC,MAAA,EAAA,MAAA;;;;;;AAHJ,KAjBU,uBAAA,GAiBV;EAAO,IAAA,EAAA,QAAA;EAUG,MAAA,EA3BoD,YA2BpC;AAK5B,CAAA;;;;AAsEwB,KAjGZ,yBAAA,GAiGY,cAAA,GAAA,eAAA;AAYF,KA3GV,mBAAA,GA2GU,aAAA,GAAA,WAAA;AAAL,KAzGL,0BAAA,GAA6B,OAyGxB,CAxGf,IAwGe,CAxGV,mBAwGU,EAAA,cAAA,CAAA,CAAA;;;;KAlGL,kBAAA,GAAqB,KAAK,aAAa,6BACjD,QACE,KACE,aACA,oCAAoC;OAE/B,QAAQ;iBACE;;KAIT,gBAAA;;;;KAKA,WAAA;;;;;;;;;;;;;;;;eAkBG;;;;;;;;;;;;;;;;;;;;gBAsBC;;;;;;;;;;;iBAYC;;;;;;;;;;;;;;;;wBAkBO;;;;;;;;;;iBAYP,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAqCD"}
|
|
@@ -46,30 +46,39 @@ function inferPluralizationModel(models, sourceLocale, targetLocales) {
|
|
|
46
46
|
*
|
|
47
47
|
*/
|
|
48
48
|
function createLingoConfig(options) {
|
|
49
|
+
const cleanOptions = { ...options };
|
|
50
|
+
const cleanObject = (obj) => {
|
|
51
|
+
if (!obj || typeof obj !== "object") return;
|
|
52
|
+
Object.keys(obj).forEach((key) => {
|
|
53
|
+
if (obj[key] === void 0) delete obj[key];
|
|
54
|
+
else if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) cleanObject(obj[key]);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
cleanObject(cleanOptions);
|
|
49
58
|
const config = {
|
|
50
59
|
...DEFAULT_CONFIG,
|
|
51
|
-
...
|
|
52
|
-
environment:
|
|
53
|
-
cacheType:
|
|
60
|
+
...cleanOptions,
|
|
61
|
+
environment: cleanOptions.environment ?? (process.env.NODE_ENV === "development" ? "development" : "production"),
|
|
62
|
+
cacheType: cleanOptions.cacheType ?? "local",
|
|
54
63
|
dev: {
|
|
55
64
|
...DEFAULT_CONFIG.dev,
|
|
56
|
-
...
|
|
65
|
+
...cleanOptions.dev
|
|
57
66
|
},
|
|
58
67
|
pluralization: {
|
|
59
68
|
...DEFAULT_CONFIG.pluralization,
|
|
60
|
-
...
|
|
69
|
+
...cleanOptions.pluralization
|
|
61
70
|
},
|
|
62
71
|
localePersistence: {
|
|
63
72
|
...DEFAULT_CONFIG.localePersistence,
|
|
64
|
-
...
|
|
73
|
+
...cleanOptions.localePersistence,
|
|
65
74
|
config: {
|
|
66
75
|
...DEFAULT_CONFIG.localePersistence.config,
|
|
67
|
-
...
|
|
76
|
+
...cleanOptions.localePersistence?.config
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
};
|
|
71
|
-
const explicitEnabled =
|
|
72
|
-
const explicitModel =
|
|
80
|
+
const explicitEnabled = cleanOptions.pluralization?.enabled;
|
|
81
|
+
const explicitModel = cleanOptions.pluralization?.model;
|
|
73
82
|
const hasExplicitModel = typeof explicitModel === "string" && explicitModel.trim().length > 0;
|
|
74
83
|
const pluralizationEnabled = typeof explicitEnabled === "boolean" ? explicitEnabled : hasExplicitModel;
|
|
75
84
|
let pluralizationModel = hasExplicitModel ? explicitModel.trim() : config.pluralization.model;
|
|
@@ -45,30 +45,39 @@ function inferPluralizationModel(models, sourceLocale, targetLocales) {
|
|
|
45
45
|
*
|
|
46
46
|
*/
|
|
47
47
|
function createLingoConfig(options) {
|
|
48
|
+
const cleanOptions = { ...options };
|
|
49
|
+
const cleanObject = (obj) => {
|
|
50
|
+
if (!obj || typeof obj !== "object") return;
|
|
51
|
+
Object.keys(obj).forEach((key) => {
|
|
52
|
+
if (obj[key] === void 0) delete obj[key];
|
|
53
|
+
else if (obj[key] && typeof obj[key] === "object" && !Array.isArray(obj[key])) cleanObject(obj[key]);
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
cleanObject(cleanOptions);
|
|
48
57
|
const config = {
|
|
49
58
|
...DEFAULT_CONFIG,
|
|
50
|
-
...
|
|
51
|
-
environment:
|
|
52
|
-
cacheType:
|
|
59
|
+
...cleanOptions,
|
|
60
|
+
environment: cleanOptions.environment ?? (process.env.NODE_ENV === "development" ? "development" : "production"),
|
|
61
|
+
cacheType: cleanOptions.cacheType ?? "local",
|
|
53
62
|
dev: {
|
|
54
63
|
...DEFAULT_CONFIG.dev,
|
|
55
|
-
...
|
|
64
|
+
...cleanOptions.dev
|
|
56
65
|
},
|
|
57
66
|
pluralization: {
|
|
58
67
|
...DEFAULT_CONFIG.pluralization,
|
|
59
|
-
...
|
|
68
|
+
...cleanOptions.pluralization
|
|
60
69
|
},
|
|
61
70
|
localePersistence: {
|
|
62
71
|
...DEFAULT_CONFIG.localePersistence,
|
|
63
|
-
...
|
|
72
|
+
...cleanOptions.localePersistence,
|
|
64
73
|
config: {
|
|
65
74
|
...DEFAULT_CONFIG.localePersistence.config,
|
|
66
|
-
...
|
|
75
|
+
...cleanOptions.localePersistence?.config
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
};
|
|
70
|
-
const explicitEnabled =
|
|
71
|
-
const explicitModel =
|
|
79
|
+
const explicitEnabled = cleanOptions.pluralization?.enabled;
|
|
80
|
+
const explicitModel = cleanOptions.pluralization?.model;
|
|
72
81
|
const hasExplicitModel = typeof explicitModel === "string" && explicitModel.trim().length > 0;
|
|
73
82
|
const pluralizationEnabled = typeof explicitEnabled === "boolean" ? explicitEnabled : hasExplicitModel;
|
|
74
83
|
let pluralizationModel = hasExplicitModel ? explicitModel.trim() : config.pluralization.model;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-factory.mjs","names":["config: LingoConfig"],"sources":["../../src/utils/config-factory.ts"],"sourcesContent":["/**\n * Config factory for creating LoaderConfig instances\n */\nimport type {\n LingoConfig,\n LingoConfigRequiredFields,\n LingoInternalFields,\n PartialLingoConfig,\n} from \"../types\";\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n sourceRoot: \"src\",\n lingoDir: \"lingo\",\n useDirective: false,\n dev: {\n translationServerStartPort: 60000,\n },\n localePersistence: {\n type: \"cookie\" as const,\n config: {\n name: \"locale\",\n maxAge: 31536000,\n },\n },\n models: \"lingo.dev\",\n pluralization: {\n enabled: false,\n model: \"groq:llama-3.1-8b-instant\",\n },\n buildMode: \"translate\",\n} satisfies Omit<\n LingoConfig,\n // Looks like we can use LingoInternalFields, but it's only a coincidence that the types match, we may want to provide default for internal fields\n LingoConfigRequiredFields | \"environment\" | \"cacheType\"\n>;\n\nfunction getModelStringForLocales(\n models: Record<string, string>,\n sourceLocale: string,\n targetLocale: string | undefined,\n): string | undefined {\n const localeKeys = targetLocale\n ? [\n `${sourceLocale}:${targetLocale}`,\n `*:${targetLocale}`,\n `${sourceLocale}:*`,\n \"*:*\",\n ]\n : [`${sourceLocale}:*`, \"*:*\"];\n\n const modelKey = localeKeys.find((key) => key in models);\n if (modelKey) {\n return models[modelKey];\n }\n\n const sortedKeys = Object.keys(models).sort();\n if (sortedKeys.length === 0) {\n return undefined;\n }\n\n return models[sortedKeys[0]];\n}\n\nfunction inferPluralizationModel(\n models: \"lingo.dev\" | Record<string, string>,\n sourceLocale: string,\n targetLocales: string[],\n): string | undefined {\n if (models === \"lingo.dev\") {\n return undefined;\n }\n\n return getModelStringForLocales(\n models,\n sourceLocale,\n targetLocales[0],\n );\n}\n\n/**\n * Create a LoaderConfig with defaults applied\n *\n * @param options - Partial config to override defaults\n * @returns Complete LoaderConfig with all defaults applied\n *\n */\nexport function createLingoConfig(\n options: PartialLingoConfig & Partial<Pick<LingoConfig, LingoInternalFields>>,\n): LingoConfig {\n const config: LingoConfig = {\n ...DEFAULT_CONFIG,\n ...
|
|
1
|
+
{"version":3,"file":"config-factory.mjs","names":["config: LingoConfig"],"sources":["../../src/utils/config-factory.ts"],"sourcesContent":["/**\n * Config factory for creating LoaderConfig instances\n */\nimport type {\n LingoConfig,\n LingoConfigRequiredFields,\n LingoInternalFields,\n PartialLingoConfig,\n} from \"../types\";\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n sourceRoot: \"src\",\n lingoDir: \"lingo\",\n useDirective: false,\n dev: {\n translationServerStartPort: 60000,\n },\n localePersistence: {\n type: \"cookie\" as const,\n config: {\n name: \"locale\",\n maxAge: 31536000,\n },\n },\n models: \"lingo.dev\",\n pluralization: {\n enabled: false,\n model: \"groq:llama-3.1-8b-instant\",\n },\n buildMode: \"translate\",\n} satisfies Omit<\n LingoConfig,\n // Looks like we can use LingoInternalFields, but it's only a coincidence that the types match, we may want to provide default for internal fields\n LingoConfigRequiredFields | \"environment\" | \"cacheType\"\n>;\n\nfunction getModelStringForLocales(\n models: Record<string, string>,\n sourceLocale: string,\n targetLocale: string | undefined,\n): string | undefined {\n const localeKeys = targetLocale\n ? [\n `${sourceLocale}:${targetLocale}`,\n `*:${targetLocale}`,\n `${sourceLocale}:*`,\n \"*:*\",\n ]\n : [`${sourceLocale}:*`, \"*:*\"];\n\n const modelKey = localeKeys.find((key) => key in models);\n if (modelKey) {\n return models[modelKey];\n }\n\n const sortedKeys = Object.keys(models).sort();\n if (sortedKeys.length === 0) {\n return undefined;\n }\n\n return models[sortedKeys[0]];\n}\n\nfunction inferPluralizationModel(\n models: \"lingo.dev\" | Record<string, string>,\n sourceLocale: string,\n targetLocales: string[],\n): string | undefined {\n if (models === \"lingo.dev\") {\n return undefined;\n }\n\n return getModelStringForLocales(\n models,\n sourceLocale,\n targetLocales[0],\n );\n}\n\n/**\n * Create a LoaderConfig with defaults applied\n *\n * @param options - Partial config to override defaults\n * @returns Complete LoaderConfig with all defaults applied\n *\n */\nexport function createLingoConfig(\n options: PartialLingoConfig & Partial<Pick<LingoConfig, LingoInternalFields>>,\n): LingoConfig {\n const cleanOptions = { ...options };\n\n const cleanObject = (obj: any) => {\n if (!obj || typeof obj !== \"object\") return;\n Object.keys(obj).forEach((key) => {\n if (obj[key] === undefined) {\n delete obj[key];\n } else if (\n obj[key] &&\n typeof obj[key] === \"object\" &&\n !Array.isArray(obj[key])\n ) {\n cleanObject(obj[key]);\n }\n });\n };\n\n cleanObject(cleanOptions);\n\n const config: LingoConfig = {\n ...DEFAULT_CONFIG,\n ...cleanOptions,\n environment:\n cleanOptions.environment ??\n (process.env.NODE_ENV === \"development\" ? \"development\" : \"production\"),\n cacheType: cleanOptions.cacheType ?? \"local\",\n dev: {\n ...DEFAULT_CONFIG.dev,\n ...cleanOptions.dev,\n },\n pluralization: {\n ...DEFAULT_CONFIG.pluralization,\n ...cleanOptions.pluralization,\n },\n localePersistence: {\n ...DEFAULT_CONFIG.localePersistence,\n ...cleanOptions.localePersistence,\n config: {\n ...DEFAULT_CONFIG.localePersistence.config,\n ...cleanOptions.localePersistence?.config,\n },\n },\n };\n\n const explicitEnabled = cleanOptions.pluralization?.enabled;\n const explicitModel = cleanOptions.pluralization?.model;\n const hasExplicitModel =\n typeof explicitModel === \"string\" && explicitModel.trim().length > 0;\n const hasExplicitEnabled = typeof explicitEnabled === \"boolean\";\n\n const pluralizationEnabled = hasExplicitEnabled\n ? explicitEnabled\n : hasExplicitModel;\n\n let pluralizationModel = hasExplicitModel\n ? explicitModel!.trim()\n : config.pluralization.model;\n\n if (pluralizationEnabled && !hasExplicitModel) {\n const inferredModel = inferPluralizationModel(\n config.models,\n config.sourceLocale,\n config.targetLocales,\n );\n\n if (!inferredModel) {\n throw new Error(\n 'Pluralization is enabled but no \"pluralization.model\" is configured. Please set \"pluralization.model\" explicitly or use direct LLM models (not \"lingo.dev\") so the model can be inferred.',\n );\n }\n\n pluralizationModel = inferredModel;\n }\n\n config.pluralization = {\n ...config.pluralization,\n enabled: pluralizationEnabled,\n model: pluralizationModel,\n };\n\n return config;\n}\n"],"mappings":";;;;AAaA,MAAa,iBAAiB;CAC5B,YAAY;CACZ,UAAU;CACV,cAAc;CACd,KAAK,EACH,4BAA4B,KAC7B;CACD,mBAAmB;EACjB,MAAM;EACN,QAAQ;GACN,MAAM;GACN,QAAQ;GACT;EACF;CACD,QAAQ;CACR,eAAe;EACb,SAAS;EACT,OAAO;EACR;CACD,WAAW;CACZ;AAMD,SAAS,yBACP,QACA,cACA,cACoB;CAUpB,MAAM,YATa,eACf;EACE,GAAG,aAAa,GAAG;EACnB,KAAK;EACL,GAAG,aAAa;EAChB;EACD,GACD,CAAC,GAAG,aAAa,KAAK,MAAM,EAEJ,MAAM,QAAQ,OAAO,OAAO;AACxD,KAAI,SACF,QAAO,OAAO;CAGhB,MAAM,aAAa,OAAO,KAAK,OAAO,CAAC,MAAM;AAC7C,KAAI,WAAW,WAAW,EACxB;AAGF,QAAO,OAAO,WAAW;;AAG3B,SAAS,wBACP,QACA,cACA,eACoB;AACpB,KAAI,WAAW,YACb;AAGF,QAAO,yBACL,QACA,cACA,cAAc,GACf;;;;;;;;;AAUH,SAAgB,kBACd,SACa;CACb,MAAM,eAAe,EAAE,GAAG,SAAS;CAEnC,MAAM,eAAe,QAAa;AAChC,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU;AACrC,SAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;AAChC,OAAI,IAAI,SAAS,OACf,QAAO,IAAI;YAEX,IAAI,QACJ,OAAO,IAAI,SAAS,YACpB,CAAC,MAAM,QAAQ,IAAI,KAAK,CAExB,aAAY,IAAI,KAAK;IAEvB;;AAGJ,aAAY,aAAa;CAEzB,MAAMA,SAAsB;EAC1B,GAAG;EACH,GAAG;EACH,aACE,aAAa,gBACZ,QAAQ,IAAI,aAAa,gBAAgB,gBAAgB;EAC5D,WAAW,aAAa,aAAa;EACrC,KAAK;GACH,GAAG,eAAe;GAClB,GAAG,aAAa;GACjB;EACD,eAAe;GACb,GAAG,eAAe;GAClB,GAAG,aAAa;GACjB;EACD,mBAAmB;GACjB,GAAG,eAAe;GAClB,GAAG,aAAa;GAChB,QAAQ;IACN,GAAG,eAAe,kBAAkB;IACpC,GAAG,aAAa,mBAAmB;IACpC;GACF;EACF;CAED,MAAM,kBAAkB,aAAa,eAAe;CACpD,MAAM,gBAAgB,aAAa,eAAe;CAClD,MAAM,mBACJ,OAAO,kBAAkB,YAAY,cAAc,MAAM,CAAC,SAAS;CAGrE,MAAM,uBAFqB,OAAO,oBAAoB,YAGlD,kBACA;CAEJ,IAAI,qBAAqB,mBACrB,cAAe,MAAM,GACrB,OAAO,cAAc;AAEzB,KAAI,wBAAwB,CAAC,kBAAkB;EAC7C,MAAM,gBAAgB,wBACpB,OAAO,QACP,OAAO,cACP,OAAO,cACR;AAED,MAAI,CAAC,cACH,OAAM,IAAI,MACR,kMACD;AAGH,uBAAqB;;AAGvB,QAAO,gBAAgB;EACrB,GAAG,OAAO;EACV,SAAS;EACT,OAAO;EACR;AAED,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingo.dev/compiler",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"description": "Lingo.dev Compiler",
|
|
5
5
|
"private": false,
|
|
6
6
|
"repository": {
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"posthog-node": "5.14.0",
|
|
162
162
|
"lmdb": "3.2.6",
|
|
163
163
|
"ws": "8.18.3",
|
|
164
|
-
"lingo.dev": "^0.132.
|
|
164
|
+
"lingo.dev": "^0.132.9"
|
|
165
165
|
},
|
|
166
166
|
"peerDependencies": {
|
|
167
167
|
"next": "^15.0.0 || ^16.0.4",
|