lezu 0.0.25 → 0.0.27
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/dist/api-GAITHTMN.js +7 -0
- package/dist/{chunk-EVS3X4J2.js → chunk-2VL7SDZF.js} +2 -3
- package/dist/chunk-2VL7SDZF.js.map +1 -0
- package/dist/{chunk-XLG4OXOO.js → chunk-3IKM5VEF.js} +3 -3
- package/dist/{chunk-WZDLWLM3.js → chunk-DDC5YFYH.js} +43 -13
- package/dist/chunk-DDC5YFYH.js.map +1 -0
- package/dist/{chunk-CUKGTW6G.js → chunk-E7WFVQV4.js} +3 -3
- package/dist/get-FF4GMUHS.js +9 -0
- package/dist/index.js +313 -165
- package/dist/index.js.map +1 -1
- package/dist/load-WQ7PB665.js +11 -0
- package/package.json +2 -1
- package/dist/api-PFXU7GZT.js +0 -7
- package/dist/chunk-EVS3X4J2.js.map +0 -1
- package/dist/chunk-WZDLWLM3.js.map +0 -1
- package/dist/get-N7YBCERI.js +0 -9
- package/dist/load-5U463JIB.js +0 -11
- /package/dist/{api-PFXU7GZT.js.map → api-GAITHTMN.js.map} +0 -0
- /package/dist/{chunk-XLG4OXOO.js.map → chunk-3IKM5VEF.js.map} +0 -0
- /package/dist/{chunk-CUKGTW6G.js.map → chunk-E7WFVQV4.js.map} +0 -0
- /package/dist/{get-N7YBCERI.js.map → get-FF4GMUHS.js.map} +0 -0
- /package/dist/{load-5U463JIB.js.map → load-WQ7PB665.js.map} +0 -0
|
@@ -35,7 +35,7 @@ function loadConfig(options = {}) {
|
|
|
35
35
|
watch: false,
|
|
36
36
|
watchInterval: 5e3
|
|
37
37
|
};
|
|
38
|
-
const configFiles = [".lezurc", ".lezurc.json"];
|
|
38
|
+
const configFiles = [".lezurc", ".lezurc.json", "lezu.config.json"];
|
|
39
39
|
for (const file of configFiles) {
|
|
40
40
|
const configPath = resolve(process.cwd(), file);
|
|
41
41
|
if (existsSync(configPath)) {
|
|
@@ -43,7 +43,6 @@ function loadConfig(options = {}) {
|
|
|
43
43
|
const content = readFileSync(configPath, "utf-8");
|
|
44
44
|
const fileConfig = JSON.parse(content);
|
|
45
45
|
config = { ...config, ...fileConfig };
|
|
46
|
-
console.log(`[Config] Loaded from ${file}`);
|
|
47
46
|
break;
|
|
48
47
|
} catch (error) {
|
|
49
48
|
console.warn(`[Warning] Failed to load config from ${file}:`, error);
|
|
@@ -93,4 +92,4 @@ export {
|
|
|
93
92
|
loadConfig,
|
|
94
93
|
validateConfig
|
|
95
94
|
};
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-2VL7SDZF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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})\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":";AAAA,SAAS,cAAc,kBAAkB;AACzC,SAAS,eAAe;AACxB,OAAO,YAAY;;;ACFnB,SAAS,SAAS;AAEX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,QAAQ,sBAAsB;AAAA,EACjD,MAAM,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EACrC,QAAQ,EAAE,KAAK,CAAC,QAAQ,MAAM,MAAM,QAAQ,IAAI,CAAC,EAAE,QAAQ,MAAM;AAAA,EACjE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EAC5C,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,WAAW,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAChC,eAAe,EAAE,OAAO,EAAE,QAAQ,GAAI;AACxC,CAAC;;;ADVD,OAAO,OAAO;AAEP,SAAS,WAAW,UAA2B,CAAC,GAAW;AAEhE,MAAI,SAA0B;AAAA,IAC5B,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,IACX,cAAc;AAAA,IACd,OAAO;AAAA,IACP,eAAe;AAAA,EACjB;AAGA,QAAM,cAAc,CAAC,WAAW,gBAAgB,kBAAkB;AAClE,aAAW,QAAQ,aAAa;AAC9B,UAAM,aAAa,QAAQ,QAAQ,IAAI,GAAG,IAAI;AAC9C,QAAI,WAAW,UAAU,GAAG;AAC1B,UAAI;AAEF,cAAM,UAAU,aAAa,YAAY,OAAO;AAChD,cAAM,aAAa,KAAK,MAAM,OAAO;AACrC,iBAAS,EAAE,GAAG,QAAQ,GAAG,WAAW;AAEpC;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,KAAK,wCAAwC,IAAI,KAAK,KAAK;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAGA,MAAI,QAAQ,IAAI,iBAAiB;AAC/B,WAAO,YAAY,QAAQ,IAAI;AAAA,EACjC;AACA,MAAI,QAAQ,IAAI,cAAc;AAC5B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,cAAc;AAC5B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,WAAW;AACzB,WAAO,OAAO,QAAQ,IAAI;AAAA,EAC5B;AACA,MAAI,QAAQ,IAAI,aAAa;AAC3B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,kBAAkB;AAChC,WAAO,cAAc,QAAQ,IAAI;AAAA,EACnC;AAGA,WAAS,EAAE,GAAG,QAAQ,GAAG,QAAQ;AAGjC,MAAI;AACF,WAAO,aAAa,MAAM,MAAM;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,YAAM,IAAI,MAAM,0BAA0B,MAAM,OAAO,EAAE;AAAA,IAC3D;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,eAAe,QAA0B;AACvD,QAAM,SAAmB,CAAC;AAE1B,MAAI,CAAC,OAAO,WAAW;AACrB,WAAO,KAAK,8FAA8F;AAAA,EAC5G;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO,KAAK,qFAAqF;AAAA,EACnG;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
validateConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2VL7SDZF.js";
|
|
5
5
|
import {
|
|
6
6
|
LezuApiClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DDC5YFYH.js";
|
|
8
8
|
|
|
9
9
|
// src/commands/load.ts
|
|
10
10
|
import { Command } from "commander";
|
|
@@ -245,4 +245,4 @@ export {
|
|
|
245
245
|
createLoadCommand,
|
|
246
246
|
syncTranslations
|
|
247
247
|
};
|
|
248
|
-
//# sourceMappingURL=chunk-
|
|
248
|
+
//# sourceMappingURL=chunk-3IKM5VEF.js.map
|
|
@@ -7,20 +7,50 @@ var LezuApiClient = class {
|
|
|
7
7
|
}
|
|
8
8
|
async request(endpoint, options = {}) {
|
|
9
9
|
const url = `${this.config.apiUrl}${endpoint}`;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(url, {
|
|
12
|
+
...options,
|
|
13
|
+
headers: {
|
|
14
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
15
|
+
"Content-Type": "application/json",
|
|
16
|
+
...options.headers
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
let errorMessage = "";
|
|
21
|
+
let errorData;
|
|
22
|
+
try {
|
|
23
|
+
const errorText = await response.text();
|
|
24
|
+
errorData = JSON.parse(errorText);
|
|
25
|
+
errorMessage = errorData.error || errorData.message || errorText;
|
|
26
|
+
} catch {
|
|
27
|
+
errorMessage = await response.text();
|
|
28
|
+
}
|
|
29
|
+
if (response.status === 401) {
|
|
30
|
+
throw new Error("Authentication failed. Please check your API key.");
|
|
31
|
+
} else if (response.status === 403) {
|
|
32
|
+
throw new Error("Access denied. Your API key may not have permission for this action.");
|
|
33
|
+
} else if (response.status === 404) {
|
|
34
|
+
throw new Error("Resource not found. Please check your project ID and configuration.");
|
|
35
|
+
} else if (response.status === 500) {
|
|
36
|
+
if (errorMessage.includes("project") || errorMessage.includes("not found")) {
|
|
37
|
+
throw new Error("Project not found. Please verify your project ID is correct.");
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`Server error: ${errorMessage || "Something went wrong on the server"}`);
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error(`API error (${response.status}): ${errorMessage || response.statusText}`);
|
|
42
|
+
}
|
|
16
43
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
${
|
|
44
|
+
return response.json();
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error instanceof Error) {
|
|
47
|
+
if (error.message.includes("ENOTFOUND") || error.message.includes("ECONNREFUSED")) {
|
|
48
|
+
throw new Error(`Cannot connect to Lezu API at ${this.config.apiUrl}. Please check your internet connection and API URL.`);
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
throw new Error("An unexpected error occurred");
|
|
22
53
|
}
|
|
23
|
-
return response.json();
|
|
24
54
|
}
|
|
25
55
|
async getTranslations() {
|
|
26
56
|
let endpoint = `/v1/translations/bundle?environment=${this.config.environment}`;
|
|
@@ -106,4 +136,4 @@ ${error}`);
|
|
|
106
136
|
export {
|
|
107
137
|
LezuApiClient
|
|
108
138
|
};
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
139
|
+
//# sourceMappingURL=chunk-DDC5YFYH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api.ts"],"sourcesContent":["import fetch from 'node-fetch'\nimport type { Config, ApiResponse, ReleaseResponse } from './types.js'\n\nexport class LezuApiClient {\n private config: Config\n\n constructor(config: Config) {\n this.config = config\n }\n\n private async request<T>(endpoint: string, options: any = {}): Promise<T> {\n const url = `${this.config.apiUrl}${endpoint}`\n \n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n ...options.headers\n }\n })\n\n if (!response.ok) {\n let errorMessage = ''\n let errorData: any\n \n try {\n const errorText = await response.text()\n errorData = JSON.parse(errorText)\n errorMessage = errorData.error || errorData.message || errorText\n } catch {\n errorMessage = await response.text()\n }\n\n // Provide user-friendly error messages\n if (response.status === 401) {\n throw new Error('Authentication failed. Please check your API key.')\n } else if (response.status === 403) {\n throw new Error('Access denied. Your API key may not have permission for this action.')\n } else if (response.status === 404) {\n throw new Error('Resource not found. Please check your project ID and configuration.')\n } else if (response.status === 500) {\n // Check for common 500 errors\n if (errorMessage.includes('project') || errorMessage.includes('not found')) {\n throw new Error('Project not found. Please verify your project ID is correct.')\n }\n throw new Error(`Server error: ${errorMessage || 'Something went wrong on the server'}`)\n } else {\n throw new Error(`API error (${response.status}): ${errorMessage || response.statusText}`)\n }\n }\n\n return response.json() as Promise<T>\n } catch (error) {\n if (error instanceof Error) {\n // Check for network errors\n if (error.message.includes('ENOTFOUND') || error.message.includes('ECONNREFUSED')) {\n throw new Error(`Cannot connect to Lezu API at ${this.config.apiUrl}. Please check your internet connection and API URL.`)\n }\n throw error\n }\n throw new Error('An unexpected error occurred')\n }\n }\n\n async getTranslations(): Promise<ApiResponse> {\n let endpoint = `/v1/translations/bundle?environment=${this.config.environment}`\n \n if (this.config.release) {\n endpoint = `/v1/releases/${this.config.release}/bundle`\n }\n\n // Add language filter if specified\n if (this.config.languages && this.config.languages.length > 0) {\n const params = new URLSearchParams()\n this.config.languages.forEach(lang => params.append('languages', lang))\n endpoint += `?${params.toString()}`\n }\n\n const response = await this.request<any>(endpoint)\n \n // Transform the response to match our expected format\n return {\n translations: response.translations || response,\n meta: {\n version: response.version,\n timestamp: response.timestamp || new Date().toISOString(),\n languages: response.languages || Object.keys(response.translations || response)\n }\n }\n }\n\n async getReleases(): Promise<ReleaseResponse> {\n return this.request<ReleaseResponse>(\n `/v1/releases?environment=${this.config.environment}`\n )\n }\n\n async getLatestRelease(): Promise<string | null> {\n try {\n const releases = await this.getReleases()\n if (releases.releases && releases.releases.length > 0) {\n // Releases are ordered by created_at desc, so first one is latest\n return releases.releases[0].id\n }\n return null\n } catch (error) {\n console.warn('Failed to fetch latest release:', error)\n return null\n }\n }\n\n async getLanguages(): Promise<any> {\n return this.request<any>(`/v1/languages`)\n }\n\n async addTranslationKey(key: string, translations: Record<string, string>): Promise<any> {\n return this.request<any>(\n `/v1/keys`,\n {\n method: 'POST',\n body: JSON.stringify({ key, translations })\n }\n )\n }\n\n async translateKey(text: string, sourceLanguage: string, targetLanguages: string[]): Promise<Record<string, string>> {\n // Use batch translate for efficiency\n const response = await this.request<any>('/v1/translations/translate/batch', {\n method: 'POST',\n body: JSON.stringify({\n texts: [text],\n sourceLanguage,\n targetLanguages\n })\n })\n \n return response.translations[text] || {}\n }\n\n async createRelease(data: {\n version?: string\n name?: string\n description?: string\n reviewedOnly?: boolean\n } = {}): Promise<any> {\n return this.request<any>(\n `/v1/releases`,\n {\n method: 'POST',\n body: JSON.stringify({\n environment: this.config.environment || 'production',\n version: data.version || new Date().toISOString().split('T')[0],\n name: data.name,\n description: data.description,\n reviewedOnly: data.reviewedOnly || false,\n setAsCurrent: true\n })\n }\n )\n }\n\n async getProject(): Promise<any> {\n return this.request<any>(`/v1/projects/${this.config.projectId}`)\n }\n}"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
validateConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2VL7SDZF.js";
|
|
5
5
|
import {
|
|
6
6
|
LezuApiClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DDC5YFYH.js";
|
|
8
8
|
|
|
9
9
|
// src/commands/get.ts
|
|
10
10
|
import { Command } from "commander";
|
|
@@ -214,4 +214,4 @@ async function getProject(config, options) {
|
|
|
214
214
|
export {
|
|
215
215
|
createGetCommand
|
|
216
216
|
};
|
|
217
|
-
//# sourceMappingURL=chunk-
|
|
217
|
+
//# sourceMappingURL=chunk-E7WFVQV4.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createLoadCommand
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3IKM5VEF.js";
|
|
4
4
|
import {
|
|
5
5
|
createGetCommand
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-E7WFVQV4.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig,
|
|
9
9
|
validateConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2VL7SDZF.js";
|
|
11
11
|
import {
|
|
12
12
|
LezuApiClient
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DDC5YFYH.js";
|
|
14
14
|
|
|
15
15
|
// src/index.ts
|
|
16
16
|
import { program } from "commander";
|
|
@@ -38,15 +38,15 @@ function createAddCommand() {
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
if (options.value && Object.keys(translations).length === 0) {
|
|
41
|
-
const
|
|
41
|
+
const spinner2 = ora("Getting project information...").start();
|
|
42
42
|
const client = new LezuApiClient(config);
|
|
43
43
|
try {
|
|
44
44
|
const { project } = await client.getProject();
|
|
45
45
|
const sourceLanguage = project.source_language || "en";
|
|
46
46
|
translations[sourceLanguage] = options.value;
|
|
47
|
-
|
|
47
|
+
spinner2.succeed(`Using ${sourceLanguage} as source language`);
|
|
48
48
|
} catch (error) {
|
|
49
|
-
|
|
49
|
+
spinner2.fail("Failed to get project information");
|
|
50
50
|
translations["en"] = options.value;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -64,11 +64,11 @@ function createAddCommand() {
|
|
|
64
64
|
return command;
|
|
65
65
|
}
|
|
66
66
|
async function addTranslationKey(config, options) {
|
|
67
|
-
const
|
|
67
|
+
const spinner2 = ora("Adding translation key...").start();
|
|
68
68
|
try {
|
|
69
69
|
const client = new LezuApiClient(config);
|
|
70
70
|
const response = await client.addTranslationKey(options.key, options.translations);
|
|
71
|
-
|
|
71
|
+
spinner2.succeed("Translation key added successfully!");
|
|
72
72
|
console.log(chalk.green("\n[Success] Key added:"));
|
|
73
73
|
console.log(chalk.gray(` - Key: ${options.key}`));
|
|
74
74
|
if (options.description) {
|
|
@@ -85,7 +85,7 @@ async function addTranslationKey(config, options) {
|
|
|
85
85
|
console.log(chalk.cyan("\n[AI] Auto-translation was enabled. Check the dashboard to review AI-generated translations."));
|
|
86
86
|
}
|
|
87
87
|
} catch (error) {
|
|
88
|
-
|
|
88
|
+
spinner2.fail("Failed to add translation key");
|
|
89
89
|
throw error;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -135,7 +135,7 @@ function createReleaseCommand() {
|
|
|
135
135
|
errors.forEach((error) => console.error(chalk2.red(` - ${error}`)));
|
|
136
136
|
process.exit(1);
|
|
137
137
|
}
|
|
138
|
-
const { getReleases } = await import("./get-
|
|
138
|
+
const { getReleases } = await import("./get-FF4GMUHS.js");
|
|
139
139
|
await getReleases(config, options);
|
|
140
140
|
} catch (error) {
|
|
141
141
|
console.error(chalk2.red("\n[Error]"), error instanceof Error ? error.message : error);
|
|
@@ -145,7 +145,7 @@ function createReleaseCommand() {
|
|
|
145
145
|
return command;
|
|
146
146
|
}
|
|
147
147
|
async function createRelease(config, options) {
|
|
148
|
-
const
|
|
148
|
+
const spinner2 = ora2("Creating release...").start();
|
|
149
149
|
try {
|
|
150
150
|
const client = new LezuApiClient(config);
|
|
151
151
|
const languages = options.languages ? options.languages.split(",").map((l) => l.trim()) : void 0;
|
|
@@ -167,9 +167,9 @@ async function createRelease(config, options) {
|
|
|
167
167
|
timestamp,
|
|
168
168
|
languages
|
|
169
169
|
};
|
|
170
|
-
|
|
170
|
+
spinner2.text = "Creating release and generating bundles...";
|
|
171
171
|
const response = await client.createRelease(releaseData);
|
|
172
|
-
|
|
172
|
+
spinner2.succeed("Release created successfully!");
|
|
173
173
|
if (options.json) {
|
|
174
174
|
console.log(JSON.stringify(response, null, 2));
|
|
175
175
|
return;
|
|
@@ -202,12 +202,12 @@ Total: ${response.release.artifacts.length} language bundles`));
|
|
|
202
202
|
console.log(chalk2.green("\n[Success] This release is now set as current!"));
|
|
203
203
|
}
|
|
204
204
|
} catch (error) {
|
|
205
|
-
|
|
205
|
+
spinner2.fail("Failed to create release");
|
|
206
206
|
throw error;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
async function setCurrentRelease(config, releaseId, options) {
|
|
210
|
-
const
|
|
210
|
+
const spinner2 = ora2("Setting release as current...").start();
|
|
211
211
|
try {
|
|
212
212
|
const response = await fetch(`${config.apiUrl}/v1/releases/${releaseId}/current`, {
|
|
213
213
|
method: "PUT",
|
|
@@ -222,7 +222,7 @@ async function setCurrentRelease(config, releaseId, options) {
|
|
|
222
222
|
${error}`);
|
|
223
223
|
}
|
|
224
224
|
const data = await response.json();
|
|
225
|
-
|
|
225
|
+
spinner2.succeed("Release set as current!");
|
|
226
226
|
if (options.json) {
|
|
227
227
|
console.log(JSON.stringify(data, null, 2));
|
|
228
228
|
return;
|
|
@@ -232,108 +232,136 @@ ${error}`);
|
|
|
232
232
|
console.log(" Status: Now set as current release");
|
|
233
233
|
console.log(chalk2.cyan("\n[Info] All new bundle requests will now use this release"));
|
|
234
234
|
} catch (error) {
|
|
235
|
-
|
|
235
|
+
spinner2.fail("Failed to set release as current");
|
|
236
236
|
throw error;
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
// src/interactive.ts
|
|
241
|
-
import
|
|
242
|
-
import { stdin as input, stdout as output } from "process";
|
|
243
|
-
import { promisify } from "util";
|
|
241
|
+
import { intro, outro, select, text, confirm, spinner, cancel, isCancel } from "@clack/prompts";
|
|
244
242
|
import chalk3 from "chalk";
|
|
245
243
|
async function interactiveMode(initialConfig) {
|
|
246
|
-
|
|
247
|
-
const question = promisify(rl.question).bind(rl);
|
|
248
|
-
console.log(chalk3.cyan("[Lezu CLI] Interactive Mode\n"));
|
|
249
|
-
console.log(chalk3.gray("What would you like to do?\n"));
|
|
244
|
+
intro(chalk3.cyan("Welcome to Lezu CLI!"));
|
|
250
245
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
) || initialConfig.apiKey;
|
|
288
|
-
if (!apiKey) {
|
|
289
|
-
throw new Error("API Key is required");
|
|
246
|
+
const command = await select({
|
|
247
|
+
message: "What would you like to do?",
|
|
248
|
+
options: [
|
|
249
|
+
{ value: "load", label: "Load translation files" },
|
|
250
|
+
{ value: "add", label: "Add a new translation key" },
|
|
251
|
+
{ value: "get", label: "Get project information" },
|
|
252
|
+
{ value: "release", label: "Manage releases" }
|
|
253
|
+
]
|
|
254
|
+
});
|
|
255
|
+
if (isCancel(command)) {
|
|
256
|
+
cancel("Operation cancelled");
|
|
257
|
+
process.exit(0);
|
|
258
|
+
}
|
|
259
|
+
const projectId = await text({
|
|
260
|
+
message: "Project ID",
|
|
261
|
+
placeholder: initialConfig.projectId || "Enter your project ID",
|
|
262
|
+
defaultValue: initialConfig.projectId,
|
|
263
|
+
validate: (value) => {
|
|
264
|
+
if (!value) return "Project ID is required";
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
if (isCancel(projectId)) {
|
|
268
|
+
cancel("Operation cancelled");
|
|
269
|
+
process.exit(0);
|
|
270
|
+
}
|
|
271
|
+
const apiKey = await text({
|
|
272
|
+
message: "API Key",
|
|
273
|
+
placeholder: initialConfig.apiKey ? "(press enter to use existing key)" : "Enter your API key",
|
|
274
|
+
defaultValue: initialConfig.apiKey,
|
|
275
|
+
validate: (value) => {
|
|
276
|
+
if (!value) return "API Key is required";
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
if (isCancel(apiKey)) {
|
|
280
|
+
cancel("Operation cancelled");
|
|
281
|
+
process.exit(0);
|
|
290
282
|
}
|
|
291
283
|
const config = loadConfig({ projectId, apiKey, ...initialConfig });
|
|
284
|
+
const validationSpinner = spinner();
|
|
285
|
+
validationSpinner.start("Validating credentials...");
|
|
286
|
+
try {
|
|
287
|
+
const { LezuApiClient: LezuApiClient2 } = await import("./api-GAITHTMN.js");
|
|
288
|
+
const client = new LezuApiClient2(config);
|
|
289
|
+
await client.getProject();
|
|
290
|
+
validationSpinner.stop("Credentials validated!");
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (error instanceof Error) {
|
|
293
|
+
validationSpinner.stop("Invalid credentials");
|
|
294
|
+
outro(chalk3.red(error.message));
|
|
295
|
+
} else {
|
|
296
|
+
validationSpinner.stop("Failed to validate credentials");
|
|
297
|
+
outro(chalk3.red("Could not connect to Lezu API"));
|
|
298
|
+
}
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
292
301
|
switch (command) {
|
|
293
302
|
case "load":
|
|
294
|
-
await configureLoadCommand(
|
|
303
|
+
await configureLoadCommand(config);
|
|
295
304
|
break;
|
|
296
305
|
case "add":
|
|
297
|
-
await configureAddCommand(
|
|
306
|
+
await configureAddCommand(config);
|
|
298
307
|
break;
|
|
299
308
|
case "get":
|
|
300
|
-
await configureGetCommand(
|
|
309
|
+
await configureGetCommand(config);
|
|
301
310
|
break;
|
|
302
311
|
case "release":
|
|
303
|
-
await configureReleaseCommand(
|
|
312
|
+
await configureReleaseCommand(config);
|
|
304
313
|
break;
|
|
305
314
|
}
|
|
315
|
+
outro(chalk3.green("Done!"));
|
|
306
316
|
} catch (error) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
317
|
+
if (error instanceof Error) {
|
|
318
|
+
outro(chalk3.red(error.message));
|
|
319
|
+
} else {
|
|
320
|
+
outro(chalk3.red("An unexpected error occurred"));
|
|
321
|
+
}
|
|
322
|
+
process.exit(1);
|
|
310
323
|
}
|
|
311
324
|
}
|
|
312
|
-
async function configureLoadCommand(
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
325
|
+
async function configureLoadCommand(config) {
|
|
326
|
+
const dest = await text({
|
|
327
|
+
message: "Destination folder",
|
|
328
|
+
placeholder: config.dest || "./src/i18n",
|
|
329
|
+
defaultValue: config.dest || "./src/i18n"
|
|
330
|
+
});
|
|
331
|
+
if (isCancel(dest)) {
|
|
332
|
+
cancel("Operation cancelled");
|
|
333
|
+
process.exit(0);
|
|
334
|
+
}
|
|
335
|
+
const format = await select({
|
|
336
|
+
message: "Output format",
|
|
337
|
+
options: [
|
|
338
|
+
{ value: "json", label: "JSON" },
|
|
339
|
+
{ value: "js", label: "JavaScript (ES modules)" },
|
|
340
|
+
{ value: "ts", label: "TypeScript" },
|
|
341
|
+
{ value: "yaml", label: "YAML" }
|
|
342
|
+
]
|
|
343
|
+
});
|
|
344
|
+
if (isCancel(format)) {
|
|
345
|
+
cancel("Operation cancelled");
|
|
346
|
+
process.exit(0);
|
|
347
|
+
}
|
|
348
|
+
const environment = await text({
|
|
349
|
+
message: "Environment",
|
|
350
|
+
placeholder: config.environment || "production",
|
|
351
|
+
defaultValue: config.environment || "production"
|
|
352
|
+
});
|
|
353
|
+
if (isCancel(environment)) {
|
|
354
|
+
cancel("Operation cancelled");
|
|
355
|
+
process.exit(0);
|
|
356
|
+
}
|
|
357
|
+
const languages = await text({
|
|
358
|
+
message: "Specific languages (comma-separated, leave empty for all)",
|
|
359
|
+
placeholder: "en,es,fr"
|
|
360
|
+
});
|
|
361
|
+
if (isCancel(languages)) {
|
|
362
|
+
cancel("Operation cancelled");
|
|
363
|
+
process.exit(0);
|
|
364
|
+
}
|
|
337
365
|
const finalConfig = {
|
|
338
366
|
...config,
|
|
339
367
|
dest,
|
|
@@ -341,108 +369,214 @@ async function configureLoadCommand(rl, config) {
|
|
|
341
369
|
environment,
|
|
342
370
|
languages: languages ? languages.split(",").map((l) => l.trim()) : void 0
|
|
343
371
|
};
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
372
|
+
const s = spinner();
|
|
373
|
+
s.start("Syncing translations...");
|
|
374
|
+
try {
|
|
375
|
+
const { syncTranslations } = await import("./load-WQ7PB665.js");
|
|
376
|
+
await syncTranslations(finalConfig);
|
|
377
|
+
s.stop("Translations synced successfully!");
|
|
378
|
+
} catch (error) {
|
|
379
|
+
if (error instanceof Error) {
|
|
380
|
+
s.stop(`Failed: ${error.message}`);
|
|
381
|
+
} else {
|
|
382
|
+
s.stop("Failed to sync translations");
|
|
383
|
+
}
|
|
384
|
+
throw error;
|
|
385
|
+
}
|
|
347
386
|
}
|
|
348
|
-
async function configureAddCommand(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
387
|
+
async function configureAddCommand(config) {
|
|
388
|
+
const key = await text({
|
|
389
|
+
message: "Translation key",
|
|
390
|
+
placeholder: "common.save",
|
|
391
|
+
validate: (value) => {
|
|
392
|
+
if (!value) return "Translation key is required";
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
if (isCancel(key)) {
|
|
396
|
+
cancel("Operation cancelled");
|
|
397
|
+
process.exit(0);
|
|
398
|
+
}
|
|
399
|
+
const description = await text({
|
|
400
|
+
message: "Description (optional)",
|
|
401
|
+
placeholder: "Save button text"
|
|
402
|
+
});
|
|
403
|
+
if (isCancel(description)) {
|
|
404
|
+
cancel("Operation cancelled");
|
|
405
|
+
process.exit(0);
|
|
406
|
+
}
|
|
407
|
+
const translationMethod = await select({
|
|
408
|
+
message: "How would you like to provide translations?",
|
|
409
|
+
options: [
|
|
410
|
+
{ value: "manual", label: "Provide translations manually" },
|
|
411
|
+
{ value: "auto", label: "Auto-translate from source language" }
|
|
412
|
+
]
|
|
413
|
+
});
|
|
414
|
+
if (isCancel(translationMethod)) {
|
|
415
|
+
cancel("Operation cancelled");
|
|
416
|
+
process.exit(0);
|
|
353
417
|
}
|
|
354
|
-
const description = await rl.question(chalk3.gray("Description (optional): "));
|
|
355
|
-
console.log(chalk3.gray("\nDo you want to:"));
|
|
356
|
-
console.log("1) Provide translations manually");
|
|
357
|
-
console.log("2) Auto-translate from source language");
|
|
358
|
-
const choice = await rl.question(chalk3.gray("Choice (1-2): ")) || "1";
|
|
359
418
|
let translations = {};
|
|
360
419
|
let auto = false;
|
|
361
|
-
if (
|
|
420
|
+
if (translationMethod === "auto") {
|
|
362
421
|
auto = true;
|
|
363
|
-
const sourceValue = await
|
|
364
|
-
|
|
365
|
-
|
|
422
|
+
const sourceValue = await text({
|
|
423
|
+
message: "Source language value",
|
|
424
|
+
placeholder: "Save",
|
|
425
|
+
validate: (value) => {
|
|
426
|
+
if (!value) return "Source value is required for auto-translation";
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
if (isCancel(sourceValue)) {
|
|
430
|
+
cancel("Operation cancelled");
|
|
431
|
+
process.exit(0);
|
|
366
432
|
}
|
|
433
|
+
translations.en = sourceValue;
|
|
367
434
|
} else {
|
|
368
|
-
console.log(chalk3.gray("\nEnter translations (press Enter to skip):"));
|
|
369
435
|
const languages = ["en", "es", "fr", "de", "nl"];
|
|
370
436
|
for (const lang of languages) {
|
|
371
|
-
const value = await
|
|
437
|
+
const value = await text({
|
|
438
|
+
message: `Translation for ${lang} (optional)`,
|
|
439
|
+
placeholder: `Enter ${lang} translation`
|
|
440
|
+
});
|
|
441
|
+
if (isCancel(value)) {
|
|
442
|
+
cancel("Operation cancelled");
|
|
443
|
+
process.exit(0);
|
|
444
|
+
}
|
|
372
445
|
if (value) {
|
|
373
446
|
translations[lang] = value;
|
|
374
447
|
}
|
|
375
448
|
}
|
|
376
449
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const client = new LezuApiClient2(config);
|
|
450
|
+
const s = spinner();
|
|
451
|
+
s.start("Adding translation key...");
|
|
380
452
|
try {
|
|
453
|
+
const { LezuApiClient: LezuApiClient2 } = await import("./api-GAITHTMN.js");
|
|
454
|
+
const client = new LezuApiClient2(config);
|
|
381
455
|
await client.addTranslationKey(key, translations);
|
|
382
|
-
|
|
456
|
+
s.stop("Translation key added successfully!");
|
|
457
|
+
if (auto) {
|
|
458
|
+
console.log(chalk3.cyan("\n[AI] Auto-translation was enabled. Check the dashboard to review AI-generated translations."));
|
|
459
|
+
}
|
|
383
460
|
} catch (error) {
|
|
384
|
-
|
|
461
|
+
if (error instanceof Error) {
|
|
462
|
+
s.stop(`Failed: ${error.message}`);
|
|
463
|
+
} else {
|
|
464
|
+
s.stop("Failed to add translation key");
|
|
465
|
+
}
|
|
466
|
+
throw error;
|
|
385
467
|
}
|
|
386
468
|
}
|
|
387
|
-
async function configureGetCommand(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
469
|
+
async function configureGetCommand(config) {
|
|
470
|
+
const infoType = await select({
|
|
471
|
+
message: "What information would you like to get?",
|
|
472
|
+
options: [
|
|
473
|
+
{ value: "project", label: "Project information" },
|
|
474
|
+
{ value: "languages", label: "Languages" },
|
|
475
|
+
{ value: "releases", label: "Releases" }
|
|
476
|
+
]
|
|
477
|
+
});
|
|
478
|
+
if (isCancel(infoType)) {
|
|
479
|
+
cancel("Operation cancelled");
|
|
480
|
+
process.exit(0);
|
|
481
|
+
}
|
|
482
|
+
const s = spinner();
|
|
483
|
+
s.start("Fetching information...");
|
|
395
484
|
try {
|
|
396
|
-
|
|
397
|
-
|
|
485
|
+
const { LezuApiClient: LezuApiClient2 } = await import("./api-GAITHTMN.js");
|
|
486
|
+
const client = new LezuApiClient2(config);
|
|
487
|
+
switch (infoType) {
|
|
488
|
+
case "project":
|
|
398
489
|
const project = await client.getProject();
|
|
399
|
-
|
|
490
|
+
s.stop("Project information:");
|
|
400
491
|
console.log(` Name: ${project.project.name}`);
|
|
401
492
|
console.log(` Key: ${project.project.key}`);
|
|
402
493
|
console.log(` Source Language: ${project.project.source_language}`);
|
|
403
494
|
break;
|
|
404
|
-
case "
|
|
495
|
+
case "languages":
|
|
405
496
|
const languages = await client.getLanguages();
|
|
406
|
-
|
|
497
|
+
s.stop("Languages:");
|
|
407
498
|
languages.languages?.forEach((lang) => {
|
|
408
|
-
const status = lang.enabled ? "[ON]" : "[OFF]";
|
|
499
|
+
const status = lang.enabled ? chalk3.green("[ON]") : chalk3.gray("[OFF]");
|
|
409
500
|
console.log(` ${status} ${lang.language?.name || lang.language_code}`);
|
|
410
501
|
});
|
|
411
502
|
break;
|
|
412
|
-
case "
|
|
503
|
+
case "releases":
|
|
413
504
|
const releases = await client.getReleases();
|
|
414
|
-
|
|
415
|
-
releases.releases?.slice(0,
|
|
416
|
-
const current = release.is_current ? " [CURRENT]" : "";
|
|
417
|
-
console.log(`
|
|
505
|
+
s.stop("Recent releases:");
|
|
506
|
+
releases.releases?.slice(0, 10).forEach((release) => {
|
|
507
|
+
const current = release.is_current ? chalk3.green(" [CURRENT]") : "";
|
|
508
|
+
console.log(` ${release.version}${current}`);
|
|
418
509
|
});
|
|
419
510
|
break;
|
|
420
511
|
}
|
|
421
512
|
} catch (error) {
|
|
422
|
-
|
|
513
|
+
if (error instanceof Error) {
|
|
514
|
+
s.stop(`Failed: ${error.message}`);
|
|
515
|
+
} else {
|
|
516
|
+
s.stop("Failed to fetch information");
|
|
517
|
+
}
|
|
518
|
+
throw error;
|
|
423
519
|
}
|
|
424
520
|
}
|
|
425
|
-
async function configureReleaseCommand(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
521
|
+
async function configureReleaseCommand(config) {
|
|
522
|
+
const action = await select({
|
|
523
|
+
message: "Release management",
|
|
524
|
+
options: [
|
|
525
|
+
{ value: "create", label: "Create new release" },
|
|
526
|
+
{ value: "list", label: "List releases" }
|
|
527
|
+
]
|
|
528
|
+
});
|
|
529
|
+
if (isCancel(action)) {
|
|
530
|
+
cancel("Operation cancelled");
|
|
531
|
+
process.exit(0);
|
|
532
|
+
}
|
|
533
|
+
const { LezuApiClient: LezuApiClient2 } = await import("./api-GAITHTMN.js");
|
|
534
|
+
const client = new LezuApiClient2(config);
|
|
535
|
+
if (action === "create") {
|
|
536
|
+
const version2 = await text({
|
|
537
|
+
message: "Version",
|
|
538
|
+
placeholder: "1.0.0",
|
|
539
|
+
validate: (value) => {
|
|
540
|
+
if (!value) return "Version is required";
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
if (isCancel(version2)) {
|
|
544
|
+
cancel("Operation cancelled");
|
|
545
|
+
process.exit(0);
|
|
546
|
+
}
|
|
547
|
+
const name = await text({
|
|
548
|
+
message: "Name (optional)",
|
|
549
|
+
placeholder: "Production Release"
|
|
550
|
+
});
|
|
551
|
+
if (isCancel(name)) {
|
|
552
|
+
cancel("Operation cancelled");
|
|
553
|
+
process.exit(0);
|
|
554
|
+
}
|
|
555
|
+
const description = await text({
|
|
556
|
+
message: "Description (optional)",
|
|
557
|
+
placeholder: "Added new features..."
|
|
558
|
+
});
|
|
559
|
+
if (isCancel(description)) {
|
|
560
|
+
cancel("Operation cancelled");
|
|
561
|
+
process.exit(0);
|
|
562
|
+
}
|
|
563
|
+
const setCurrent = await confirm({
|
|
564
|
+
message: "Set as current release?"
|
|
565
|
+
});
|
|
566
|
+
if (isCancel(setCurrent)) {
|
|
567
|
+
cancel("Operation cancelled");
|
|
568
|
+
process.exit(0);
|
|
569
|
+
}
|
|
570
|
+
const s = spinner();
|
|
571
|
+
s.start("Creating release...");
|
|
438
572
|
try {
|
|
439
573
|
const release = await client.createRelease({
|
|
440
574
|
version: version2,
|
|
441
|
-
name,
|
|
442
|
-
description,
|
|
575
|
+
name: name || void 0,
|
|
576
|
+
description: description || void 0,
|
|
443
577
|
reviewedOnly: false
|
|
444
578
|
});
|
|
445
|
-
if (setCurrent
|
|
579
|
+
if (setCurrent) {
|
|
446
580
|
await fetch(`${config.apiUrl}/v1/releases/${release.release.id}/current`, {
|
|
447
581
|
method: "PUT",
|
|
448
582
|
headers: {
|
|
@@ -450,30 +584,40 @@ async function configureReleaseCommand(rl, config) {
|
|
|
450
584
|
}
|
|
451
585
|
});
|
|
452
586
|
}
|
|
453
|
-
|
|
587
|
+
s.stop("Release created successfully!");
|
|
454
588
|
console.log(` ID: ${release.release.id}`);
|
|
455
589
|
console.log(` Version: ${release.release.version}`);
|
|
456
590
|
} catch (error) {
|
|
457
|
-
|
|
591
|
+
if (error instanceof Error) {
|
|
592
|
+
s.stop(`Failed: ${error.message}`);
|
|
593
|
+
} else {
|
|
594
|
+
s.stop("Failed to create release");
|
|
595
|
+
}
|
|
596
|
+
throw error;
|
|
458
597
|
}
|
|
459
598
|
} else {
|
|
460
|
-
const
|
|
461
|
-
|
|
599
|
+
const s = spinner();
|
|
600
|
+
s.start("Fetching releases...");
|
|
462
601
|
try {
|
|
463
602
|
const releases = await client.getReleases();
|
|
464
|
-
|
|
603
|
+
s.stop("Releases:");
|
|
465
604
|
releases.releases?.forEach((release, index) => {
|
|
466
|
-
const current = release.is_current ? " [CURRENT]" : "";
|
|
605
|
+
const current = release.is_current ? chalk3.green(" [CURRENT]") : "";
|
|
467
606
|
console.log(` ${index + 1}. ${release.version}${current}`);
|
|
468
607
|
});
|
|
469
608
|
} catch (error) {
|
|
470
|
-
|
|
609
|
+
if (error instanceof Error) {
|
|
610
|
+
s.stop(`Failed: ${error.message}`);
|
|
611
|
+
} else {
|
|
612
|
+
s.stop("Failed to list releases");
|
|
613
|
+
}
|
|
614
|
+
throw error;
|
|
471
615
|
}
|
|
472
616
|
}
|
|
473
617
|
}
|
|
474
618
|
|
|
475
619
|
// src/index.ts
|
|
476
|
-
var version = "0.0.
|
|
620
|
+
var version = "0.0.27";
|
|
477
621
|
program.name("lezu").description("CLI tool for managing translations with Lezu").version(version);
|
|
478
622
|
program.addCommand(createLoadCommand());
|
|
479
623
|
program.addCommand(createAddCommand());
|
|
@@ -488,7 +632,11 @@ if (process.argv.length <= 2) {
|
|
|
488
632
|
const config = loadConfig({});
|
|
489
633
|
await interactiveMode(config);
|
|
490
634
|
} catch (error) {
|
|
491
|
-
|
|
635
|
+
if (error instanceof Error) {
|
|
636
|
+
console.error(chalk4.red("\nError:"), error.message);
|
|
637
|
+
} else {
|
|
638
|
+
console.error(chalk4.red("\nError:"), error);
|
|
639
|
+
}
|
|
492
640
|
process.exit(1);
|
|
493
641
|
}
|
|
494
642
|
})();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/add.ts","../src/commands/release.ts","../src/interactive.ts"],"sourcesContent":["import { program } from 'commander'\nimport chalk from 'chalk'\nimport { createLoadCommand } from './commands/load.js'\nimport { createAddCommand } from './commands/add.js'\nimport { createGetCommand } from './commands/get.js'\nimport { createReleaseCommand } from './commands/release.js'\nimport { interactiveMode } from './interactive.js'\nimport { loadConfig } from './config.js'\n\n// Version from package.json\nconst version = '0.0.25'\n\nprogram\n .name('lezu')\n .description('CLI tool for managing translations with Lezu')\n .version(version)\n\n// Add subcommands\nprogram.addCommand(createLoadCommand())\nprogram.addCommand(createAddCommand())\nprogram.addCommand(createGetCommand())\nprogram.addCommand(createReleaseCommand())\n\n// If no command was provided, run interactive mode\nif (process.argv.length <= 2) {\n ;(async () => {\n console.log(chalk.blue('Welcome to Lezu CLI!'))\n console.log()\n \n try {\n const config = loadConfig({})\n await interactiveMode(config)\n } catch (error) {\n console.error(chalk.red('\\nError:'), error instanceof Error ? error.message : error)\n process.exit(1)\n }\n })()\n} else {\n // Parse commands normally\n program.parse()\n}","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 createAddCommand() {\n const command = new Command('add')\n .description('Add a new translation key with values')\n .requiredOption('-k, --key <key>', 'Translation key (e.g., \"common.save\")')\n .option('-v, --value <value>', 'Value for the source language')\n .option('--en <value>', 'English translation')\n .option('--es <value>', 'Spanish translation')\n .option('--fr <value>', 'French translation')\n .option('--de <value>', 'German translation')\n .option('--nl <value>', 'Dutch translation')\n .option('--it <value>', 'Italian translation')\n .option('--pt <value>', 'Portuguese translation')\n .option('--ru <value>', 'Russian translation')\n .option('--ja <value>', 'Japanese translation')\n .option('--ko <value>', 'Korean translation')\n .option('--zh <value>', 'Chinese translation')\n .option('--ar <value>', 'Arabic translation')\n .option('-d, --description <desc>', 'Description for the translation key')\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('--auto', 'Auto-translate to all enabled languages')\n .action(async (options) => {\n try {\n // Load configuration\n const config = loadConfig(options)\n \n // Validate configuration\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 // Collect translations from language options\n const translations: Record<string, string> = {}\n const languageOptions = ['en', 'es', 'fr', 'de', 'nl', 'it', 'pt', 'ru', 'ja', 'ko', 'zh', 'ar']\n \n languageOptions.forEach(lang => {\n if (options[lang]) {\n translations[lang] = options[lang]\n }\n })\n \n // If --value is provided without specific language, use project's source language\n if (options.value && Object.keys(translations).length === 0) {\n // We'll need to get the project info to determine source language\n const spinner = ora('Getting project information...').start()\n const client = new LezuApiClient(config)\n \n try {\n const { project } = await client.getProject()\n const sourceLanguage = project.source_language || 'en'\n translations[sourceLanguage] = options.value\n spinner.succeed(`Using ${sourceLanguage} as source language`)\n } catch (error) {\n spinner.fail('Failed to get project information')\n translations['en'] = options.value // fallback to English\n }\n }\n \n await addTranslationKey(config, {\n key: options.key,\n description: options.description,\n translations,\n auto: options.auto,\n })\n \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\ninterface AddKeyOptions {\n key: string\n description?: string\n translations: Record<string, string>\n auto?: boolean\n}\n\nasync function addTranslationKey(config: Config, options: AddKeyOptions) {\n const spinner = ora('Adding translation key...').start()\n \n try {\n const client = new LezuApiClient(config)\n \n // Add the key with translations\n const response = await client.addTranslationKey(options.key, options.translations)\n \n spinner.succeed('Translation key added successfully!')\n \n // Show summary\n console.log(chalk.green('\\n[Success] Key added:'))\n console.log(chalk.gray(` - Key: ${options.key}`))\n if (options.description) {\n console.log(chalk.gray(` - Description: ${options.description}`))\n }\n console.log(chalk.gray(` - Languages: ${Object.keys(options.translations).join(', ')}`))\n \n // Show translations\n if (Object.keys(options.translations).length > 0) {\n console.log(chalk.gray('\\n Translations:'))\n Object.entries(options.translations).forEach(([lang, value]) => {\n console.log(chalk.gray(` ${lang}: \"${value}\"`))\n })\n }\n \n // If auto-translate was used, show additional info\n if (options.auto) {\n console.log(chalk.cyan('\\n[AI] Auto-translation was enabled. Check the dashboard to review AI-generated translations.'))\n }\n \n } catch (error) {\n spinner.fail('Failed to add translation key')\n throw error\n }\n}","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 createReleaseCommand() {\n const command = new Command('release')\n .description('Manage releases')\n \n // Create release subcommand\n command\n .command('create')\n .alias('new')\n .description('Create a new release')\n .option('-v, --version <version>', 'Release version (e.g., \"1.0.0\")')\n .option('-n, --name <name>', 'Release name')\n .option('-d, --description <desc>', 'Release description')\n .option('-e, --environment <env>', 'Environment', 'production')\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('--reviewed-only', 'Include only reviewed translations')\n .option('--set-current', 'Set this release as the current release')\n .option('--timestamp <iso>', 'Specific timestamp for the release (ISO format)')\n .option('--languages <langs>', 'Comma-separated list of languages to include')\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 createRelease(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 // Set current release subcommand\n command\n .command('current <releaseId>')\n .description('Set a release as current')\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 .action(async (releaseId, 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 setCurrentRelease(config, releaseId, 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 // List releases (alias for get releases)\n command\n .command('list')\n .alias('ls')\n .description('List all releases')\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 // Import and use the getReleases function from get command\n const { getReleases } = await import('./get.js')\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 return command\n}\n\nasync function createRelease(config: Config, options: any) {\n const spinner = ora('Creating release...').start()\n \n try {\n const client = new LezuApiClient(config)\n \n // Parse languages if provided\n const languages = options.languages ? options.languages.split(',').map((l: string) => l.trim()) : undefined\n \n // Validate timestamp if provided\n let timestamp\n if (options.timestamp) {\n try {\n timestamp = new Date(options.timestamp).toISOString()\n } catch (error) {\n throw new Error('Invalid timestamp format. Use ISO format (e.g., 2023-12-01T10:00:00Z)')\n }\n }\n \n const releaseData = {\n environment: options.environment,\n version: options.version,\n name: options.name,\n description: options.description,\n reviewedOnly: options.reviewedOnly || false,\n setAsCurrent: options.setCurrent || false,\n timestamp,\n languages,\n }\n \n spinner.text = 'Creating release and generating bundles...'\n const response = await client.createRelease(releaseData)\n \n spinner.succeed('Release created successfully!')\n \n if (options.json) {\n console.log(JSON.stringify(response, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Release Created]'))\n console.log(` ID: ${response.release.id}`)\n console.log(` Version: ${response.release.version}`)\n if (response.release.name) {\n console.log(` Name: ${response.release.name}`)\n }\n if (response.release.description) {\n console.log(` Description: ${response.release.description}`)\n }\n console.log(` Environment: ${response.release.environment?.name || options.environment}`)\n console.log(` Reviewed Only: ${response.release.reviewed_only ? 'Yes' : 'No'}`)\n console.log(` Is Current: ${response.release.is_current ? 'Yes' : 'No'}`)\n console.log(` Created: ${new Date(response.release.created_at).toLocaleString()}`)\n \n // Show bundle information\n if (response.release.artifacts && response.release.artifacts.length > 0) {\n console.log(chalk.green('\\n[Bundles Generated]'))\n response.release.artifacts.forEach((artifact: any) => {\n const sizeKB = Math.round(artifact.file_size / 1024)\n console.log(` - ${artifact.language_code}: ${sizeKB}KB`)\n })\n console.log(chalk.gray(`\\nTotal: ${response.release.artifacts.length} language bundles`))\n }\n \n console.log(chalk.cyan('\\n[Tip] You can now use this release with:'))\n console.log(chalk.gray(` npx lezu load --release ${response.release.id}`))\n \n if (response.release.is_current) {\n console.log(chalk.green('\\n[Success] This release is now set as current!'))\n }\n \n } catch (error) {\n spinner.fail('Failed to create release')\n throw error\n }\n}\n\nasync function setCurrentRelease(config: Config, releaseId: string, options: any) {\n const spinner = ora('Setting release as current...').start()\n \n try {\n const response = await fetch(`${config.apiUrl}/v1/releases/${releaseId}/current`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n 'Content-Type': 'application/json',\n },\n })\n \n if (!response.ok) {\n const error = await response.text()\n throw new Error(`Failed to set current release: ${response.status} ${response.statusText}\\n${error}`)\n }\n \n const data = await response.json()\n \n spinner.succeed('Release set as current!')\n \n if (options.json) {\n console.log(JSON.stringify(data, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Release Updated]'))\n console.log(` Release ID: ${releaseId}`)\n console.log(' Status: Now set as current release')\n \n console.log(chalk.cyan('\\n[Info] All new bundle requests will now use this release'))\n \n } catch (error) {\n spinner.fail('Failed to set release as current')\n throw error\n }\n}","import * as readline from 'readline'\nimport { stdin as input, stdout as output } from 'process'\nimport { promisify } from 'util'\nimport chalk from 'chalk'\nimport { loadConfig } from './config.js'\nimport type { Config } from './types.js'\n\nexport async function interactiveMode(initialConfig: Partial<Config>): Promise<void> {\n const rl = readline.createInterface({ input, output })\n const question = promisify(rl.question).bind(rl)\n\n console.log(chalk.cyan('[Lezu CLI] Interactive Mode\\n'))\n console.log(chalk.gray('What would you like to do?\\n'))\n\n try {\n // Show available commands\n console.log('Available commands:')\n console.log(chalk.green('1) load') + chalk.gray(' - Download translation files'))\n console.log(chalk.green('2) add') + chalk.gray(' - Add a new translation key'))\n console.log(chalk.green('3) get') + chalk.gray(' - Get project information'))\n console.log(chalk.green('4) release') + chalk.gray(' - Manage releases'))\n console.log()\n\n const commandChoice = await question(chalk.bold('Choose a command (1-4): '))\n \n let command: string\n switch (commandChoice) {\n case '1':\n command = 'load'\n break\n case '2':\n command = 'add'\n break\n case '3':\n command = 'get'\n break\n case '4':\n command = 'release'\n break\n default:\n console.log(chalk.yellow('Invalid choice, defaulting to load'))\n command = 'load'\n }\n\n console.log(chalk.cyan(`\\n[Setup] Setting up ${command} command...\\n`))\n\n // Get basic configuration\n const projectId = await rl.question(\n chalk.bold('Project ID') + \n (initialConfig.projectId ? chalk.gray(` (${initialConfig.projectId}): `) : ': ')\n ) || initialConfig.projectId\n\n if (!projectId) {\n throw new Error('Project ID is required')\n }\n\n const apiKey = await rl.question(\n chalk.bold('API Key') + \n (initialConfig.apiKey ? chalk.gray(' (current key will be used): ') : ': ')\n ) || initialConfig.apiKey\n\n if (!apiKey) {\n throw new Error('API Key is required')\n }\n\n const config = loadConfig({ projectId, apiKey, ...initialConfig })\n\n // Handle specific command configurations\n switch (command) {\n case 'load':\n await configureLoadCommand(rl, config)\n break\n case 'add':\n await configureAddCommand(rl, config)\n break\n case 'get':\n await configureGetCommand(rl, config)\n break\n case 'release':\n await configureReleaseCommand(rl, config)\n break\n }\n\n } catch (error) {\n throw error\n } finally {\n rl.close()\n }\n}\n\nasync function configureLoadCommand(rl: any, config: Config): Promise<void> {\n const { syncTranslations } = await import('./commands/load.js')\n \n console.log(chalk.bold('\\nLoad Configuration:'))\n \n // Destination\n const dest = await rl.question(\n chalk.gray(`Destination folder (${config.dest || './src/i18n'}): `)\n ) || config.dest || './src/i18n'\n\n // Format\n console.log(chalk.gray('\\nOutput format:'))\n console.log('1) JSON (default)')\n console.log('2) JavaScript (ES modules)')\n console.log('3) TypeScript')\n console.log('4) YAML')\n \n const formatChoice = await rl.question(chalk.gray('Choice (1-4): ')) || '1'\n const formatMap: Record<string, 'json' | 'js' | 'ts' | 'yaml'> = {\n '1': 'json',\n '2': 'js',\n '3': 'ts',\n '4': 'yaml'\n }\n const format = formatMap[formatChoice] || 'json'\n\n // Environment\n const environment = await rl.question(\n chalk.gray(`Environment (${config.environment || 'production'}): `)\n ) || config.environment || 'production'\n\n // Languages\n const languages = await rl.question(\n chalk.gray('Specific languages (comma-separated, leave empty for all): ')\n )\n\n const finalConfig = {\n ...config,\n dest,\n format,\n environment,\n languages: languages ? languages.split(',').map(l => l.trim()) : undefined\n }\n\n console.log(chalk.green('\\n[Starting] Translation sync...'))\n \n // Import and execute the sync\n const { syncTranslations: sync } = await import('./commands/load.js')\n await sync(finalConfig)\n}\n\nasync function configureAddCommand(rl: any, config: Config): Promise<void> {\n console.log(chalk.bold('\\nAdd Translation Key:'))\n \n const key = await rl.question(chalk.bold('Translation key (e.g., \"common.save\"): '))\n if (!key) {\n throw new Error('Translation key is required')\n }\n\n const description = await rl.question(chalk.gray('Description (optional): '))\n\n console.log(chalk.gray('\\nDo you want to:'))\n console.log('1) Provide translations manually')\n console.log('2) Auto-translate from source language')\n \n const choice = await rl.question(chalk.gray('Choice (1-2): ')) || '1'\n\n let translations: Record<string, string> = {}\n let auto = false\n\n if (choice === '2') {\n auto = true\n const sourceValue = await rl.question(chalk.bold('Source language value: '))\n if (sourceValue) {\n // We'll determine the source language from the project\n translations.en = sourceValue // Default fallback\n }\n } else {\n console.log(chalk.gray('\\nEnter translations (press Enter to skip):'))\n const languages = ['en', 'es', 'fr', 'de', 'nl']\n \n for (const lang of languages) {\n const value = await rl.question(chalk.gray(`${lang}: `))\n if (value) {\n translations[lang] = value\n }\n }\n }\n\n console.log(chalk.green('\\n[Adding] Translation key...'))\n\n // Import and execute the add command\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n \n try {\n await client.addTranslationKey(key, translations)\n console.log(chalk.green('[Success] Translation key added successfully!'))\n } catch (error) {\n console.error(chalk.red('[Error] Failed to add translation key:'), error)\n }\n}\n\nasync function configureGetCommand(rl: any, config: Config): Promise<void> {\n console.log(chalk.bold('\\nGet Information:'))\n console.log('1) Project info')\n console.log('2) Languages')\n console.log('3) Releases')\n \n const choice = await rl.question(chalk.gray('What to get (1-3): ')) || '1'\n \n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n\n try {\n switch (choice) {\n case '1':\n const project = await client.getProject()\n console.log(chalk.green('\\n[Project Information]'))\n console.log(` Name: ${project.project.name}`)\n console.log(` Key: ${project.project.key}`)\n console.log(` Source Language: ${project.project.source_language}`)\n break\n \n case '2':\n const languages = await client.getLanguages()\n console.log(chalk.green('\\n[Languages]'))\n languages.languages?.forEach((lang: any) => {\n const status = lang.enabled ? '[ON]' : '[OFF]'\n console.log(` ${status} ${lang.language?.name || lang.language_code}`)\n })\n break\n \n case '3':\n const releases = await client.getReleases()\n console.log(chalk.green('\\n[Recent Releases]'))\n releases.releases?.slice(0, 5).forEach((release: any) => {\n const current = release.is_current ? ' [CURRENT]' : ''\n console.log(` • ${release.version}${current}`)\n })\n break\n }\n } catch (error) {\n console.error(chalk.red('[Error] Failed to get information:'), error)\n }\n}\n\nasync function configureReleaseCommand(rl: any, config: Config): Promise<void> {\n console.log(chalk.bold('\\nRelease Management:'))\n console.log('1) Create new release')\n console.log('2) List releases')\n \n const choice = await rl.question(chalk.gray('Choice (1-2): ')) || '1'\n\n if (choice === '1') {\n const version = await rl.question(chalk.bold('Version (e.g., \"1.0.0\"): '))\n const name = await rl.question(chalk.gray('Name (optional): '))\n const description = await rl.question(chalk.gray('Description (optional): '))\n \n const setCurrent = await rl.question(chalk.gray('Set as current release? (y/n): '))\n\n console.log(chalk.green('\\n[Creating] Release...'))\n\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n \n try {\n const release = await client.createRelease({\n version,\n name,\n description,\n reviewedOnly: false,\n })\n \n if (setCurrent?.toLowerCase() === 'y') {\n // Set as current\n await fetch(`${config.apiUrl}/v1/releases/${release.release.id}/current`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n })\n }\n \n console.log(chalk.green('[Success] Release created successfully!'))\n console.log(` ID: ${release.release.id}`)\n console.log(` Version: ${release.release.version}`)\n } catch (error) {\n console.error(chalk.red('[Error] Failed to create release:'), error)\n }\n \n } else {\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n \n try {\n const releases = await client.getReleases()\n console.log(chalk.green('\\n[Releases]'))\n releases.releases?.forEach((release: any, index: number) => {\n const current = release.is_current ? ' [CURRENT]' : ''\n console.log(` ${index + 1}. ${release.version}${current}`)\n })\n } catch (error) {\n console.error(chalk.red('[Error] Failed to list releases:'), error)\n }\n }\n}"],"mappings":"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","names":["chalk","Command","chalk","ora","Command","chalk","ora","chalk","chalk","LezuApiClient","version","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/add.ts","../src/commands/release.ts","../src/interactive.ts"],"sourcesContent":["import { program } from 'commander'\nimport chalk from 'chalk'\nimport { createLoadCommand } from './commands/load.js'\nimport { createAddCommand } from './commands/add.js'\nimport { createGetCommand } from './commands/get.js'\nimport { createReleaseCommand } from './commands/release.js'\nimport { interactiveMode } from './interactive.js'\nimport { loadConfig } from './config.js'\n\n// Version from package.json\nconst version = '0.0.27'\n\nprogram\n .name('lezu')\n .description('CLI tool for managing translations with Lezu')\n .version(version)\n\n// Add subcommands\nprogram.addCommand(createLoadCommand())\nprogram.addCommand(createAddCommand())\nprogram.addCommand(createGetCommand())\nprogram.addCommand(createReleaseCommand())\n\n// If no command was provided, run interactive mode\nif (process.argv.length <= 2) {\n ;(async () => {\n console.log(chalk.blue('Welcome to Lezu CLI!'))\n console.log()\n \n try {\n const config = loadConfig({})\n await interactiveMode(config)\n } catch (error) {\n if (error instanceof Error) {\n console.error(chalk.red('\\nError:'), error.message)\n } else {\n console.error(chalk.red('\\nError:'), error)\n }\n process.exit(1)\n }\n })()\n} else {\n // Parse commands normally\n program.parse()\n}","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 createAddCommand() {\n const command = new Command('add')\n .description('Add a new translation key with values')\n .requiredOption('-k, --key <key>', 'Translation key (e.g., \"common.save\")')\n .option('-v, --value <value>', 'Value for the source language')\n .option('--en <value>', 'English translation')\n .option('--es <value>', 'Spanish translation')\n .option('--fr <value>', 'French translation')\n .option('--de <value>', 'German translation')\n .option('--nl <value>', 'Dutch translation')\n .option('--it <value>', 'Italian translation')\n .option('--pt <value>', 'Portuguese translation')\n .option('--ru <value>', 'Russian translation')\n .option('--ja <value>', 'Japanese translation')\n .option('--ko <value>', 'Korean translation')\n .option('--zh <value>', 'Chinese translation')\n .option('--ar <value>', 'Arabic translation')\n .option('-d, --description <desc>', 'Description for the translation key')\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('--auto', 'Auto-translate to all enabled languages')\n .action(async (options) => {\n try {\n // Load configuration\n const config = loadConfig(options)\n \n // Validate configuration\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 // Collect translations from language options\n const translations: Record<string, string> = {}\n const languageOptions = ['en', 'es', 'fr', 'de', 'nl', 'it', 'pt', 'ru', 'ja', 'ko', 'zh', 'ar']\n \n languageOptions.forEach(lang => {\n if (options[lang]) {\n translations[lang] = options[lang]\n }\n })\n \n // If --value is provided without specific language, use project's source language\n if (options.value && Object.keys(translations).length === 0) {\n // We'll need to get the project info to determine source language\n const spinner = ora('Getting project information...').start()\n const client = new LezuApiClient(config)\n \n try {\n const { project } = await client.getProject()\n const sourceLanguage = project.source_language || 'en'\n translations[sourceLanguage] = options.value\n spinner.succeed(`Using ${sourceLanguage} as source language`)\n } catch (error) {\n spinner.fail('Failed to get project information')\n translations['en'] = options.value // fallback to English\n }\n }\n \n await addTranslationKey(config, {\n key: options.key,\n description: options.description,\n translations,\n auto: options.auto,\n })\n \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\ninterface AddKeyOptions {\n key: string\n description?: string\n translations: Record<string, string>\n auto?: boolean\n}\n\nasync function addTranslationKey(config: Config, options: AddKeyOptions) {\n const spinner = ora('Adding translation key...').start()\n \n try {\n const client = new LezuApiClient(config)\n \n // Add the key with translations\n const response = await client.addTranslationKey(options.key, options.translations)\n \n spinner.succeed('Translation key added successfully!')\n \n // Show summary\n console.log(chalk.green('\\n[Success] Key added:'))\n console.log(chalk.gray(` - Key: ${options.key}`))\n if (options.description) {\n console.log(chalk.gray(` - Description: ${options.description}`))\n }\n console.log(chalk.gray(` - Languages: ${Object.keys(options.translations).join(', ')}`))\n \n // Show translations\n if (Object.keys(options.translations).length > 0) {\n console.log(chalk.gray('\\n Translations:'))\n Object.entries(options.translations).forEach(([lang, value]) => {\n console.log(chalk.gray(` ${lang}: \"${value}\"`))\n })\n }\n \n // If auto-translate was used, show additional info\n if (options.auto) {\n console.log(chalk.cyan('\\n[AI] Auto-translation was enabled. Check the dashboard to review AI-generated translations.'))\n }\n \n } catch (error) {\n spinner.fail('Failed to add translation key')\n throw error\n }\n}","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 createReleaseCommand() {\n const command = new Command('release')\n .description('Manage releases')\n \n // Create release subcommand\n command\n .command('create')\n .alias('new')\n .description('Create a new release')\n .option('-v, --version <version>', 'Release version (e.g., \"1.0.0\")')\n .option('-n, --name <name>', 'Release name')\n .option('-d, --description <desc>', 'Release description')\n .option('-e, --environment <env>', 'Environment', 'production')\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('--reviewed-only', 'Include only reviewed translations')\n .option('--set-current', 'Set this release as the current release')\n .option('--timestamp <iso>', 'Specific timestamp for the release (ISO format)')\n .option('--languages <langs>', 'Comma-separated list of languages to include')\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 createRelease(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 // Set current release subcommand\n command\n .command('current <releaseId>')\n .description('Set a release as current')\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 .action(async (releaseId, 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 setCurrentRelease(config, releaseId, 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 // List releases (alias for get releases)\n command\n .command('list')\n .alias('ls')\n .description('List all releases')\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 // Import and use the getReleases function from get command\n const { getReleases } = await import('./get.js')\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 return command\n}\n\nasync function createRelease(config: Config, options: any) {\n const spinner = ora('Creating release...').start()\n \n try {\n const client = new LezuApiClient(config)\n \n // Parse languages if provided\n const languages = options.languages ? options.languages.split(',').map((l: string) => l.trim()) : undefined\n \n // Validate timestamp if provided\n let timestamp\n if (options.timestamp) {\n try {\n timestamp = new Date(options.timestamp).toISOString()\n } catch (error) {\n throw new Error('Invalid timestamp format. Use ISO format (e.g., 2023-12-01T10:00:00Z)')\n }\n }\n \n const releaseData = {\n environment: options.environment,\n version: options.version,\n name: options.name,\n description: options.description,\n reviewedOnly: options.reviewedOnly || false,\n setAsCurrent: options.setCurrent || false,\n timestamp,\n languages,\n }\n \n spinner.text = 'Creating release and generating bundles...'\n const response = await client.createRelease(releaseData)\n \n spinner.succeed('Release created successfully!')\n \n if (options.json) {\n console.log(JSON.stringify(response, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Release Created]'))\n console.log(` ID: ${response.release.id}`)\n console.log(` Version: ${response.release.version}`)\n if (response.release.name) {\n console.log(` Name: ${response.release.name}`)\n }\n if (response.release.description) {\n console.log(` Description: ${response.release.description}`)\n }\n console.log(` Environment: ${response.release.environment?.name || options.environment}`)\n console.log(` Reviewed Only: ${response.release.reviewed_only ? 'Yes' : 'No'}`)\n console.log(` Is Current: ${response.release.is_current ? 'Yes' : 'No'}`)\n console.log(` Created: ${new Date(response.release.created_at).toLocaleString()}`)\n \n // Show bundle information\n if (response.release.artifacts && response.release.artifacts.length > 0) {\n console.log(chalk.green('\\n[Bundles Generated]'))\n response.release.artifacts.forEach((artifact: any) => {\n const sizeKB = Math.round(artifact.file_size / 1024)\n console.log(` - ${artifact.language_code}: ${sizeKB}KB`)\n })\n console.log(chalk.gray(`\\nTotal: ${response.release.artifacts.length} language bundles`))\n }\n \n console.log(chalk.cyan('\\n[Tip] You can now use this release with:'))\n console.log(chalk.gray(` npx lezu load --release ${response.release.id}`))\n \n if (response.release.is_current) {\n console.log(chalk.green('\\n[Success] This release is now set as current!'))\n }\n \n } catch (error) {\n spinner.fail('Failed to create release')\n throw error\n }\n}\n\nasync function setCurrentRelease(config: Config, releaseId: string, options: any) {\n const spinner = ora('Setting release as current...').start()\n \n try {\n const response = await fetch(`${config.apiUrl}/v1/releases/${releaseId}/current`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n 'Content-Type': 'application/json',\n },\n })\n \n if (!response.ok) {\n const error = await response.text()\n throw new Error(`Failed to set current release: ${response.status} ${response.statusText}\\n${error}`)\n }\n \n const data = await response.json()\n \n spinner.succeed('Release set as current!')\n \n if (options.json) {\n console.log(JSON.stringify(data, null, 2))\n return\n }\n \n console.log(chalk.green('\\n[Release Updated]'))\n console.log(` Release ID: ${releaseId}`)\n console.log(' Status: Now set as current release')\n \n console.log(chalk.cyan('\\n[Info] All new bundle requests will now use this release'))\n \n } catch (error) {\n spinner.fail('Failed to set release as current')\n throw error\n }\n}","import { intro, outro, select, text, confirm, spinner, cancel, isCancel } from '@clack/prompts'\nimport chalk from 'chalk'\nimport { loadConfig } from './config.js'\nimport type { Config } from './types.js'\n\nexport async function interactiveMode(initialConfig: Partial<Config>): Promise<void> {\n intro(chalk.cyan('Welcome to Lezu CLI!'))\n\n try {\n // Select command\n const command = await select({\n message: 'What would you like to do?',\n options: [\n { value: 'load', label: 'Load translation files' },\n { value: 'add', label: 'Add a new translation key' },\n { value: 'get', label: 'Get project information' },\n { value: 'release', label: 'Manage releases' },\n ],\n })\n\n if (isCancel(command)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n // Get basic configuration\n const projectId = await text({\n message: 'Project ID',\n placeholder: initialConfig.projectId || 'Enter your project ID',\n defaultValue: initialConfig.projectId,\n validate: (value) => {\n if (!value) return 'Project ID is required'\n },\n })\n\n if (isCancel(projectId)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const apiKey = await text({\n message: 'API Key',\n placeholder: initialConfig.apiKey ? '(press enter to use existing key)' : 'Enter your API key',\n defaultValue: initialConfig.apiKey,\n validate: (value) => {\n if (!value) return 'API Key is required'\n },\n })\n\n if (isCancel(apiKey)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const config = loadConfig({ projectId: projectId as string, apiKey: apiKey as string, ...initialConfig })\n\n // Validate connection before proceeding\n const validationSpinner = spinner()\n validationSpinner.start('Validating credentials...')\n \n try {\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n await client.getProject()\n validationSpinner.stop('Credentials validated!')\n } catch (error) {\n if (error instanceof Error) {\n validationSpinner.stop('Invalid credentials')\n outro(chalk.red(error.message))\n } else {\n validationSpinner.stop('Failed to validate credentials')\n outro(chalk.red('Could not connect to Lezu API'))\n }\n process.exit(1)\n }\n\n // Handle specific command configurations\n switch (command) {\n case 'load':\n await configureLoadCommand(config)\n break\n case 'add':\n await configureAddCommand(config)\n break\n case 'get':\n await configureGetCommand(config)\n break\n case 'release':\n await configureReleaseCommand(config)\n break\n }\n\n outro(chalk.green('Done!'))\n } catch (error) {\n if (error instanceof Error) {\n outro(chalk.red(error.message))\n } else {\n outro(chalk.red('An unexpected error occurred'))\n }\n process.exit(1)\n }\n}\n\nasync function configureLoadCommand(config: Config): Promise<void> {\n const dest = await text({\n message: 'Destination folder',\n placeholder: config.dest || './src/i18n',\n defaultValue: config.dest || './src/i18n',\n })\n\n if (isCancel(dest)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const format = await select({\n message: 'Output format',\n options: [\n { value: 'json', label: 'JSON' },\n { value: 'js', label: 'JavaScript (ES modules)' },\n { value: 'ts', label: 'TypeScript' },\n { value: 'yaml', label: 'YAML' },\n ],\n })\n\n if (isCancel(format)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const environment = await text({\n message: 'Environment',\n placeholder: config.environment || 'production',\n defaultValue: config.environment || 'production',\n })\n\n if (isCancel(environment)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const languages = await text({\n message: 'Specific languages (comma-separated, leave empty for all)',\n placeholder: 'en,es,fr',\n })\n\n if (isCancel(languages)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const finalConfig = {\n ...config,\n dest: dest as string,\n format: format as 'json' | 'js' | 'ts' | 'yaml',\n environment: environment as string,\n languages: languages ? (languages as string).split(',').map(l => l.trim()) : undefined\n }\n\n const s = spinner()\n s.start('Syncing translations...')\n \n try {\n const { syncTranslations } = await import('./commands/load.js')\n await syncTranslations(finalConfig)\n s.stop('Translations synced successfully!')\n } catch (error) {\n if (error instanceof Error) {\n s.stop(`Failed: ${error.message}`)\n } else {\n s.stop('Failed to sync translations')\n }\n throw error\n }\n}\n\nasync function configureAddCommand(config: Config): Promise<void> {\n const key = await text({\n message: 'Translation key',\n placeholder: 'common.save',\n validate: (value) => {\n if (!value) return 'Translation key is required'\n },\n })\n\n if (isCancel(key)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const description = await text({\n message: 'Description (optional)',\n placeholder: 'Save button text',\n })\n\n if (isCancel(description)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const translationMethod = await select({\n message: 'How would you like to provide translations?',\n options: [\n { value: 'manual', label: 'Provide translations manually' },\n { value: 'auto', label: 'Auto-translate from source language' },\n ],\n })\n\n if (isCancel(translationMethod)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n let translations: Record<string, string> = {}\n let auto = false\n\n if (translationMethod === 'auto') {\n auto = true\n const sourceValue = await text({\n message: 'Source language value',\n placeholder: 'Save',\n validate: (value) => {\n if (!value) return 'Source value is required for auto-translation'\n },\n })\n\n if (isCancel(sourceValue)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n translations.en = sourceValue as string\n } else {\n const languages = ['en', 'es', 'fr', 'de', 'nl']\n \n for (const lang of languages) {\n const value = await text({\n message: `Translation for ${lang} (optional)`,\n placeholder: `Enter ${lang} translation`,\n })\n\n if (isCancel(value)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n if (value) {\n translations[lang] = value as string\n }\n }\n }\n\n const s = spinner()\n s.start('Adding translation key...')\n\n try {\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n await client.addTranslationKey(key as string, translations)\n s.stop('Translation key added successfully!')\n \n if (auto) {\n console.log(chalk.cyan('\\n[AI] Auto-translation was enabled. Check the dashboard to review AI-generated translations.'))\n }\n } catch (error) {\n if (error instanceof Error) {\n s.stop(`Failed: ${error.message}`)\n } else {\n s.stop('Failed to add translation key')\n }\n throw error\n }\n}\n\nasync function configureGetCommand(config: Config): Promise<void> {\n const infoType = await select({\n message: 'What information would you like to get?',\n options: [\n { value: 'project', label: 'Project information' },\n { value: 'languages', label: 'Languages' },\n { value: 'releases', label: 'Releases' },\n ],\n })\n\n if (isCancel(infoType)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const s = spinner()\n s.start('Fetching information...')\n\n try {\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n\n switch (infoType) {\n case 'project':\n const project = await client.getProject()\n s.stop('Project information:')\n console.log(` Name: ${project.project.name}`)\n console.log(` Key: ${project.project.key}`)\n console.log(` Source Language: ${project.project.source_language}`)\n break\n \n case 'languages':\n const languages = await client.getLanguages()\n s.stop('Languages:')\n languages.languages?.forEach((lang: any) => {\n const status = lang.enabled ? chalk.green('[ON]') : chalk.gray('[OFF]')\n console.log(` ${status} ${lang.language?.name || lang.language_code}`)\n })\n break\n \n case 'releases':\n const releases = await client.getReleases()\n s.stop('Recent releases:')\n releases.releases?.slice(0, 10).forEach((release: any) => {\n const current = release.is_current ? chalk.green(' [CURRENT]') : ''\n console.log(` ${release.version}${current}`)\n })\n break\n }\n } catch (error) {\n if (error instanceof Error) {\n s.stop(`Failed: ${error.message}`)\n } else {\n s.stop('Failed to fetch information')\n }\n throw error\n }\n}\n\nasync function configureReleaseCommand(config: Config): Promise<void> {\n const action = await select({\n message: 'Release management',\n options: [\n { value: 'create', label: 'Create new release' },\n { value: 'list', label: 'List releases' },\n ],\n })\n\n if (isCancel(action)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const { LezuApiClient } = await import('./api.js')\n const client = new LezuApiClient(config)\n\n if (action === 'create') {\n const version = await text({\n message: 'Version',\n placeholder: '1.0.0',\n validate: (value) => {\n if (!value) return 'Version is required'\n },\n })\n\n if (isCancel(version)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const name = await text({\n message: 'Name (optional)',\n placeholder: 'Production Release',\n })\n\n if (isCancel(name)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const description = await text({\n message: 'Description (optional)',\n placeholder: 'Added new features...',\n })\n\n if (isCancel(description)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const setCurrent = await confirm({\n message: 'Set as current release?',\n })\n\n if (isCancel(setCurrent)) {\n cancel('Operation cancelled')\n process.exit(0)\n }\n\n const s = spinner()\n s.start('Creating release...')\n\n try {\n const release = await client.createRelease({\n version: version as string,\n name: name as string || undefined,\n description: description as string || undefined,\n reviewedOnly: false,\n })\n \n if (setCurrent) {\n await fetch(`${config.apiUrl}/v1/releases/${release.release.id}/current`, {\n method: 'PUT',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n })\n }\n \n s.stop('Release created successfully!')\n console.log(` ID: ${release.release.id}`)\n console.log(` Version: ${release.release.version}`)\n } catch (error) {\n if (error instanceof Error) {\n s.stop(`Failed: ${error.message}`)\n } else {\n s.stop('Failed to create release')\n }\n throw error\n }\n \n } else {\n const s = spinner()\n s.start('Fetching releases...')\n \n try {\n const releases = await client.getReleases()\n s.stop('Releases:')\n releases.releases?.forEach((release: any, index: number) => {\n const current = release.is_current ? chalk.green(' [CURRENT]') : ''\n console.log(` ${index + 1}. ${release.version}${current}`)\n })\n } catch (error) {\n if (error instanceof Error) {\n s.stop(`Failed: ${error.message}`)\n } else {\n s.stop('Failed to list releases')\n }\n throw error\n }\n }\n}"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AACxB,OAAOA,YAAW;;;ACDlB,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAKT,SAAS,mBAAmB;AACjC,QAAM,UAAU,IAAI,QAAQ,KAAK,EAC9B,YAAY,uCAAuC,EACnD,eAAe,mBAAmB,uCAAuC,EACzE,OAAO,uBAAuB,+BAA+B,EAC7D,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,gBAAgB,oBAAoB,EAC3C,OAAO,gBAAgB,oBAAoB,EAC3C,OAAO,gBAAgB,mBAAmB,EAC1C,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,gBAAgB,wBAAwB,EAC/C,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,gBAAgB,sBAAsB,EAC7C,OAAO,gBAAgB,oBAAoB,EAC3C,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,gBAAgB,oBAAoB,EAC3C,OAAO,4BAA4B,qCAAqC,EACxE,OAAO,sBAAsB,YAAY,EACzC,OAAO,uBAAuB,SAAS,EACvC,OAAO,mBAAmB,WAAW,sBAAsB,EAC3D,OAAO,UAAU,yCAAyC,EAC1D,OAAO,OAAO,YAAY;AACzB,QAAI;AAEF,YAAM,SAAS,WAAW,OAAO;AAGjC,YAAM,SAAS,eAAe,MAAM;AACpC,UAAI,OAAO,SAAS,GAAG;AACrB,gBAAQ,MAAM,MAAM,IAAI,uBAAuB,CAAC;AAChD,eAAO,QAAQ,WAAS,QAAQ,MAAM,MAAM,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAGA,YAAM,eAAuC,CAAC;AAC9C,YAAM,kBAAkB,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAE/F,sBAAgB,QAAQ,UAAQ;AAC9B,YAAI,QAAQ,IAAI,GAAG;AACjB,uBAAa,IAAI,IAAI,QAAQ,IAAI;AAAA,QACnC;AAAA,MACF,CAAC;AAGD,UAAI,QAAQ,SAAS,OAAO,KAAK,YAAY,EAAE,WAAW,GAAG;AAE3D,cAAMC,WAAU,IAAI,gCAAgC,EAAE,MAAM;AAC5D,cAAM,SAAS,IAAI,cAAc,MAAM;AAEvC,YAAI;AACF,gBAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,WAAW;AAC5C,gBAAM,iBAAiB,QAAQ,mBAAmB;AAClD,uBAAa,cAAc,IAAI,QAAQ;AACvC,UAAAA,SAAQ,QAAQ,SAAS,cAAc,qBAAqB;AAAA,QAC9D,SAAS,OAAO;AACd,UAAAA,SAAQ,KAAK,mCAAmC;AAChD,uBAAa,IAAI,IAAI,QAAQ;AAAA,QAC/B;AAAA,MACF;AAEA,YAAM,kBAAkB,QAAQ;AAAA,QAC9B,KAAK,QAAQ;AAAA,QACb,aAAa,QAAQ;AAAA,QACrB;AAAA,QACA,MAAM,QAAQ;AAAA,MAChB,CAAC;AAAA,IAEH,SAAS,OAAO;AACd,cAAQ,MAAM,MAAM,IAAI,WAAW,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACpF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO;AACT;AASA,eAAe,kBAAkB,QAAgB,SAAwB;AACvE,QAAMA,WAAU,IAAI,2BAA2B,EAAE,MAAM;AAEvD,MAAI;AACF,UAAM,SAAS,IAAI,cAAc,MAAM;AAGvC,UAAM,WAAW,MAAM,OAAO,kBAAkB,QAAQ,KAAK,QAAQ,YAAY;AAEjF,IAAAA,SAAQ,QAAQ,qCAAqC;AAGrD,YAAQ,IAAI,MAAM,MAAM,wBAAwB,CAAC;AACjD,YAAQ,IAAI,MAAM,KAAK,YAAY,QAAQ,GAAG,EAAE,CAAC;AACjD,QAAI,QAAQ,aAAa;AACvB,cAAQ,IAAI,MAAM,KAAK,oBAAoB,QAAQ,WAAW,EAAE,CAAC;AAAA,IACnE;AACA,YAAQ,IAAI,MAAM,KAAK,kBAAkB,OAAO,KAAK,QAAQ,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAGxF,QAAI,OAAO,KAAK,QAAQ,YAAY,EAAE,SAAS,GAAG;AAChD,cAAQ,IAAI,MAAM,KAAK,mBAAmB,CAAC;AAC3C,aAAO,QAAQ,QAAQ,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM;AAC9D,gBAAQ,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,GAAG,CAAC;AAAA,MACnD,CAAC;AAAA,IACH;AAGA,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,MAAM,KAAK,+FAA+F,CAAC;AAAA,IACzH;AAAA,EAEF,SAAS,OAAO;AACd,IAAAA,SAAQ,KAAK,+BAA+B;AAC5C,UAAM;AAAA,EACR;AACF;;;AChIA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAKT,SAAS,uBAAuB;AACrC,QAAM,UAAU,IAAIC,SAAQ,SAAS,EAClC,YAAY,iBAAiB;AAGhC,UACG,QAAQ,QAAQ,EAChB,MAAM,KAAK,EACX,YAAY,sBAAsB,EAClC,OAAO,2BAA2B,iCAAiC,EACnE,OAAO,qBAAqB,cAAc,EAC1C,OAAO,4BAA4B,qBAAqB,EACxD,OAAO,2BAA2B,eAAe,YAAY,EAC7D,OAAO,sBAAsB,YAAY,EACzC,OAAO,uBAAuB,SAAS,EACvC,OAAO,mBAAmB,WAAW,sBAAsB,EAC3D,OAAO,mBAAmB,oCAAoC,EAC9D,OAAO,iBAAiB,yCAAyC,EACjE,OAAO,qBAAqB,iDAAiD,EAC7E,OAAO,uBAAuB,8CAA8C,EAC5E,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,YAAY;AACzB,QAAI;AACF,YAAM,SAAS,WAAW,OAAO;AACjC,YAAM,SAAS,eAAe,MAAM;AACpC,UAAI,OAAO,SAAS,GAAG;AACrB,gBAAQ,MAAMC,OAAM,IAAI,uBAAuB,CAAC;AAChD,eAAO,QAAQ,WAAS,QAAQ,MAAMA,OAAM,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,cAAc,QAAQ,OAAO;AAAA,IACrC,SAAS,OAAO;AACd,cAAQ,MAAMA,OAAM,IAAI,WAAW,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACpF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,UACG,QAAQ,qBAAqB,EAC7B,YAAY,0BAA0B,EACtC,OAAO,sBAAsB,YAAY,EACzC,OAAO,uBAAuB,SAAS,EACvC,OAAO,mBAAmB,WAAW,sBAAsB,EAC3D,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,WAAW,YAAY;AACpC,QAAI;AACF,YAAM,SAAS,WAAW,OAAO;AACjC,YAAM,SAAS,eAAe,MAAM;AACpC,UAAI,OAAO,SAAS,GAAG;AACrB,gBAAQ,MAAMA,OAAM,IAAI,uBAAuB,CAAC;AAChD,eAAO,QAAQ,WAAS,QAAQ,MAAMA,OAAM,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,kBAAkB,QAAQ,WAAW,OAAO;AAAA,IACpD,SAAS,OAAO;AACd,cAAQ,MAAMA,OAAM,IAAI,WAAW,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACpF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,UACG,QAAQ,MAAM,EACd,MAAM,IAAI,EACV,YAAY,mBAAmB,EAC/B,OAAO,sBAAsB,YAAY,EACzC,OAAO,uBAAuB,SAAS,EACvC,OAAO,mBAAmB,WAAW,sBAAsB,EAC3D,OAAO,2BAA2B,eAAe,YAAY,EAC7D,OAAO,UAAU,gBAAgB,EACjC,OAAO,eAAe,2BAA2B,IAAI,EACrD,OAAO,OAAO,YAAY;AACzB,QAAI;AACF,YAAM,SAAS,WAAW,OAAO;AACjC,YAAM,SAAS,eAAe,MAAM;AACpC,UAAI,OAAO,SAAS,GAAG;AACrB,gBAAQ,MAAMA,OAAM,IAAI,uBAAuB,CAAC;AAChD,eAAO,QAAQ,WAAS,QAAQ,MAAMA,OAAM,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC;AAChE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAGA,YAAM,EAAE,YAAY,IAAI,MAAM,OAAO,mBAAU;AAC/C,YAAM,YAAY,QAAQ,OAAO;AAAA,IACnC,SAAS,OAAO;AACd,cAAQ,MAAMA,OAAM,IAAI,WAAW,GAAG,iBAAiB,QAAQ,MAAM,UAAU,KAAK;AACpF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO;AACT;AAEA,eAAe,cAAc,QAAgB,SAAc;AACzD,QAAMC,WAAUC,KAAI,qBAAqB,EAAE,MAAM;AAEjD,MAAI;AACF,UAAM,SAAS,IAAI,cAAc,MAAM;AAGvC,UAAM,YAAY,QAAQ,YAAY,QAAQ,UAAU,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC,IAAI;AAGlG,QAAI;AACJ,QAAI,QAAQ,WAAW;AACrB,UAAI;AACF,oBAAY,IAAI,KAAK,QAAQ,SAAS,EAAE,YAAY;AAAA,MACtD,SAAS,OAAO;AACd,cAAM,IAAI,MAAM,uEAAuE;AAAA,MACzF;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,aAAa,QAAQ;AAAA,MACrB,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ;AAAA,MACd,aAAa,QAAQ;AAAA,MACrB,cAAc,QAAQ,gBAAgB;AAAA,MACtC,cAAc,QAAQ,cAAc;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAEA,IAAAD,SAAQ,OAAO;AACf,UAAM,WAAW,MAAM,OAAO,cAAc,WAAW;AAEvD,IAAAA,SAAQ,QAAQ,+BAA+B;AAE/C,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC7C;AAAA,IACF;AAEA,YAAQ,IAAID,OAAM,MAAM,qBAAqB,CAAC;AAC9C,YAAQ,IAAI,SAAS,SAAS,QAAQ,EAAE,EAAE;AAC1C,YAAQ,IAAI,cAAc,SAAS,QAAQ,OAAO,EAAE;AACpD,QAAI,SAAS,QAAQ,MAAM;AACzB,cAAQ,IAAI,WAAW,SAAS,QAAQ,IAAI,EAAE;AAAA,IAChD;AACA,QAAI,SAAS,QAAQ,aAAa;AAChC,cAAQ,IAAI,kBAAkB,SAAS,QAAQ,WAAW,EAAE;AAAA,IAC9D;AACA,YAAQ,IAAI,kBAAkB,SAAS,QAAQ,aAAa,QAAQ,QAAQ,WAAW,EAAE;AACzF,YAAQ,IAAI,oBAAoB,SAAS,QAAQ,gBAAgB,QAAQ,IAAI,EAAE;AAC/E,YAAQ,IAAI,iBAAiB,SAAS,QAAQ,aAAa,QAAQ,IAAI,EAAE;AACzE,YAAQ,IAAI,cAAc,IAAI,KAAK,SAAS,QAAQ,UAAU,EAAE,eAAe,CAAC,EAAE;AAGlF,QAAI,SAAS,QAAQ,aAAa,SAAS,QAAQ,UAAU,SAAS,GAAG;AACvE,cAAQ,IAAIA,OAAM,MAAM,uBAAuB,CAAC;AAChD,eAAS,QAAQ,UAAU,QAAQ,CAAC,aAAkB;AACpD,cAAM,SAAS,KAAK,MAAM,SAAS,YAAY,IAAI;AACnD,gBAAQ,IAAI,OAAO,SAAS,aAAa,KAAK,MAAM,IAAI;AAAA,MAC1D,CAAC;AACD,cAAQ,IAAIA,OAAM,KAAK;AAAA,SAAY,SAAS,QAAQ,UAAU,MAAM,mBAAmB,CAAC;AAAA,IAC1F;AAEA,YAAQ,IAAIA,OAAM,KAAK,4CAA4C,CAAC;AACpE,YAAQ,IAAIA,OAAM,KAAK,8BAA8B,SAAS,QAAQ,EAAE,EAAE,CAAC;AAE3E,QAAI,SAAS,QAAQ,YAAY;AAC/B,cAAQ,IAAIA,OAAM,MAAM,iDAAiD,CAAC;AAAA,IAC5E;AAAA,EAEF,SAAS,OAAO;AACd,IAAAC,SAAQ,KAAK,0BAA0B;AACvC,UAAM;AAAA,EACR;AACF;AAEA,eAAe,kBAAkB,QAAgB,WAAmB,SAAc;AAChF,QAAMA,WAAUC,KAAI,+BAA+B,EAAE,MAAM;AAE3D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,MAAM,gBAAgB,SAAS,YAAY;AAAA,MAChF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,iBAAiB,UAAU,OAAO,MAAM;AAAA,QACxC,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,EAAK,KAAK,EAAE;AAAA,IACtG;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,IAAAD,SAAQ,QAAQ,yBAAyB;AAEzC,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACzC;AAAA,IACF;AAEA,YAAQ,IAAID,OAAM,MAAM,qBAAqB,CAAC;AAC9C,YAAQ,IAAI,iBAAiB,SAAS,EAAE;AACxC,YAAQ,IAAI,sCAAsC;AAElD,YAAQ,IAAIA,OAAM,KAAK,4DAA4D,CAAC;AAAA,EAEtF,SAAS,OAAO;AACd,IAAAC,SAAQ,KAAK,kCAAkC;AAC/C,UAAM;AAAA,EACR;AACF;;;ACxNA,SAAS,OAAO,OAAO,QAAQ,MAAM,SAAS,SAAS,QAAQ,gBAAgB;AAC/E,OAAOE,YAAW;AAIlB,eAAsB,gBAAgB,eAA+C;AACnF,QAAMC,OAAM,KAAK,sBAAsB,CAAC;AAExC,MAAI;AAEF,UAAM,UAAU,MAAM,OAAO;AAAA,MAC3B,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,OAAO,QAAQ,OAAO,yBAAyB;AAAA,QACjD,EAAE,OAAO,OAAO,OAAO,4BAA4B;AAAA,QACnD,EAAE,OAAO,OAAO,OAAO,0BAA0B;AAAA,QACjD,EAAE,OAAO,WAAW,OAAO,kBAAkB;AAAA,MAC/C;AAAA,IACF,CAAC;AAED,QAAI,SAAS,OAAO,GAAG;AACrB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,UAAM,YAAY,MAAM,KAAK;AAAA,MAC3B,SAAS;AAAA,MACT,aAAa,cAAc,aAAa;AAAA,MACxC,cAAc,cAAc;AAAA,MAC5B,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB,SAAS;AAAA,MACT,aAAa,cAAc,SAAS,sCAAsC;AAAA,MAC1E,cAAc,cAAc;AAAA,MAC5B,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,SAAS,MAAM,GAAG;AACpB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,WAAW,EAAE,WAAgC,QAA0B,GAAG,cAAc,CAAC;AAGxG,UAAM,oBAAoB,QAAQ;AAClC,sBAAkB,MAAM,2BAA2B;AAEnD,QAAI;AACF,YAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,mBAAU;AACjD,YAAM,SAAS,IAAIA,eAAc,MAAM;AACvC,YAAM,OAAO,WAAW;AACxB,wBAAkB,KAAK,wBAAwB;AAAA,IACjD,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO;AAC1B,0BAAkB,KAAK,qBAAqB;AAC5C,cAAMD,OAAM,IAAI,MAAM,OAAO,CAAC;AAAA,MAChC,OAAO;AACL,0BAAkB,KAAK,gCAAgC;AACvD,cAAMA,OAAM,IAAI,+BAA+B,CAAC;AAAA,MAClD;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,cAAM,qBAAqB,MAAM;AACjC;AAAA,MACF,KAAK;AACH,cAAM,oBAAoB,MAAM;AAChC;AAAA,MACF,KAAK;AACH,cAAM,oBAAoB,MAAM;AAChC;AAAA,MACF,KAAK;AACH,cAAM,wBAAwB,MAAM;AACpC;AAAA,IACJ;AAEA,UAAMA,OAAM,MAAM,OAAO,CAAC;AAAA,EAC5B,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,YAAMA,OAAM,IAAI,MAAM,OAAO,CAAC;AAAA,IAChC,OAAO;AACL,YAAMA,OAAM,IAAI,8BAA8B,CAAC;AAAA,IACjD;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,eAAe,qBAAqB,QAA+B;AACjE,QAAM,OAAO,MAAM,KAAK;AAAA,IACtB,SAAS;AAAA,IACT,aAAa,OAAO,QAAQ;AAAA,IAC5B,cAAc,OAAO,QAAQ;AAAA,EAC/B,CAAC;AAED,MAAI,SAAS,IAAI,GAAG;AAClB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM,OAAO;AAAA,IAC1B,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,MAC/B,EAAE,OAAO,MAAM,OAAO,0BAA0B;AAAA,MAChD,EAAE,OAAO,MAAM,OAAO,aAAa;AAAA,MACnC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,IACjC;AAAA,EACF,CAAC;AAED,MAAI,SAAS,MAAM,GAAG;AACpB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,MAAM,KAAK;AAAA,IAC7B,SAAS;AAAA,IACT,aAAa,OAAO,eAAe;AAAA,IACnC,cAAc,OAAO,eAAe;AAAA,EACtC,CAAC;AAED,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,YAAY,MAAM,KAAK;AAAA,IAC3B,SAAS;AAAA,IACT,aAAa;AAAA,EACf,CAAC;AAED,MAAI,SAAS,SAAS,GAAG;AACvB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc;AAAA,IAClB,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,YAAa,UAAqB,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,IAAI;AAAA,EAC/E;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,yBAAyB;AAEjC,MAAI;AACF,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,oBAAoB;AAC9D,UAAM,iBAAiB,WAAW;AAClC,MAAE,KAAK,mCAAmC;AAAA,EAC5C,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,QAAE,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,IACnC,OAAO;AACL,QAAE,KAAK,6BAA6B;AAAA,IACtC;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,oBAAoB,QAA+B;AAChE,QAAM,MAAM,MAAM,KAAK;AAAA,IACrB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,MAAO,QAAO;AAAA,IACrB;AAAA,EACF,CAAC;AAED,MAAI,SAAS,GAAG,GAAG;AACjB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,MAAM,KAAK;AAAA,IAC7B,SAAS;AAAA,IACT,aAAa;AAAA,EACf,CAAC;AAED,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,oBAAoB,MAAM,OAAO;AAAA,IACrC,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,UAAU,OAAO,gCAAgC;AAAA,MAC1D,EAAE,OAAO,QAAQ,OAAO,sCAAsC;AAAA,IAChE;AAAA,EACF,CAAC;AAED,MAAI,SAAS,iBAAiB,GAAG;AAC/B,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,eAAuC,CAAC;AAC5C,MAAI,OAAO;AAEX,MAAI,sBAAsB,QAAQ;AAChC,WAAO;AACP,UAAM,cAAc,MAAM,KAAK;AAAA,MAC7B,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,iBAAa,KAAK;AAAA,EACpB,OAAO;AACL,UAAM,YAAY,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI;AAE/C,eAAW,QAAQ,WAAW;AAC5B,YAAM,QAAQ,MAAM,KAAK;AAAA,QACvB,SAAS,mBAAmB,IAAI;AAAA,QAChC,aAAa,SAAS,IAAI;AAAA,MAC5B,CAAC;AAED,UAAI,SAAS,KAAK,GAAG;AACnB,eAAO,qBAAqB;AAC5B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,OAAO;AACT,qBAAa,IAAI,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,2BAA2B;AAEnC,MAAI;AACF,UAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,mBAAU;AACjD,UAAM,SAAS,IAAIA,eAAc,MAAM;AACvC,UAAM,OAAO,kBAAkB,KAAe,YAAY;AAC1D,MAAE,KAAK,qCAAqC;AAE5C,QAAI,MAAM;AACR,cAAQ,IAAID,OAAM,KAAK,+FAA+F,CAAC;AAAA,IACzH;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,QAAE,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,IACnC,OAAO;AACL,QAAE,KAAK,+BAA+B;AAAA,IACxC;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,oBAAoB,QAA+B;AAChE,QAAM,WAAW,MAAM,OAAO;AAAA,IAC5B,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,WAAW,OAAO,sBAAsB;AAAA,MACjD,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,MACzC,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,IACzC;AAAA,EACF,CAAC;AAED,MAAI,SAAS,QAAQ,GAAG;AACtB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,IAAI,QAAQ;AAClB,IAAE,MAAM,yBAAyB;AAEjC,MAAI;AACF,UAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,mBAAU;AACjD,UAAM,SAAS,IAAIA,eAAc,MAAM;AAEvC,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,cAAM,UAAU,MAAM,OAAO,WAAW;AACxC,UAAE,KAAK,sBAAsB;AAC7B,gBAAQ,IAAI,WAAW,QAAQ,QAAQ,IAAI,EAAE;AAC7C,gBAAQ,IAAI,UAAU,QAAQ,QAAQ,GAAG,EAAE;AAC3C,gBAAQ,IAAI,sBAAsB,QAAQ,QAAQ,eAAe,EAAE;AACnE;AAAA,MAEF,KAAK;AACH,cAAM,YAAY,MAAM,OAAO,aAAa;AAC5C,UAAE,KAAK,YAAY;AACnB,kBAAU,WAAW,QAAQ,CAAC,SAAc;AAC1C,gBAAM,SAAS,KAAK,UAAUD,OAAM,MAAM,MAAM,IAAIA,OAAM,KAAK,OAAO;AACtE,kBAAQ,IAAI,KAAK,MAAM,IAAI,KAAK,UAAU,QAAQ,KAAK,aAAa,EAAE;AAAA,QACxE,CAAC;AACD;AAAA,MAEF,KAAK;AACH,cAAM,WAAW,MAAM,OAAO,YAAY;AAC1C,UAAE,KAAK,kBAAkB;AACzB,iBAAS,UAAU,MAAM,GAAG,EAAE,EAAE,QAAQ,CAAC,YAAiB;AACxD,gBAAM,UAAU,QAAQ,aAAaA,OAAM,MAAM,YAAY,IAAI;AACjE,kBAAQ,IAAI,KAAK,QAAQ,OAAO,GAAG,OAAO,EAAE;AAAA,QAC9C,CAAC;AACD;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,QAAE,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,IACnC,OAAO;AACL,QAAE,KAAK,6BAA6B;AAAA,IACtC;AACA,UAAM;AAAA,EACR;AACF;AAEA,eAAe,wBAAwB,QAA+B;AACpE,QAAM,SAAS,MAAM,OAAO;AAAA,IAC1B,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,OAAO,UAAU,OAAO,qBAAqB;AAAA,MAC/C,EAAE,OAAO,QAAQ,OAAO,gBAAgB;AAAA,IAC1C;AAAA,EACF,CAAC;AAED,MAAI,SAAS,MAAM,GAAG;AACpB,WAAO,qBAAqB;AAC5B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,mBAAU;AACjD,QAAM,SAAS,IAAIA,eAAc,MAAM;AAEvC,MAAI,WAAW,UAAU;AACvB,UAAMC,WAAU,MAAM,KAAK;AAAA,MACzB,SAAS;AAAA,MACT,aAAa;AAAA,MACb,UAAU,CAAC,UAAU;AACnB,YAAI,CAAC,MAAO,QAAO;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,SAASA,QAAO,GAAG;AACrB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC;AAED,QAAI,SAAS,IAAI,GAAG;AAClB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,cAAc,MAAM,KAAK;AAAA,MAC7B,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC;AAED,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,aAAa,MAAM,QAAQ;AAAA,MAC/B,SAAS;AAAA,IACX,CAAC;AAED,QAAI,SAAS,UAAU,GAAG;AACxB,aAAO,qBAAqB;AAC5B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,QAAQ;AAClB,MAAE,MAAM,qBAAqB;AAE7B,QAAI;AACF,YAAM,UAAU,MAAM,OAAO,cAAc;AAAA,QACzC,SAASA;AAAA,QACT,MAAM,QAAkB;AAAA,QACxB,aAAa,eAAyB;AAAA,QACtC,cAAc;AAAA,MAChB,CAAC;AAED,UAAI,YAAY;AACd,cAAM,MAAM,GAAG,OAAO,MAAM,gBAAgB,QAAQ,QAAQ,EAAE,YAAY;AAAA,UACxE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,iBAAiB,UAAU,OAAO,MAAM;AAAA,UAC1C;AAAA,QACF,CAAC;AAAA,MACH;AAEA,QAAE,KAAK,+BAA+B;AACtC,cAAQ,IAAI,SAAS,QAAQ,QAAQ,EAAE,EAAE;AACzC,cAAQ,IAAI,cAAc,QAAQ,QAAQ,OAAO,EAAE;AAAA,IACrD,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO;AAC1B,UAAE,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,MACnC,OAAO;AACL,UAAE,KAAK,0BAA0B;AAAA,MACnC;AACA,YAAM;AAAA,IACR;AAAA,EAEF,OAAO;AACL,UAAM,IAAI,QAAQ;AAClB,MAAE,MAAM,sBAAsB;AAE9B,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,YAAY;AAC1C,QAAE,KAAK,WAAW;AAClB,eAAS,UAAU,QAAQ,CAAC,SAAc,UAAkB;AAC1D,cAAM,UAAU,QAAQ,aAAaF,OAAM,MAAM,YAAY,IAAI;AACjE,gBAAQ,IAAI,KAAK,QAAQ,CAAC,KAAK,QAAQ,OAAO,GAAG,OAAO,EAAE;AAAA,MAC5D,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO;AAC1B,UAAE,KAAK,WAAW,MAAM,OAAO,EAAE;AAAA,MACnC,OAAO;AACL,UAAE,KAAK,yBAAyB;AAAA,MAClC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AHnbA,IAAM,UAAU;AAEhB,QACG,KAAK,MAAM,EACX,YAAY,8CAA8C,EAC1D,QAAQ,OAAO;AAGlB,QAAQ,WAAW,kBAAkB,CAAC;AACtC,QAAQ,WAAW,iBAAiB,CAAC;AACrC,QAAQ,WAAW,iBAAiB,CAAC;AACrC,QAAQ,WAAW,qBAAqB,CAAC;AAGzC,IAAI,QAAQ,KAAK,UAAU,GAAG;AAC5B;AAAC,GAAC,YAAY;AACZ,YAAQ,IAAIG,OAAM,KAAK,sBAAsB,CAAC;AAC9C,YAAQ,IAAI;AAEZ,QAAI;AACF,YAAM,SAAS,WAAW,CAAC,CAAC;AAC5B,YAAM,gBAAgB,MAAM;AAAA,IAC9B,SAAS,OAAO;AACd,UAAI,iBAAiB,OAAO;AAC1B,gBAAQ,MAAMA,OAAM,IAAI,UAAU,GAAG,MAAM,OAAO;AAAA,MACpD,OAAO;AACL,gBAAQ,MAAMA,OAAM,IAAI,UAAU,GAAG,KAAK;AAAA,MAC5C;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,GAAG;AACL,OAAO;AAEL,UAAQ,MAAM;AAChB;","names":["chalk","spinner","Command","chalk","ora","Command","chalk","spinner","ora","chalk","chalk","LezuApiClient","version","chalk"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lezu",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.27",
|
|
4
4
|
"description": "CLI tool for pulling translations from Lezu",
|
|
5
5
|
"bin": {
|
|
6
6
|
"lezu": "bin/lezu.js"
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"prepublishOnly": "echo 'Build already done in CI'"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@clack/prompts": "^0.8.2",
|
|
17
18
|
"chalk": "^5.3.0",
|
|
18
19
|
"commander": "^12.0.0",
|
|
19
20
|
"dotenv": "^16.4.5",
|
package/dist/api-PFXU7GZT.js
DELETED
|
@@ -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']\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 console.log(`[Config] Loaded from ${file}`)\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})\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":";AAAA,SAAS,cAAc,kBAAkB;AACzC,SAAS,eAAe;AACxB,OAAO,YAAY;;;ACFnB,SAAS,SAAS;AAEX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,QAAQ,EAAE,OAAO,EAAE,QAAQ,sBAAsB;AAAA,EACjD,MAAM,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EACrC,QAAQ,EAAE,KAAK,CAAC,QAAQ,MAAM,MAAM,QAAQ,IAAI,CAAC,EAAE,QAAQ,MAAM;AAAA,EACjE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EAC5C,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,WAAW,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,cAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAChC,eAAe,EAAE,OAAO,EAAE,QAAQ,GAAI;AACxC,CAAC;;;ADVD,OAAO,OAAO;AAEP,SAAS,WAAW,UAA2B,CAAC,GAAW;AAEhE,MAAI,SAA0B;AAAA,IAC5B,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,IACX,cAAc;AAAA,IACd,OAAO;AAAA,IACP,eAAe;AAAA,EACjB;AAGA,QAAM,cAAc,CAAC,WAAW,cAAc;AAC9C,aAAW,QAAQ,aAAa;AAC9B,UAAM,aAAa,QAAQ,QAAQ,IAAI,GAAG,IAAI;AAC9C,QAAI,WAAW,UAAU,GAAG;AAC1B,UAAI;AAEF,cAAM,UAAU,aAAa,YAAY,OAAO;AAChD,cAAM,aAAa,KAAK,MAAM,OAAO;AACrC,iBAAS,EAAE,GAAG,QAAQ,GAAG,WAAW;AACpC,gBAAQ,IAAI,wBAAwB,IAAI,EAAE;AAC1C;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,KAAK,wCAAwC,IAAI,KAAK,KAAK;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAGA,MAAI,QAAQ,IAAI,iBAAiB;AAC/B,WAAO,YAAY,QAAQ,IAAI;AAAA,EACjC;AACA,MAAI,QAAQ,IAAI,cAAc;AAC5B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,cAAc;AAC5B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,WAAW;AACzB,WAAO,OAAO,QAAQ,IAAI;AAAA,EAC5B;AACA,MAAI,QAAQ,IAAI,aAAa;AAC3B,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,MAAI,QAAQ,IAAI,kBAAkB;AAChC,WAAO,cAAc,QAAQ,IAAI;AAAA,EACnC;AAGA,WAAS,EAAE,GAAG,QAAQ,GAAG,QAAQ;AAGjC,MAAI;AACF,WAAO,aAAa,MAAM,MAAM;AAAA,EAClC,SAAS,OAAO;AACd,QAAI,iBAAiB,OAAO;AAC1B,YAAM,IAAI,MAAM,0BAA0B,MAAM,OAAO,EAAE;AAAA,IAC3D;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,eAAe,QAA0B;AACvD,QAAM,SAAmB,CAAC;AAE1B,MAAI,CAAC,OAAO,WAAW;AACrB,WAAO,KAAK,8FAA8F;AAAA,EAC5G;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO,KAAK,qFAAqF;AAAA,EACnG;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts"],"sourcesContent":["import fetch from 'node-fetch'\nimport type { Config, ApiResponse, ReleaseResponse } from './types.js'\n\nexport class LezuApiClient {\n private config: Config\n\n constructor(config: Config) {\n this.config = config\n }\n\n private async request<T>(endpoint: string, options: any = {}): Promise<T> {\n const url = `${this.config.apiUrl}${endpoint}`\n \n const response = await fetch(url, {\n ...options,\n headers: {\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'Content-Type': 'application/json',\n ...options.headers\n }\n })\n\n if (!response.ok) {\n const error = await response.text()\n throw new Error(`API request failed: ${response.status} ${response.statusText}\\n${error}`)\n }\n\n return response.json() as Promise<T>\n }\n\n async getTranslations(): Promise<ApiResponse> {\n let endpoint = `/v1/translations/bundle?environment=${this.config.environment}`\n \n if (this.config.release) {\n endpoint = `/v1/releases/${this.config.release}/bundle`\n }\n\n // Add language filter if specified\n if (this.config.languages && this.config.languages.length > 0) {\n const params = new URLSearchParams()\n this.config.languages.forEach(lang => params.append('languages', lang))\n endpoint += `?${params.toString()}`\n }\n\n const response = await this.request<any>(endpoint)\n \n // Transform the response to match our expected format\n return {\n translations: response.translations || response,\n meta: {\n version: response.version,\n timestamp: response.timestamp || new Date().toISOString(),\n languages: response.languages || Object.keys(response.translations || response)\n }\n }\n }\n\n async getReleases(): Promise<ReleaseResponse> {\n return this.request<ReleaseResponse>(\n `/v1/releases?environment=${this.config.environment}`\n )\n }\n\n async getLatestRelease(): Promise<string | null> {\n try {\n const releases = await this.getReleases()\n if (releases.releases && releases.releases.length > 0) {\n // Releases are ordered by created_at desc, so first one is latest\n return releases.releases[0].id\n }\n return null\n } catch (error) {\n console.warn('Failed to fetch latest release:', error)\n return null\n }\n }\n\n async getLanguages(): Promise<any> {\n return this.request<any>(`/v1/languages`)\n }\n\n async addTranslationKey(key: string, translations: Record<string, string>): Promise<any> {\n return this.request<any>(\n `/v1/keys`,\n {\n method: 'POST',\n body: JSON.stringify({ key, translations })\n }\n )\n }\n\n async translateKey(text: string, sourceLanguage: string, targetLanguages: string[]): Promise<Record<string, string>> {\n // Use batch translate for efficiency\n const response = await this.request<any>('/v1/translations/translate/batch', {\n method: 'POST',\n body: JSON.stringify({\n texts: [text],\n sourceLanguage,\n targetLanguages\n })\n })\n \n return response.translations[text] || {}\n }\n\n async createRelease(data: {\n version?: string\n name?: string\n description?: string\n reviewedOnly?: boolean\n } = {}): Promise<any> {\n return this.request<any>(\n `/v1/releases`,\n {\n method: 'POST',\n body: JSON.stringify({\n environment: this.config.environment || 'production',\n version: data.version || new Date().toISOString().split('T')[0],\n name: data.name,\n description: data.description,\n reviewedOnly: data.reviewedOnly || false,\n setAsCurrent: true\n })\n }\n )\n }\n\n async getProject(): Promise<any> {\n return this.request<any>(`/v1/projects/${this.config.projectId}`)\n }\n}"],"mappings":"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","names":[]}
|
package/dist/get-N7YBCERI.js
DELETED
package/dist/load-5U463JIB.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|