lezu 0.0.40 → 0.0.42

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.
@@ -1,217 +0,0 @@
1
- import {
2
- loadConfig,
3
- validateConfig
4
- } from "./chunk-EDQCBUBB.js";
5
- import {
6
- LezuApiClient
7
- } from "./chunk-V2UO7VTR.js";
8
-
9
- // src/commands/get.ts
10
- import { Command } from "commander";
11
- import chalk from "chalk";
12
- import ora from "ora";
13
- function createGetCommand() {
14
- const command = new Command("get").description("Get information about your project");
15
- command.command("languages").alias("langs").description("List all languages in your project").option("-p, --project <id>", "Project ID").option("-a, --api-key <key>", "API key").option("--api-url <url>", "API URL", "https://api.lezu.app").option("--include-disabled", "Include disabled languages").option("--json", "Output as JSON").action(async (options) => {
16
- try {
17
- const config = loadConfig(options);
18
- const errors = validateConfig(config);
19
- if (errors.length > 0) {
20
- console.error(chalk.red("Configuration errors:"));
21
- errors.forEach((error) => console.error(chalk.red(` - ${error}`)));
22
- process.exit(1);
23
- }
24
- await getLanguages(config, options);
25
- } catch (error) {
26
- console.error(chalk.red("\n[Error]"), error instanceof Error ? error.message : error);
27
- process.exit(1);
28
- }
29
- });
30
- command.command("releases").description("List all releases in your project").option("-p, --project <id>", "Project ID").option("-a, --api-key <key>", "API key").option("--api-url <url>", "API URL", "https://api.lezu.app").option("-e, --environment <env>", "Environment", "production").option("--json", "Output as JSON").option("--limit <n>", "Limit number of results", "10").action(async (options) => {
31
- try {
32
- const config = loadConfig(options);
33
- const errors = validateConfig(config);
34
- if (errors.length > 0) {
35
- console.error(chalk.red("Configuration errors:"));
36
- errors.forEach((error) => console.error(chalk.red(` - ${error}`)));
37
- process.exit(1);
38
- }
39
- await getReleases(config, options);
40
- } catch (error) {
41
- console.error(chalk.red("\n[Error]"), error instanceof Error ? error.message : error);
42
- process.exit(1);
43
- }
44
- });
45
- command.command("project").alias("info").description("Get project information and statistics").option("-p, --project <id>", "Project ID").option("-a, --api-key <key>", "API key").option("--api-url <url>", "API URL", "https://api.lezu.app").option("--json", "Output as JSON").option("--stats", "Include detailed statistics").action(async (options) => {
46
- try {
47
- const config = loadConfig(options);
48
- const errors = validateConfig(config);
49
- if (errors.length > 0) {
50
- console.error(chalk.red("Configuration errors:"));
51
- errors.forEach((error) => console.error(chalk.red(` - ${error}`)));
52
- process.exit(1);
53
- }
54
- await getProject(config, options);
55
- } catch (error) {
56
- console.error(chalk.red("\n[Error]"), error instanceof Error ? error.message : error);
57
- process.exit(1);
58
- }
59
- });
60
- return command;
61
- }
62
- async function getLanguages(config, options) {
63
- const spinner = ora("Fetching languages...").start();
64
- try {
65
- const client = new LezuApiClient(config);
66
- const response = await client.getLanguages();
67
- spinner.succeed("Languages fetched successfully!");
68
- if (options.json) {
69
- console.log(JSON.stringify(response, null, 2));
70
- return;
71
- }
72
- console.log(chalk.green("\n[Project Languages]"));
73
- if (!response.languages || response.languages.length === 0) {
74
- console.log(chalk.gray(" No languages found"));
75
- return;
76
- }
77
- response.languages.forEach((lang) => {
78
- const status = lang.enabled ? chalk.green("[ON]") : chalk.gray("[OFF]");
79
- const progress = lang.progress ? ` (${lang.progress.percentage}% complete)` : "";
80
- const source = lang.is_source ? chalk.yellow(" [SOURCE]") : "";
81
- console.log(` ${status} ${lang.language?.name || lang.language_code} (${lang.language_code})${source}${progress}`);
82
- if (lang.progress && lang.progress.total > 0) {
83
- console.log(chalk.gray(` ${lang.progress.translated}/${lang.progress.total} keys translated`));
84
- }
85
- });
86
- console.log(chalk.gray(`
87
- Total: ${response.total} languages`));
88
- } catch (error) {
89
- spinner.fail("Failed to fetch languages");
90
- throw error;
91
- }
92
- }
93
- async function getReleases(config, options) {
94
- const spinner = ora("Fetching releases...").start();
95
- try {
96
- const client = new LezuApiClient(config);
97
- const response = await client.getReleases();
98
- spinner.succeed("Releases fetched successfully!");
99
- if (options.json) {
100
- console.log(JSON.stringify(response, null, 2));
101
- return;
102
- }
103
- console.log(chalk.green(`
104
- [Releases] (${options.environment} environment):`));
105
- if (!response.releases || response.releases.length === 0) {
106
- console.log(chalk.gray(" No releases found"));
107
- return;
108
- }
109
- const limit = parseInt(options.limit, 10);
110
- const releases = response.releases.slice(0, limit);
111
- releases.forEach((release, index) => {
112
- const current = release.is_current ? chalk.yellow(" [CURRENT]") : "";
113
- const date = new Date(release.created_at).toLocaleDateString();
114
- const reviewedTag = release.reviewed_only ? chalk.blue(" [REVIEWED ONLY]") : "";
115
- console.log(` ${index + 1}. ${release.version}${current}${reviewedTag}`);
116
- if (release.name && release.name !== release.version) {
117
- console.log(chalk.gray(` ${release.name}`));
118
- }
119
- if (release.description) {
120
- console.log(chalk.gray(` ${release.description}`));
121
- }
122
- console.log(chalk.gray(` Created: ${date}`));
123
- if (release.created_by_user?.email) {
124
- console.log(chalk.gray(` By: ${release.created_by_user.email}`));
125
- }
126
- console.log();
127
- });
128
- if (response.releases.length > limit) {
129
- console.log(chalk.gray(`... and ${response.releases.length - limit} more releases`));
130
- console.log(chalk.gray(`Use --limit ${response.releases.length} to see all releases`));
131
- }
132
- } catch (error) {
133
- spinner.fail("Failed to fetch releases");
134
- throw error;
135
- }
136
- }
137
- async function getProject(config, options) {
138
- const spinner = ora("Fetching project information...").start();
139
- try {
140
- const client = new LezuApiClient(config);
141
- let projectData, statsData;
142
- if (options.stats) {
143
- const [projectResponse, statsResponse] = await Promise.all([
144
- client.getProject(),
145
- fetch(`${config.apiUrl}/v1/projects/${config.projectId}/stats`, {
146
- headers: {
147
- "Authorization": `Bearer ${config.apiKey}`
148
- }
149
- }).then((r) => r.json())
150
- ]);
151
- projectData = projectResponse.project;
152
- statsData = statsResponse.stats;
153
- } else {
154
- const response = await client.getProject();
155
- projectData = response.project;
156
- }
157
- spinner.succeed("Project information fetched successfully!");
158
- if (options.json) {
159
- console.log(JSON.stringify({ project: projectData, stats: statsData }, null, 2));
160
- return;
161
- }
162
- console.log(chalk.green("\n[Project Information]"));
163
- console.log(` Name: ${projectData.name}`);
164
- console.log(` Key: ${projectData.key}`);
165
- console.log(` ID: ${projectData.id}`);
166
- if (projectData.description) {
167
- console.log(` Description: ${projectData.description}`);
168
- }
169
- console.log(` Source Language: ${projectData.source_language}`);
170
- console.log(` Created: ${new Date(projectData.created_at).toLocaleDateString()}`);
171
- if (projectData.stats) {
172
- console.log(chalk.green("\n[Basic Statistics]"));
173
- console.log(` Translation Keys: ${projectData.stats.keys}`);
174
- console.log(` Languages: ${projectData.stats.languages}`);
175
- console.log(` Translations: ${projectData.stats.translations}`);
176
- console.log(` Completeness: ${projectData.stats.completeness}%`);
177
- }
178
- if (statsData) {
179
- console.log(chalk.green("\n[Detailed Statistics]"));
180
- console.log(` Total Keys: ${statsData.overview.totalKeys}`);
181
- console.log(` Total Languages: ${statsData.overview.totalLanguages}`);
182
- console.log(` Total Releases: ${statsData.overview.totalReleases}`);
183
- console.log(` Keys Added Last Month: ${statsData.overview.keysAddedLastMonth}`);
184
- if (statsData.languages && statsData.languages.length > 0) {
185
- console.log(chalk.green("\n[Language Progress]"));
186
- statsData.languages.forEach((lang) => {
187
- const percentage = lang.percentage;
188
- const bar = "#".repeat(Math.floor(percentage / 5)) + "-".repeat(20 - Math.floor(percentage / 5));
189
- console.log(` ${lang.language_code}: [${bar}] ${percentage}%`);
190
- console.log(chalk.gray(` ${lang.translated}/${lang.total} translated, ${lang.reviewed} reviewed, ${lang.missing} missing`));
191
- });
192
- }
193
- if (statsData.recentReleases && statsData.recentReleases.length > 0) {
194
- console.log(chalk.green("\n[Recent Releases]"));
195
- statsData.recentReleases.forEach((release) => {
196
- const date = new Date(release.created_at).toLocaleDateString();
197
- console.log(` - ${release.version} (${date})`);
198
- });
199
- }
200
- }
201
- if (projectData.environments && projectData.environments.length > 0) {
202
- console.log(chalk.green("\n[Environments]"));
203
- projectData.environments.forEach((env) => {
204
- const current = env.current_release_id ? ` (current: ${env.current_release_id.substring(0, 8)}...)` : "";
205
- console.log(` - ${env.name}${current}`);
206
- });
207
- }
208
- } catch (error) {
209
- spinner.fail("Failed to fetch project information");
210
- throw error;
211
- }
212
- }
213
-
214
- export {
215
- createGetCommand
216
- };
217
- //# sourceMappingURL=chunk-5N5URMOC.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/get.ts"],"sourcesContent":["import { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { loadConfig, validateConfig } from '../config.js'\nimport { LezuApiClient } from '../api.js'\nimport type { Config } from '../types.js'\n\nexport function createGetCommand() {\n const command = new Command('get')\n .description('Get information about your project')\n \n // Languages subcommand\n command\n .command('languages')\n .alias('langs')\n .description('List all languages in your project')\n .option('-p, --project <id>', 'Project ID')\n .option('-a, --api-key <key>', 'API key')\n .option('--api-url <url>', 'API URL', 'https://api.lezu.app')\n .option('--include-disabled', 'Include disabled languages')\n .option('--json', 'Output as JSON')\n .action(async (options) => {\n try {\n const config = loadConfig(options)\n const errors = validateConfig(config)\n if (errors.length > 0) {\n console.error(chalk.red('Configuration errors:'))\n errors.forEach(error => console.error(chalk.red(` - ${error}`)))\n process.exit(1)\n }\n \n await getLanguages(config, options)\n } catch (error) {\n console.error(chalk.red('\\n[Error]'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n })\n \n // Releases subcommand\n command\n .command('releases')\n .description('List all releases in your project')\n .option('-p, --project <id>', 'Project ID')\n .option('-a, --api-key <key>', 'API key')\n .option('--api-url <url>', 'API URL', 'https://api.lezu.app')\n .option('-e, --environment <env>', 'Environment', 'production')\n .option('--json', 'Output as JSON')\n .option('--limit <n>', 'Limit number of results', '10')\n .action(async (options) => {\n try {\n const config = loadConfig(options)\n const errors = validateConfig(config)\n if (errors.length > 0) {\n console.error(chalk.red('Configuration errors:'))\n errors.forEach(error => console.error(chalk.red(` - ${error}`)))\n process.exit(1)\n }\n \n await getReleases(config, options)\n } catch (error) {\n console.error(chalk.red('\\n[Error]'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n })\n \n // Project info subcommand\n command\n .command('project')\n .alias('info')\n .description('Get project information and statistics')\n .option('-p, --project <id>', 'Project ID')\n .option('-a, --api-key <key>', 'API key')\n .option('--api-url <url>', 'API URL', 'https://api.lezu.app')\n .option('--json', 'Output as JSON')\n .option('--stats', 'Include detailed statistics')\n .action(async (options) => {\n try {\n const config = loadConfig(options)\n const errors = validateConfig(config)\n if (errors.length > 0) {\n console.error(chalk.red('Configuration errors:'))\n errors.forEach(error => console.error(chalk.red(` - ${error}`)))\n process.exit(1)\n }\n \n await getProject(config, options)\n } catch (error) {\n console.error(chalk.red('\\n[Error]'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n })\n \n return command\n}\n\nasync function getLanguages(config: Config, options: any) {\n const spinner = ora('Fetching languages...').start()\n \n try {\n const client = new LezuApiClient(config)\n const response = await client.getLanguages()\n \n spinner.succeed('Languages fetched successfully!')\n \n if (options.json) {\n console.log(JSON.stringify(response, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Project Languages]'))\n \n if (!response.languages || response.languages.length === 0) {\n console.log(chalk.gray(' No languages found'))\n return\n }\n \n response.languages.forEach((lang: any) => {\n const status = lang.enabled ? chalk.green('[ON]') : chalk.gray('[OFF]')\n const progress = lang.progress ? ` (${lang.progress.percentage}% complete)` : ''\n const source = lang.is_source ? chalk.yellow(' [SOURCE]') : ''\n \n console.log(` ${status} ${lang.language?.name || lang.language_code} (${lang.language_code})${source}${progress}`)\n \n if (lang.progress && lang.progress.total > 0) {\n console.log(chalk.gray(` ${lang.progress.translated}/${lang.progress.total} keys translated`))\n }\n })\n \n console.log(chalk.gray(`\\nTotal: ${response.total} languages`))\n \n } catch (error) {\n spinner.fail('Failed to fetch languages')\n throw error\n }\n}\n\nasync function getReleases(config: Config, options: any) {\n const spinner = ora('Fetching releases...').start()\n \n try {\n const client = new LezuApiClient(config)\n const response = await client.getReleases()\n \n spinner.succeed('Releases fetched successfully!')\n \n if (options.json) {\n console.log(JSON.stringify(response, null, 2))\n return\n }\n \n console.log(chalk.green(`\\n[Releases] (${options.environment} environment):`))\n \n if (!response.releases || response.releases.length === 0) {\n console.log(chalk.gray(' No releases found'))\n return\n }\n \n const limit = parseInt(options.limit, 10)\n const releases = response.releases.slice(0, limit)\n \n releases.forEach((release: any, index: number) => {\n const current = release.is_current ? chalk.yellow(' [CURRENT]') : ''\n const date = new Date(release.created_at).toLocaleDateString()\n const reviewedTag = release.reviewed_only ? chalk.blue(' [REVIEWED ONLY]') : ''\n \n console.log(` ${index + 1}. ${release.version}${current}${reviewedTag}`)\n if (release.name && release.name !== release.version) {\n console.log(chalk.gray(` ${release.name}`))\n }\n if (release.description) {\n console.log(chalk.gray(` ${release.description}`))\n }\n console.log(chalk.gray(` Created: ${date}`))\n if (release.created_by_user?.email) {\n console.log(chalk.gray(` By: ${release.created_by_user.email}`))\n }\n console.log() // empty line\n })\n \n if (response.releases.length > limit) {\n console.log(chalk.gray(`... and ${response.releases.length - limit} more releases`))\n console.log(chalk.gray(`Use --limit ${response.releases.length} to see all releases`))\n }\n \n } catch (error) {\n spinner.fail('Failed to fetch releases')\n throw error\n }\n}\n\nasync function getProject(config: Config, options: any) {\n const spinner = ora('Fetching project information...').start()\n \n try {\n const client = new LezuApiClient(config)\n \n let projectData, statsData\n \n if (options.stats) {\n // Fetch both project info and detailed stats\n const [projectResponse, statsResponse] = await Promise.all([\n client.getProject(),\n fetch(`${config.apiUrl}/v1/projects/${config.projectId}/stats`, {\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n }).then(r => r.json())\n ])\n projectData = projectResponse.project\n statsData = statsResponse.stats\n } else {\n const response = await client.getProject()\n projectData = response.project\n }\n \n spinner.succeed('Project information fetched successfully!')\n \n if (options.json) {\n console.log(JSON.stringify({ project: projectData, stats: statsData }, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Project Information]'))\n console.log(` Name: ${projectData.name}`)\n console.log(` Key: ${projectData.key}`)\n console.log(` ID: ${projectData.id}`)\n if (projectData.description) {\n console.log(` Description: ${projectData.description}`)\n }\n console.log(` Source Language: ${projectData.source_language}`)\n console.log(` Created: ${new Date(projectData.created_at).toLocaleDateString()}`)\n \n // Basic stats (always available)\n if (projectData.stats) {\n console.log(chalk.green('\\n[Basic Statistics]'))\n console.log(` Translation Keys: ${projectData.stats.keys}`)\n console.log(` Languages: ${projectData.stats.languages}`)\n console.log(` Translations: ${projectData.stats.translations}`)\n console.log(` Completeness: ${projectData.stats.completeness}%`)\n }\n \n // Detailed stats (when --stats is used)\n if (statsData) {\n console.log(chalk.green('\\n[Detailed Statistics]'))\n console.log(` Total Keys: ${statsData.overview.totalKeys}`)\n console.log(` Total Languages: ${statsData.overview.totalLanguages}`)\n console.log(` Total Releases: ${statsData.overview.totalReleases}`)\n console.log(` Keys Added Last Month: ${statsData.overview.keysAddedLastMonth}`)\n \n if (statsData.languages && statsData.languages.length > 0) {\n console.log(chalk.green('\\n[Language Progress]'))\n statsData.languages.forEach((lang: any) => {\n const percentage = lang.percentage\n const bar = '#'.repeat(Math.floor(percentage / 5)) + '-'.repeat(20 - Math.floor(percentage / 5))\n console.log(` ${lang.language_code}: [${bar}] ${percentage}%`)\n console.log(chalk.gray(` ${lang.translated}/${lang.total} translated, ${lang.reviewed} reviewed, ${lang.missing} missing`))\n })\n }\n \n if (statsData.recentReleases && statsData.recentReleases.length > 0) {\n console.log(chalk.green('\\n[Recent Releases]'))\n statsData.recentReleases.forEach((release: any) => {\n const date = new Date(release.created_at).toLocaleDateString()\n console.log(` - ${release.version} (${date})`)\n })\n }\n }\n \n // Show environments\n if (projectData.environments && projectData.environments.length > 0) {\n console.log(chalk.green('\\n[Environments]'))\n projectData.environments.forEach((env: any) => {\n const current = env.current_release_id ? ` (current: ${env.current_release_id.substring(0, 8)}...)` : ''\n console.log(` - ${env.name}${current}`)\n })\n }\n \n } catch (error) {\n spinner.fail('Failed to fetch project information')\n throw error\n }\n}"],"mappings":"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","names":[]}
@@ -1,96 +0,0 @@
1
- // src/config.ts
2
- import { readFileSync, existsSync } from "fs";
3
- import { resolve } from "path";
4
- import dotenv from "dotenv";
5
-
6
- // src/types.ts
7
- import { z } from "zod";
8
- var ConfigSchema = z.object({
9
- projectId: z.string().optional(),
10
- apiKey: z.string().optional(),
11
- apiUrl: z.string().default("https://api.lezu.app"),
12
- dest: z.string().default("./src/i18n"),
13
- format: z.enum(["json", "js", "ts", "yaml", "po"]).default("json"),
14
- languages: z.array(z.string()).optional(),
15
- release: z.string().optional(),
16
- environment: z.string().default("production"),
17
- flatten: z.boolean().default(false),
18
- namespace: z.boolean().default(false),
19
- includeEmpty: z.boolean().default(false),
20
- watch: z.boolean().default(false),
21
- watchInterval: z.number().default(5e3),
22
- debug: z.boolean().default(false)
23
- });
24
-
25
- // src/config.ts
26
- dotenv.config();
27
- function loadConfig(options = {}) {
28
- let config = {
29
- apiUrl: "https://api.lezu.app",
30
- dest: "./src/i18n",
31
- format: "json",
32
- environment: "production",
33
- flatten: false,
34
- namespace: false,
35
- includeEmpty: false,
36
- watch: false,
37
- watchInterval: 5e3
38
- };
39
- const configFiles = [".lezurc", ".lezurc.json", "lezu.config.json"];
40
- for (const file of configFiles) {
41
- const configPath = resolve(process.cwd(), file);
42
- if (existsSync(configPath)) {
43
- try {
44
- const content = readFileSync(configPath, "utf-8");
45
- const fileConfig = JSON.parse(content);
46
- config = { ...config, ...fileConfig };
47
- break;
48
- } catch (error) {
49
- console.warn(`[Warning] Failed to load config from ${file}:`, error);
50
- }
51
- }
52
- }
53
- if (process.env.LEZU_PROJECT_ID) {
54
- config.projectId = process.env.LEZU_PROJECT_ID;
55
- }
56
- if (process.env.LEZU_API_KEY) {
57
- config.apiKey = process.env.LEZU_API_KEY;
58
- }
59
- if (process.env.LEZU_API_URL) {
60
- config.apiUrl = process.env.LEZU_API_URL;
61
- }
62
- if (process.env.LEZU_DEST) {
63
- config.dest = process.env.LEZU_DEST;
64
- }
65
- if (process.env.LEZU_FORMAT) {
66
- config.format = process.env.LEZU_FORMAT;
67
- }
68
- if (process.env.LEZU_ENVIRONMENT) {
69
- config.environment = process.env.LEZU_ENVIRONMENT;
70
- }
71
- config = { ...config, ...options };
72
- try {
73
- return ConfigSchema.parse(config);
74
- } catch (error) {
75
- if (error instanceof Error) {
76
- throw new Error(`Invalid configuration: ${error.message}`);
77
- }
78
- throw error;
79
- }
80
- }
81
- function validateConfig(config) {
82
- const errors = [];
83
- if (!config.projectId) {
84
- errors.push("Project ID is required (use --project, LEZU_PROJECT_ID env var, or projectId in config file)");
85
- }
86
- if (!config.apiKey) {
87
- errors.push("API Key is required (use --api-key, LEZU_API_KEY env var, or apiKey in config file)");
88
- }
89
- return errors;
90
- }
91
-
92
- export {
93
- loadConfig,
94
- validateConfig
95
- };
96
- //# sourceMappingURL=chunk-EDQCBUBB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config.ts","../src/types.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs'\nimport { resolve } from 'path'\nimport dotenv from 'dotenv'\nimport { Config, ConfigSchema } from './types.js'\n\n// Load environment variables\ndotenv.config()\n\nexport function loadConfig(options: Partial<Config> = {}): Config {\n // 1. Start with defaults\n let config: Partial<Config> = {\n apiUrl: 'https://api.lezu.app',\n dest: './src/i18n',\n format: 'json',\n environment: 'production',\n flatten: false,\n namespace: false,\n includeEmpty: false,\n watch: false,\n watchInterval: 5000\n }\n\n // 2. Load from config file (only JSON files to avoid JS module complexity)\n const configFiles = ['.lezurc', '.lezurc.json', 'lezu.config.json']\n for (const file of configFiles) {\n const configPath = resolve(process.cwd(), file)\n if (existsSync(configPath)) {\n try {\n // JSON config files only\n const content = readFileSync(configPath, 'utf-8')\n const fileConfig = JSON.parse(content)\n config = { ...config, ...fileConfig }\n // Don't log in production to keep output clean\n break\n } catch (error) {\n console.warn(`[Warning] Failed to load config from ${file}:`, error)\n }\n }\n }\n\n // 3. Load from environment variables\n if (process.env.LEZU_PROJECT_ID) {\n config.projectId = process.env.LEZU_PROJECT_ID\n }\n if (process.env.LEZU_API_KEY) {\n config.apiKey = process.env.LEZU_API_KEY\n }\n if (process.env.LEZU_API_URL) {\n config.apiUrl = process.env.LEZU_API_URL\n }\n if (process.env.LEZU_DEST) {\n config.dest = process.env.LEZU_DEST\n }\n if (process.env.LEZU_FORMAT) {\n config.format = process.env.LEZU_FORMAT as any\n }\n if (process.env.LEZU_ENVIRONMENT) {\n config.environment = process.env.LEZU_ENVIRONMENT\n }\n\n // 4. Apply CLI options (highest priority)\n config = { ...config, ...options }\n\n // 5. Validate and return\n try {\n return ConfigSchema.parse(config)\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Invalid configuration: ${error.message}`)\n }\n throw error\n }\n}\n\nexport function validateConfig(config: Config): string[] {\n const errors: string[] = []\n\n if (!config.projectId) {\n errors.push('Project ID is required (use --project, LEZU_PROJECT_ID env var, or projectId in config file)')\n }\n\n if (!config.apiKey) {\n errors.push('API Key is required (use --api-key, LEZU_API_KEY env var, or apiKey in config file)')\n }\n\n return errors\n}","import { z } from 'zod'\n\nexport const ConfigSchema = z.object({\n projectId: z.string().optional(),\n apiKey: z.string().optional(),\n apiUrl: z.string().default('https://api.lezu.app'),\n dest: z.string().default('./src/i18n'),\n format: z.enum(['json', 'js', 'ts', 'yaml', 'po']).default('json'),\n languages: z.array(z.string()).optional(),\n release: z.string().optional(),\n environment: z.string().default('production'),\n flatten: z.boolean().default(false),\n namespace: z.boolean().default(false),\n includeEmpty: z.boolean().default(false),\n watch: z.boolean().default(false),\n watchInterval: z.number().default(5000),\n debug: z.boolean().default(false)\n})\n\nexport type Config = z.infer<typeof ConfigSchema>\n\nexport interface TranslationBundle {\n [key: string]: string | TranslationBundle\n}\n\nexport interface ApiResponse {\n translations: Record<string, any>\n meta?: {\n version?: string\n timestamp?: string\n languages?: string[]\n }\n}\n\nexport interface ReleaseResponse {\n releases: Array<{\n id: string\n version: string\n name?: string\n created_at: string\n }>\n}"],"mappings":"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","names":[]}
@@ -1,300 +0,0 @@
1
- import {
2
- loadConfig,
3
- validateConfig
4
- } from "./chunk-EDQCBUBB.js";
5
- import {
6
- LezuApiClient
7
- } from "./chunk-V2UO7VTR.js";
8
-
9
- // src/commands/load.ts
10
- import { Command } from "commander";
11
- import chalk from "chalk";
12
- import ora from "ora";
13
- import { confirm, isCancel, text } from "@clack/prompts";
14
-
15
- // src/writer.ts
16
- import { writeFileSync, mkdirSync } from "fs";
17
- import { dirname, join } from "path";
18
- var TranslationWriter = class {
19
- config;
20
- constructor(config) {
21
- this.config = config;
22
- }
23
- write(translations) {
24
- mkdirSync(this.config.dest, { recursive: true });
25
- for (const [language, content] of Object.entries(translations)) {
26
- const processedContent = this.processContent(content);
27
- const filePath = this.getFilePath(language);
28
- mkdirSync(dirname(filePath), { recursive: true });
29
- const fileContent = this.formatContent(processedContent, language);
30
- writeFileSync(filePath, fileContent, "utf-8");
31
- console.log(`[Written] ${language} translations to ${filePath}`);
32
- }
33
- }
34
- processContent(content) {
35
- if (this.config.flatten) {
36
- return this.flattenObject(content);
37
- }
38
- if (!this.config.includeEmpty) {
39
- return this.removeEmptyValues(content);
40
- }
41
- return content;
42
- }
43
- flattenObject(obj, prefix = "") {
44
- const result = {};
45
- for (const [key, value] of Object.entries(obj)) {
46
- const newKey = prefix ? `${prefix}.${key}` : key;
47
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
48
- Object.assign(result, this.flattenObject(value, newKey));
49
- } else {
50
- result[newKey] = value;
51
- }
52
- }
53
- return result;
54
- }
55
- removeEmptyValues(obj) {
56
- if (typeof obj !== "object" || obj === null) {
57
- return obj;
58
- }
59
- const result = {};
60
- for (const [key, value] of Object.entries(obj)) {
61
- if (typeof value === "object" && value !== null) {
62
- const cleaned = this.removeEmptyValues(value);
63
- if (Object.keys(cleaned).length > 0) {
64
- result[key] = cleaned;
65
- }
66
- } else if (value !== "" && value !== null && value !== void 0) {
67
- result[key] = value;
68
- }
69
- }
70
- return result;
71
- }
72
- getFilePath(language) {
73
- const extension = this.getFileExtension();
74
- if (this.config.namespace) {
75
- return join(this.config.dest, "locales", `${language}.${extension}`);
76
- } else {
77
- return join(this.config.dest, `${language}.${extension}`);
78
- }
79
- }
80
- getFileExtension() {
81
- switch (this.config.format) {
82
- case "json":
83
- return "json";
84
- case "js":
85
- return "js";
86
- case "ts":
87
- return "ts";
88
- case "yaml":
89
- return "yaml";
90
- case "po":
91
- return "po";
92
- default:
93
- return "json";
94
- }
95
- }
96
- formatContent(content, language) {
97
- switch (this.config.format) {
98
- case "json":
99
- return JSON.stringify(content, null, 2);
100
- case "js":
101
- return `export default ${JSON.stringify(content, null, 2)}`;
102
- case "ts":
103
- return `const translations = ${JSON.stringify(content, null, 2)} as const
104
-
105
- export default translations`;
106
- case "yaml":
107
- return this.toYaml(content);
108
- case "po":
109
- return this.toPo(content, language);
110
- default:
111
- return JSON.stringify(content, null, 2);
112
- }
113
- }
114
- toYaml(obj, indent = 0) {
115
- let result = "";
116
- const spaces = " ".repeat(indent);
117
- for (const [key, value] of Object.entries(obj)) {
118
- if (typeof value === "object" && value !== null) {
119
- result += `${spaces}${key}:
120
- ${this.toYaml(value, indent + 2)}`;
121
- } else {
122
- const escapedValue = String(value).includes(":") || String(value).includes("#") ? `"${String(value).replace(/"/g, '\\"')}"` : value;
123
- result += `${spaces}${key}: ${escapedValue}
124
- `;
125
- }
126
- }
127
- return result;
128
- }
129
- toPo(obj, language) {
130
- const now = (/* @__PURE__ */ new Date()).toISOString();
131
- let result = `# Translation file for ${language}
132
- # Generated by Lezu CLI on ${now}
133
- msgid ""
134
- msgstr ""
135
- "Language: ${language}\\n"
136
- "MIME-Version: 1.0\\n"
137
- "Content-Type: text/plain; charset=UTF-8\\n"
138
- "Content-Transfer-Encoding: 8bit\\n"
139
- "Generated-By: Lezu CLI\\n"
140
-
141
- `;
142
- const flatEntries = this.flattenForPo(obj);
143
- for (const [key, value] of Object.entries(flatEntries)) {
144
- const escapedKey = this.escapePoString(key);
145
- const escapedValue = this.escapePoString(String(value));
146
- result += `msgid "${escapedKey}"
147
- `;
148
- result += `msgstr "${escapedValue}"
149
-
150
- `;
151
- }
152
- return result;
153
- }
154
- flattenForPo(obj, prefix = "") {
155
- const result = {};
156
- for (const [key, value] of Object.entries(obj)) {
157
- const fullKey = prefix ? `${prefix}.${key}` : key;
158
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
159
- Object.assign(result, this.flattenForPo(value, fullKey));
160
- } else {
161
- result[fullKey] = String(value);
162
- }
163
- }
164
- return result;
165
- }
166
- escapePoString(str) {
167
- return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
168
- }
169
- };
170
-
171
- // src/commands/load.ts
172
- function createLoadCommand() {
173
- const command = new Command("load").description("Download translation files from Lezu").option("-p, --project <id>", "Project ID").option("-k, --api-key <key>", "API key").option("-d, --dest <path>", "Destination folder", "./src/i18n").option("-f, --format <format>", "Output format (json, js, ts, yaml, po)", "json").option("-l, --languages <languages>", "Comma-separated list of languages to download").option("-r, --release <id>", "Specific release ID").option("-e, --environment <env>", "Environment", "production").option("--api-url <url>", "API URL", "https://api.lezu.app").option("--flatten", "Flatten nested keys").option("--namespace", "Use namespace folder structure").option("--include-empty", "Include empty translations").option("-w, --watch", "Watch for changes").option("--watch-interval <ms>", "Watch interval in milliseconds", "5000").action(async (options) => {
174
- try {
175
- if (options.languages) {
176
- options.languages = options.languages.split(",").map((l) => l.trim());
177
- }
178
- if (options.watchInterval) {
179
- options.watchInterval = parseInt(options.watchInterval, 10);
180
- }
181
- const config = loadConfig(options);
182
- const errors = validateConfig(config);
183
- if (errors.length > 0) {
184
- console.error(chalk.red("Configuration errors:"));
185
- errors.forEach((error) => console.error(chalk.red(` - ${error}`)));
186
- process.exit(1);
187
- }
188
- await syncTranslations(config);
189
- if (config.watch) {
190
- console.log(chalk.cyan(`
191
- [Watching] Monitoring for changes every ${config.watchInterval}ms...`));
192
- console.log(chalk.gray("Press Ctrl+C to stop"));
193
- setInterval(async () => {
194
- console.log(chalk.gray("\n[Checking] Looking for updates..."));
195
- await syncTranslations(config);
196
- }, config.watchInterval);
197
- }
198
- } catch (error) {
199
- console.error(chalk.red("\n[Error]"), error instanceof Error ? error.message : error);
200
- process.exit(1);
201
- }
202
- });
203
- return command;
204
- }
205
- async function syncTranslations(config) {
206
- const spinner = ora("Connecting to Lezu API...").start();
207
- try {
208
- const client = new LezuApiClient(config);
209
- if (!config.languages || config.languages.length === 0) {
210
- spinner.text = "Fetching project languages...";
211
- try {
212
- const projectData = await client.getProject();
213
- const projectLanguages = projectData.project.languages || ["en"];
214
- config.languages = Array.isArray(projectLanguages) ? projectLanguages.map((lang) => typeof lang === "string" ? lang : lang.code) : ["en"];
215
- spinner.info(`Using project languages: ${config.languages.join(", ")}`);
216
- spinner.start("Connecting to Lezu API...");
217
- } catch (error) {
218
- spinner.warn('Could not fetch project languages, defaulting to "en"');
219
- config.languages = ["en"];
220
- spinner.start("Connecting to Lezu API...");
221
- }
222
- }
223
- if (!config.release) {
224
- spinner.text = "Fetching latest release...";
225
- const latestRelease = await client.getLatestRelease();
226
- if (latestRelease) {
227
- config.release = latestRelease;
228
- spinner.succeed(`Using latest release: ${latestRelease}`);
229
- spinner.start("Fetching translations...");
230
- } else {
231
- spinner.fail("No releases found");
232
- console.log(chalk.yellow("\n\u26A0\uFE0F No releases found for this project."));
233
- console.log(chalk.gray("Releases provide cached, versioned snapshots that are fast and efficient."));
234
- const shouldCreateRelease = await confirm({
235
- message: "Would you like to create a release now?",
236
- initialValue: true
237
- });
238
- if (isCancel(shouldCreateRelease) || !shouldCreateRelease) {
239
- console.log(chalk.red("\n\u2716 A release is required to download translations"));
240
- console.log(chalk.gray("\nOptions:"));
241
- console.log(chalk.gray(" 1. Create a release through the Lezu dashboard"));
242
- console.log(chalk.gray(" 2. Use: npx lezu release create"));
243
- process.exit(1);
244
- }
245
- const version = await text({
246
- message: "Version",
247
- placeholder: (/* @__PURE__ */ new Date()).toISOString().split("T")[0].replace(/-/g, "."),
248
- initialValue: (/* @__PURE__ */ new Date()).toISOString().split("T")[0].replace(/-/g, ".")
249
- });
250
- if (isCancel(version)) {
251
- console.log(chalk.yellow("\nOperation cancelled"));
252
- process.exit(0);
253
- }
254
- spinner.start("Creating release...");
255
- try {
256
- const release = await client.createRelease({
257
- version,
258
- name: "Initial Release",
259
- description: "Created by Lezu CLI"
260
- });
261
- config.release = release.release.id;
262
- spinner.succeed(`Created release v${release.release.version}`);
263
- spinner.start("Fetching translations...");
264
- } catch (error) {
265
- spinner.fail("Failed to create release");
266
- console.log(chalk.red("\n\u2716 Cannot continue without a release"));
267
- console.log(chalk.gray("Please check your permissions or try again later."));
268
- process.exit(1);
269
- }
270
- }
271
- }
272
- spinner.text = "Fetching translations...";
273
- const response = await client.getTranslations();
274
- if (!response.translations || Object.keys(response.translations).length === 0) {
275
- spinner.fail("No translations found");
276
- return;
277
- }
278
- spinner.succeed(`Fetched translations for ${Object.keys(response.translations).length} languages`);
279
- const writer = new TranslationWriter(config);
280
- writer.write(response.translations);
281
- console.log(chalk.green("\n[Success] Translations synced successfully!"));
282
- console.log(chalk.gray("\nSummary:"));
283
- console.log(chalk.gray(` - Project: ${config.projectId}`));
284
- console.log(chalk.gray(` - Languages: ${Object.keys(response.translations).join(", ")}`));
285
- console.log(chalk.gray(` - Destination: ${config.dest}`));
286
- console.log(chalk.gray(` - Format: ${config.format}`));
287
- if (response.meta?.version) {
288
- console.log(chalk.gray(` - Version: ${response.meta.version}`));
289
- }
290
- } catch (error) {
291
- spinner.fail("Failed to sync translations");
292
- throw error;
293
- }
294
- }
295
-
296
- export {
297
- createLoadCommand,
298
- syncTranslations
299
- };
300
- //# sourceMappingURL=chunk-HORO6WMJ.js.map