Skip to content

Commit 361a163

Browse files
committed
fix: port number and dev config types
1 parent 9398d38 commit 361a163

3 files changed

Lines changed: 49 additions & 60 deletions

File tree

cmp/compiler/src/translation-server/cli.ts

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,27 @@
3838
*/
3939

4040
import { parseArgs } from "node:util";
41-
import { readFile, access } from "fs/promises";
42-
import { resolve, join } from "path";
41+
import { access } from "fs/promises";
42+
import { join } from "path";
4343
import { pathToFileURL } from "url";
44-
import type { TranslationMiddlewareConfig } from "../types";
44+
import type {
45+
LingoConfig,
46+
PartialLingoConfig,
47+
TranslationMiddlewareConfig,
48+
} from "../types";
4549
import type { LingoNextPluginOptions } from "../plugin/next";
4650
import { logger } from "../utils/logger";
4751
import { startOrGetTranslationServer } from "./translation-server";
52+
import { createLingoConfig } from "../utils/config-factory";
53+
import { type LocaleCode } from "lingo.dev/spec";
4854

4955
interface CLIOptions {
5056
port?: number;
51-
sourceLocale?: string;
52-
targetLocales?: string[];
57+
sourceLocale?: LocaleCode;
58+
targetLocales?: LocaleCode[];
5359
lingoDir?: string;
5460
sourceRoot?: string;
55-
models?: string | Record<string, string>;
61+
models?: "lingo.dev" | Record<string, string>;
5662
prompt?: string;
5763
timeout?: number;
5864
usePseudo?: boolean;
@@ -83,8 +89,11 @@ function parseCliArgs(): CLIOptions {
8389

8490
return {
8591
port: values.port ? parseInt(values.port, 10) : undefined,
86-
sourceLocale: values["source-locale"],
87-
targetLocales: values["target-locales"]?.split(",").map((s) => s.trim()),
92+
// TODO (AleksandrSl 04/12/2025): Validation for LocaleCode is needed
93+
sourceLocale: values["source-locale"] as LocaleCode,
94+
targetLocales: values["target-locales"]
95+
?.split(",")
96+
.map((s) => s.trim()) as LocaleCode[],
8897
lingoDir: values["lingo-dir"],
8998
sourceRoot: values["source-root"],
9099
models: values.models ? parseModelsString(values.models) : undefined,
@@ -230,7 +239,7 @@ function extractViteLingoConfig(
230239
*/
231240
async function loadBundlerConfig(
232241
cwd: string = process.cwd(),
233-
): Promise<Partial<TranslationMiddlewareConfig> | null> {
242+
): Promise<PartialLingoConfig | null> {
234243
const detected = await findBundlerConfig(cwd);
235244

236245
if (!detected) {
@@ -257,13 +266,13 @@ async function loadBundlerConfig(
257266
const lingoConfig = extractNextLingoConfig(resolvedConfig);
258267
if (lingoConfig) {
259268
logger.info("Extracted Lingo configuration from Next.js config");
260-
return lingoConfig as Partial<TranslationMiddlewareConfig>;
269+
return lingoConfig as PartialLingoConfig;
261270
}
262271
} else if (detected.type === "vite") {
263272
const lingoConfig = extractViteLingoConfig(resolvedConfig);
264273
if (lingoConfig) {
265274
logger.info("Extracted Lingo configuration from Vite config");
266-
return lingoConfig;
275+
return lingoConfig as PartialLingoConfig;
267276
}
268277
}
269278

@@ -280,49 +289,34 @@ async function loadBundlerConfig(
280289
}
281290
}
282291

283-
/**
284-
* Load configuration from JSON file (legacy support)
285-
*/
286-
async function loadConfigFile(
287-
configPath: string,
288-
): Promise<Partial<TranslationMiddlewareConfig>> {
289-
try {
290-
const absolutePath = resolve(process.cwd(), configPath);
291-
const content = await readFile(absolutePath, "utf-8");
292-
return JSON.parse(content);
293-
} catch (error) {
294-
logger.error(`Failed to load config from ${configPath}:`, error);
295-
throw error;
296-
}
297-
}
298-
299-
// TODO (AleksandrSl 04/12/2025): SHould probably use createloaderConfig?
300292
/**
301293
* Merge CLI options with config file and defaults
302294
*/
303295
function buildConfig(
304296
cliOpts: CLIOptions,
305-
fileConfig?: Partial<TranslationMiddlewareConfig>,
306-
): TranslationMiddlewareConfig {
297+
fileConfig?: PartialLingoConfig,
298+
): LingoConfig {
299+
const sourceLocale = cliOpts.sourceLocale || fileConfig?.sourceLocale;
300+
const targetLocales = cliOpts.targetLocales || fileConfig?.targetLocales;
301+
if (!sourceLocale || !targetLocales) {
302+
throw new Error(
303+
`Missing required sourceLocale or targetLocales. Please provide via CLI options or ensure your config uses the Lingo plugin`,
304+
);
305+
}
307306
// Priority: CLI > config file > defaults
308-
const config: TranslationMiddlewareConfig = {
309-
sourceLocale: (cliOpts.sourceLocale ||
310-
fileConfig?.sourceLocale ||
311-
"en") as any,
312-
targetLocales: (cliOpts.targetLocales ||
313-
fileConfig?.targetLocales || ["es", "fr", "de"]) as any,
314-
lingoDir: cliOpts.lingoDir || fileConfig?.lingoDir || ".lingo",
307+
return createLingoConfig({
308+
sourceLocale,
309+
targetLocales,
310+
lingoDir: cliOpts.lingoDir || fileConfig?.lingoDir,
315311
sourceRoot: cliOpts.sourceRoot || fileConfig?.sourceRoot || process.cwd(),
316-
models: (cliOpts.models || fileConfig?.models || "lingo.dev") as any,
312+
models: cliOpts.models || fileConfig?.models,
317313
prompt: cliOpts.prompt || fileConfig?.prompt,
318314
dev: {
319315
usePseudotranslator:
320-
cliOpts.usePseudo ?? fileConfig?.dev?.usePseudotranslator ?? false,
321-
serverStartPort: fileConfig?.dev?.serverStartPort || 6000,
316+
cliOpts.usePseudo ?? fileConfig?.dev?.usePseudotranslator,
317+
serverStartPort: fileConfig?.dev?.serverStartPort,
322318
},
323-
};
324-
325-
return config;
319+
});
326320
}
327321

328322
/**
@@ -416,22 +410,13 @@ export async function main(): Promise<void> {
416410
process.exit(0);
417411
}
418412

419-
// Load configuration in priority order:
420-
// 1. Explicit --config file (JSON)
421-
// 2. Auto-detect bundler config (next.config.ts / vite.config.ts)
422-
let fileConfig: Partial<TranslationMiddlewareConfig> | undefined;
413+
// Try to auto-detect bundler config
414+
logger.info("Searching for bundler configuration...");
415+
const fileConfig: PartialLingoConfig | undefined =
416+
(await loadBundlerConfig()) || undefined;
423417

424-
if (cliOpts.config) {
425-
logger.info(`Loading configuration from ${cliOpts.config}...`);
426-
fileConfig = await loadConfigFile(cliOpts.config);
427-
} else {
428-
// Try to auto-detect bundler config
429-
logger.info("Searching for bundler configuration...");
430-
fileConfig = (await loadBundlerConfig()) || undefined;
431-
432-
if (!fileConfig) {
433-
logger.info("No bundler config found, using defaults + CLI options");
434-
}
418+
if (!fileConfig) {
419+
logger.info("No bundler config found, using defaults + CLI options");
435420
}
436421

437422
// Build final configuration

cmp/compiler/src/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ export type LingoConfigRequiredFields = "sourceLocale" | "targetLocales";
3030
* Configuration for the Lingo compiler
3131
*/
3232
export type PartialLingoConfig = Pick<LingoConfig, LingoConfigRequiredFields> &
33-
Partial<Omit<LingoConfig, LingoConfigRequiredFields>>;
33+
Partial<
34+
Omit<LingoConfig, LingoConfigRequiredFields | "dev"> & {
35+
dev: Partial<LingoConfig["dev"]>;
36+
}
37+
>;
3438

3539
/**
3640
* Lingo config with all the defaults applied

cmp/compiler/src/utils/config-factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const DEFAULT_CONFIG = {
1616
useDirective: false,
1717
skipPatterns: [/node_modules/, /\.spec\./, /\.test\./] as RegExp[],
1818
dev: {
19-
serverStartPort: 6000,
19+
serverStartPort: 60000,
2020
},
2121
cookieConfig: {
2222
name: "locale",

0 commit comments

Comments
 (0)