@localess/cli 3.0.1-dev.20260410071322 → 3.0.1-dev.20260412201733
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/index.d.ts +1 -1
- package/dist/index.mjs +382 -661
- package/package.json +6 -5
- package/dist/index.d.mts +0 -1
- package/dist/index.js +0 -697
package/dist/index.js
DELETED
|
@@ -1,697 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
-
mod
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
// src/program.ts
|
|
27
|
-
var import_commander8 = require("commander");
|
|
28
|
-
|
|
29
|
-
// src/commands/login/index.ts
|
|
30
|
-
var import_commander = require("commander");
|
|
31
|
-
var import_prompts = require("@inquirer/prompts");
|
|
32
|
-
|
|
33
|
-
// src/utils.ts
|
|
34
|
-
var RESET = "\x1B[0m";
|
|
35
|
-
var FG_BLUE = "\x1B[34m";
|
|
36
|
-
function dotToNestedObject(input2) {
|
|
37
|
-
const result = {};
|
|
38
|
-
for (const [key, value] of Object.entries(input2)) {
|
|
39
|
-
const parts = key.split(".");
|
|
40
|
-
let current = result;
|
|
41
|
-
for (let i = 0; i < parts.length; i++) {
|
|
42
|
-
if (i === parts.length - 1) {
|
|
43
|
-
current[parts[i]] = value;
|
|
44
|
-
} else {
|
|
45
|
-
if (!(parts[i] in current)) {
|
|
46
|
-
current[parts[i]] = {};
|
|
47
|
-
}
|
|
48
|
-
current = current[parts[i]];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// src/cache.ts
|
|
56
|
-
var NoCache = class {
|
|
57
|
-
set(key, value) {
|
|
58
|
-
}
|
|
59
|
-
get(key) {
|
|
60
|
-
return void 0;
|
|
61
|
-
}
|
|
62
|
-
has(key) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var TTLCache = class {
|
|
67
|
-
/**
|
|
68
|
-
* Creates a TTLCache with a specified time-to-live (TTL) for each entry.
|
|
69
|
-
* default is 5 minutes (300000 ms).
|
|
70
|
-
* @param ttlMs
|
|
71
|
-
*/
|
|
72
|
-
constructor(ttlMs = 3e5) {
|
|
73
|
-
this.ttlMs = ttlMs;
|
|
74
|
-
}
|
|
75
|
-
ttlMs;
|
|
76
|
-
cache = /* @__PURE__ */ new Map();
|
|
77
|
-
set(key, value) {
|
|
78
|
-
this.cache.set(key, { value, expiresAt: Date.now() + this.ttlMs });
|
|
79
|
-
}
|
|
80
|
-
get(key) {
|
|
81
|
-
const entry = this.cache.get(key);
|
|
82
|
-
if (!entry) return void 0;
|
|
83
|
-
if (Date.now() > entry.expiresAt) {
|
|
84
|
-
this.cache.delete(key);
|
|
85
|
-
return void 0;
|
|
86
|
-
}
|
|
87
|
-
return entry.value;
|
|
88
|
-
}
|
|
89
|
-
has(key) {
|
|
90
|
-
return this.get(key) !== void 0;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// src/client.ts
|
|
95
|
-
var LOG_GROUP = `${FG_BLUE}[Localess:Client]${RESET}`;
|
|
96
|
-
async function fetchWithRetry(url, options, retryCount = 3, retryDelay = 500, debug) {
|
|
97
|
-
let attempt = 0;
|
|
98
|
-
let lastError;
|
|
99
|
-
while (attempt <= retryCount) {
|
|
100
|
-
try {
|
|
101
|
-
const response = await fetch(url, options);
|
|
102
|
-
if (!response.ok && response.status >= 500) {
|
|
103
|
-
if (debug) {
|
|
104
|
-
console.log(LOG_GROUP, `fetchWithRetry: HTTP ${response.status} on attempt ${attempt + 1}`);
|
|
105
|
-
}
|
|
106
|
-
lastError = new Error(`HTTP ${response.status}`);
|
|
107
|
-
} else {
|
|
108
|
-
return response;
|
|
109
|
-
}
|
|
110
|
-
} catch (err) {
|
|
111
|
-
if (debug) {
|
|
112
|
-
console.log(LOG_GROUP, `fetchWithRetry: network error on attempt ${attempt + 1}`, err);
|
|
113
|
-
}
|
|
114
|
-
lastError = err;
|
|
115
|
-
}
|
|
116
|
-
attempt++;
|
|
117
|
-
if (attempt <= retryCount) {
|
|
118
|
-
await new Promise((res) => setTimeout(res, retryDelay));
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
throw lastError;
|
|
122
|
-
}
|
|
123
|
-
function localessClient(options) {
|
|
124
|
-
if (options.debug) {
|
|
125
|
-
console.log(LOG_GROUP, "Client Options : ", options);
|
|
126
|
-
}
|
|
127
|
-
const normalizedOrigin = options.origin.replace(/\/+$/, "");
|
|
128
|
-
const fetchOptions = {
|
|
129
|
-
redirect: "follow",
|
|
130
|
-
headers: {
|
|
131
|
-
"Content-Type": "application/json",
|
|
132
|
-
"Accept": "application/json",
|
|
133
|
-
"X-Localess-Agent": "Localess-CLI-Client",
|
|
134
|
-
"X-Localess-Agent-Version": "0.9.0"
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
const cache = options.cacheTTL === false ? new NoCache() : new TTLCache(options.cacheTTL);
|
|
138
|
-
return {
|
|
139
|
-
async getSpace() {
|
|
140
|
-
if (options.debug) {
|
|
141
|
-
console.log(LOG_GROUP, "getSpace()");
|
|
142
|
-
}
|
|
143
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}?token=${options.token}`;
|
|
144
|
-
if (options.debug) {
|
|
145
|
-
console.log(LOG_GROUP, "getSpace fetch url : ", url);
|
|
146
|
-
}
|
|
147
|
-
if (cache.has(url)) {
|
|
148
|
-
if (options.debug) {
|
|
149
|
-
console.log(LOG_GROUP, "getSpace cache hit");
|
|
150
|
-
}
|
|
151
|
-
return cache.get(url);
|
|
152
|
-
}
|
|
153
|
-
try {
|
|
154
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
155
|
-
if (options.debug) {
|
|
156
|
-
console.log(LOG_GROUP, "getSpace status : ", response.status);
|
|
157
|
-
}
|
|
158
|
-
const data = await response.json();
|
|
159
|
-
cache.set(url, data);
|
|
160
|
-
return data;
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error(LOG_GROUP, "getSpace error : ", error);
|
|
163
|
-
return {};
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
async getLinks(params) {
|
|
167
|
-
if (options.debug) {
|
|
168
|
-
console.log(LOG_GROUP, "getLinks() params : ", JSON.stringify(params));
|
|
169
|
-
}
|
|
170
|
-
let kind = "";
|
|
171
|
-
if (params?.kind) {
|
|
172
|
-
kind = `&kind=${params.kind}`;
|
|
173
|
-
}
|
|
174
|
-
let parentSlug = "";
|
|
175
|
-
if (params?.parentSlug) {
|
|
176
|
-
parentSlug = `&parentSlug=${params.parentSlug}`;
|
|
177
|
-
}
|
|
178
|
-
let excludeChildren = "";
|
|
179
|
-
if (params?.excludeChildren) {
|
|
180
|
-
excludeChildren = `&excludeChildren=${params.excludeChildren}`;
|
|
181
|
-
}
|
|
182
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/links?token=${options.token}${kind}${parentSlug}${excludeChildren}`;
|
|
183
|
-
if (options.debug) {
|
|
184
|
-
console.log(LOG_GROUP, "getLinks fetch url : ", url);
|
|
185
|
-
}
|
|
186
|
-
if (cache.has(url)) {
|
|
187
|
-
if (options.debug) {
|
|
188
|
-
console.log(LOG_GROUP, "getLinks cache hit");
|
|
189
|
-
}
|
|
190
|
-
return cache.get(url);
|
|
191
|
-
}
|
|
192
|
-
try {
|
|
193
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
194
|
-
if (options.debug) {
|
|
195
|
-
console.log(LOG_GROUP, "getLinks status : ", response.status);
|
|
196
|
-
}
|
|
197
|
-
const data = await response.json();
|
|
198
|
-
cache.set(url, data);
|
|
199
|
-
return data;
|
|
200
|
-
} catch (error) {
|
|
201
|
-
console.error(LOG_GROUP, "getLinks error : ", error);
|
|
202
|
-
return {};
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
async getContentBySlug(slug, params) {
|
|
206
|
-
if (options.debug) {
|
|
207
|
-
console.log(LOG_GROUP, "getContentBySlug() slug : ", slug);
|
|
208
|
-
console.log(LOG_GROUP, "getContentBySlug() params : ", JSON.stringify(params));
|
|
209
|
-
}
|
|
210
|
-
let version = "";
|
|
211
|
-
if (options?.version && options.version == "draft") {
|
|
212
|
-
version = `&version=${options.version}`;
|
|
213
|
-
}
|
|
214
|
-
if (params?.version && params.version == "draft") {
|
|
215
|
-
version = `&version=${params.version}`;
|
|
216
|
-
}
|
|
217
|
-
const locale = params?.locale ? `&locale=${params.locale}` : "";
|
|
218
|
-
const resolveReference = params?.resolveReference ? `&resolveReference=${params.resolveReference}` : "";
|
|
219
|
-
const resolveLink = params?.resolveLink ? `&resolveLink=${params.resolveLink}` : "";
|
|
220
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/contents/slugs/${slug}?token=${options.token}${version}${locale}${resolveReference}${resolveLink}`;
|
|
221
|
-
if (options.debug) {
|
|
222
|
-
console.log(LOG_GROUP, "getContentBySlug fetch url : ", url);
|
|
223
|
-
}
|
|
224
|
-
if (cache.has(url)) {
|
|
225
|
-
if (options.debug) {
|
|
226
|
-
console.log(LOG_GROUP, "getContentBySlug cache hit");
|
|
227
|
-
}
|
|
228
|
-
return cache.get(url);
|
|
229
|
-
}
|
|
230
|
-
try {
|
|
231
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
232
|
-
if (options.debug) {
|
|
233
|
-
console.log(LOG_GROUP, "getContentBySlug status : ", response.status);
|
|
234
|
-
}
|
|
235
|
-
const data = await response.json();
|
|
236
|
-
cache.set(url, data);
|
|
237
|
-
return data;
|
|
238
|
-
} catch (error) {
|
|
239
|
-
console.error(LOG_GROUP, "getContentBySlug error : ", error);
|
|
240
|
-
return {};
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
async getContentById(id, params) {
|
|
244
|
-
if (options.debug) {
|
|
245
|
-
console.log(LOG_GROUP, "getContentById() id : ", id);
|
|
246
|
-
console.log(LOG_GROUP, "getContentById() params : ", JSON.stringify(params));
|
|
247
|
-
}
|
|
248
|
-
let version = "";
|
|
249
|
-
if (options?.version && options.version == "draft") {
|
|
250
|
-
version = `&version=${options.version}`;
|
|
251
|
-
}
|
|
252
|
-
if (params?.version && params.version == "draft") {
|
|
253
|
-
version = `&version=${params.version}`;
|
|
254
|
-
}
|
|
255
|
-
const locale = params?.locale ? `&locale=${params.locale}` : "";
|
|
256
|
-
const resolveReference = params?.resolveReference ? `&resolveReference=${params.resolveReference}` : "";
|
|
257
|
-
const resolveLink = params?.resolveLink ? `&resolveLink=${params.resolveLink}` : "";
|
|
258
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/contents/${id}?token=${options.token}${version}${locale}${resolveReference}${resolveLink}`;
|
|
259
|
-
if (options.debug) {
|
|
260
|
-
console.log(LOG_GROUP, "getContentById fetch url : ", url);
|
|
261
|
-
}
|
|
262
|
-
if (cache.has(url)) {
|
|
263
|
-
if (options.debug) {
|
|
264
|
-
console.log(LOG_GROUP, "getContentById cache hit");
|
|
265
|
-
}
|
|
266
|
-
return cache.get(url);
|
|
267
|
-
}
|
|
268
|
-
try {
|
|
269
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
270
|
-
if (options.debug) {
|
|
271
|
-
console.log(LOG_GROUP, "getContentById status : ", response.status);
|
|
272
|
-
}
|
|
273
|
-
const data = await response.json();
|
|
274
|
-
cache.set(url, data);
|
|
275
|
-
return data;
|
|
276
|
-
} catch (error) {
|
|
277
|
-
console.error(LOG_GROUP, "getContentById error : ", error);
|
|
278
|
-
return {};
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
async getTranslations(locale, params) {
|
|
282
|
-
if (options.debug) {
|
|
283
|
-
console.log(LOG_GROUP, "getTranslations() locale : ", locale);
|
|
284
|
-
console.log(LOG_GROUP, "getTranslations() params : ", JSON.stringify(params));
|
|
285
|
-
}
|
|
286
|
-
let version = "";
|
|
287
|
-
if (options?.version && options.version == "draft") {
|
|
288
|
-
version = `&version=${options.version}`;
|
|
289
|
-
}
|
|
290
|
-
if (params?.version && params.version == "draft") {
|
|
291
|
-
version = `&version=${params.version}`;
|
|
292
|
-
}
|
|
293
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/translations/${locale}?token=${options.token}${version}`;
|
|
294
|
-
if (options.debug) {
|
|
295
|
-
console.log(LOG_GROUP, "getTranslations fetch url : ", url);
|
|
296
|
-
}
|
|
297
|
-
if (cache.has(url)) {
|
|
298
|
-
if (options.debug) {
|
|
299
|
-
console.log(LOG_GROUP, "getTranslations cache hit");
|
|
300
|
-
}
|
|
301
|
-
return cache.get(url);
|
|
302
|
-
}
|
|
303
|
-
try {
|
|
304
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
305
|
-
if (options.debug) {
|
|
306
|
-
console.log(LOG_GROUP, "getTranslations status : ", response.status);
|
|
307
|
-
}
|
|
308
|
-
const data = await response.json();
|
|
309
|
-
cache.set(url, data);
|
|
310
|
-
return data;
|
|
311
|
-
} catch (error) {
|
|
312
|
-
console.error(LOG_GROUP, "getTranslations error : ", error);
|
|
313
|
-
return {};
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
async updateTranslations(locale, type, values, dryRun) {
|
|
317
|
-
if (options.debug) {
|
|
318
|
-
console.log(LOG_GROUP, "updateTranslations() locale : ", locale);
|
|
319
|
-
console.log(LOG_GROUP, "updateTranslations() type : ", type);
|
|
320
|
-
console.log(LOG_GROUP, "updateTranslations() values : ", JSON.stringify(values));
|
|
321
|
-
}
|
|
322
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/translations/${locale}`;
|
|
323
|
-
if (options.debug) {
|
|
324
|
-
console.log(LOG_GROUP, "updateTranslations fetch url : ", url);
|
|
325
|
-
}
|
|
326
|
-
const body = {
|
|
327
|
-
type,
|
|
328
|
-
values,
|
|
329
|
-
dryRun
|
|
330
|
-
};
|
|
331
|
-
try {
|
|
332
|
-
const response = await fetchWithRetry(url, {
|
|
333
|
-
method: "POST",
|
|
334
|
-
headers: {
|
|
335
|
-
"X-API-KEY": options.token,
|
|
336
|
-
...fetchOptions.headers
|
|
337
|
-
},
|
|
338
|
-
body: JSON.stringify(body)
|
|
339
|
-
}, options.retryCount, options.retryDelay, options.debug);
|
|
340
|
-
if (options.debug) {
|
|
341
|
-
console.log(LOG_GROUP, "updateTranslations status : ", response.status);
|
|
342
|
-
}
|
|
343
|
-
return response.json();
|
|
344
|
-
} catch (error) {
|
|
345
|
-
console.error(LOG_GROUP, "updateTranslations error : ", error);
|
|
346
|
-
}
|
|
347
|
-
},
|
|
348
|
-
async getOpenApi() {
|
|
349
|
-
if (options.debug) {
|
|
350
|
-
console.log(LOG_GROUP, "getOpenApi()");
|
|
351
|
-
}
|
|
352
|
-
let url = `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/open-api?token=${options.token}`;
|
|
353
|
-
if (options.debug) {
|
|
354
|
-
console.log(LOG_GROUP, "getOpenApi fetch url : ", url);
|
|
355
|
-
}
|
|
356
|
-
if (cache.has(url)) {
|
|
357
|
-
if (options.debug) {
|
|
358
|
-
console.log(LOG_GROUP, "getTranslations cache hit");
|
|
359
|
-
}
|
|
360
|
-
return cache.get(url);
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
const response = await fetchWithRetry(url, fetchOptions, options.retryCount, options.retryDelay, options.debug);
|
|
364
|
-
if (options.debug) {
|
|
365
|
-
console.log(LOG_GROUP, "getOpenApi status : ", response.status);
|
|
366
|
-
}
|
|
367
|
-
const data = await response.json();
|
|
368
|
-
cache.set(url, data);
|
|
369
|
-
return data;
|
|
370
|
-
} catch (error) {
|
|
371
|
-
console.error(LOG_GROUP, "getOpenApi error : ", error);
|
|
372
|
-
return {};
|
|
373
|
-
}
|
|
374
|
-
},
|
|
375
|
-
syncScriptUrl() {
|
|
376
|
-
return `${normalizedOrigin}/scripts/sync-v1.js`;
|
|
377
|
-
},
|
|
378
|
-
assetLink(asset) {
|
|
379
|
-
if (typeof asset === "string") {
|
|
380
|
-
return `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/assets/${asset}`;
|
|
381
|
-
} else {
|
|
382
|
-
return `${normalizedOrigin}/api/v1/spaces/${options.spaceId}/assets/${asset.uri}`;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// src/session.ts
|
|
389
|
-
var import_promises2 = require("fs/promises");
|
|
390
|
-
var import_node_path2 = require("path");
|
|
391
|
-
var process2 = __toESM(require("process"));
|
|
392
|
-
|
|
393
|
-
// src/file.ts
|
|
394
|
-
var import_promises = require("fs/promises");
|
|
395
|
-
var import_node_path = require("path");
|
|
396
|
-
var DEFAULT_CONFIG_DIR = ".localess";
|
|
397
|
-
async function writeFile(filePath, data, option) {
|
|
398
|
-
const resolvedPath = (0, import_node_path.parse)(filePath).dir;
|
|
399
|
-
try {
|
|
400
|
-
await (0, import_promises.mkdir)(resolvedPath, { recursive: true });
|
|
401
|
-
} catch (mkdirError) {
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
try {
|
|
405
|
-
await (0, import_promises.writeFile)(filePath, data, option);
|
|
406
|
-
} catch (writeError) {
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
async function readFile(filePath) {
|
|
410
|
-
return (0, import_promises.readFile)(filePath, "utf-8");
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// src/session.ts
|
|
414
|
-
var CREDENTIALS_PATH = (0, import_node_path2.join)(process2.cwd(), DEFAULT_CONFIG_DIR, "credentials.json");
|
|
415
|
-
async function getSession() {
|
|
416
|
-
let session = {
|
|
417
|
-
isLoggedIn: false
|
|
418
|
-
};
|
|
419
|
-
const token = process2.env.LOCALESS_TOKEN;
|
|
420
|
-
const space = process2.env.LOCALESS_SPACE;
|
|
421
|
-
const origin = process2.env.LOCALESS_ORIGIN;
|
|
422
|
-
if (token && space && origin) {
|
|
423
|
-
console.debug(`Login in using environment variables.`);
|
|
424
|
-
return {
|
|
425
|
-
isLoggedIn: true,
|
|
426
|
-
space,
|
|
427
|
-
origin,
|
|
428
|
-
token,
|
|
429
|
-
method: "env"
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
try {
|
|
433
|
-
await (0, import_promises2.access)(CREDENTIALS_PATH);
|
|
434
|
-
const content = await (0, import_promises2.readFile)(CREDENTIALS_PATH, "utf8");
|
|
435
|
-
const parsedContent = JSON.parse(content);
|
|
436
|
-
if (Object.keys(parsedContent).length === 0) {
|
|
437
|
-
return session;
|
|
438
|
-
}
|
|
439
|
-
if (parsedContent.origin && parsedContent.token && parsedContent.space) {
|
|
440
|
-
console.debug(`Login in using credentials file.`);
|
|
441
|
-
return {
|
|
442
|
-
isLoggedIn: true,
|
|
443
|
-
space: parsedContent.space,
|
|
444
|
-
origin: parsedContent.origin,
|
|
445
|
-
token: parsedContent.token,
|
|
446
|
-
method: "file"
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
} catch (e) {
|
|
450
|
-
}
|
|
451
|
-
return session;
|
|
452
|
-
}
|
|
453
|
-
async function persistSession(data) {
|
|
454
|
-
if (data.origin && data.token && data.space) {
|
|
455
|
-
await writeFile(CREDENTIALS_PATH, JSON.stringify(data, null, 2), { mode: 384 });
|
|
456
|
-
console.log("Add session credentials to file system.");
|
|
457
|
-
console.log("Add .localess to .gitignore to avoid committing them to your repository.");
|
|
458
|
-
} else {
|
|
459
|
-
throw new Error("Cannot persist session: missing required fields.");
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
async function clearSession() {
|
|
463
|
-
try {
|
|
464
|
-
await (0, import_promises2.access)(CREDENTIALS_PATH);
|
|
465
|
-
await writeFile(CREDENTIALS_PATH, "{}", { mode: 384 });
|
|
466
|
-
} catch (error) {
|
|
467
|
-
throw new Error("Failed to clear session credentials.");
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// src/commands/login/index.ts
|
|
472
|
-
var loginCommand = new import_commander.Command("login").description("Login to Localess CLI").option("-o, --origin <origin>", "Origin of the Localess instance").option("-s, --space <space>", "Space ID to login to").option("-t, --token <token>", "Token to login to Localess CLI").action(async (options) => {
|
|
473
|
-
const session = await getSession();
|
|
474
|
-
if (session.isLoggedIn && session.method === "file") {
|
|
475
|
-
console.log("Already logged in.");
|
|
476
|
-
console.log('If you want to log in with different credentials, please log out first using "localess logout" command.');
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
const origin = options.origin ?? await (0, import_prompts.input)({
|
|
480
|
-
message: "Origin of the Localess instance:",
|
|
481
|
-
required: true
|
|
482
|
-
});
|
|
483
|
-
const space = options.space ?? await (0, import_prompts.input)({
|
|
484
|
-
message: "Space ID:",
|
|
485
|
-
required: true
|
|
486
|
-
});
|
|
487
|
-
const token = options.token ?? await (0, import_prompts.password)({
|
|
488
|
-
message: "Token:",
|
|
489
|
-
mask: true
|
|
490
|
-
});
|
|
491
|
-
const client = localessClient({
|
|
492
|
-
origin,
|
|
493
|
-
spaceId: space,
|
|
494
|
-
token
|
|
495
|
-
});
|
|
496
|
-
try {
|
|
497
|
-
const spaceData = await client.getSpace();
|
|
498
|
-
console.log(`Successfully logged in to space: ${spaceData.name} (${spaceData.id})`);
|
|
499
|
-
await persistSession({ origin, space, token });
|
|
500
|
-
} catch (e) {
|
|
501
|
-
console.error("Login failed");
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
// src/commands/logout/index.ts
|
|
506
|
-
var import_commander2 = require("commander");
|
|
507
|
-
var logoutCommand = new import_commander2.Command("logout").description("Logout from Localess CLI").action(async () => {
|
|
508
|
-
console.log("Logging out...");
|
|
509
|
-
const session = await getSession();
|
|
510
|
-
if (!session.isLoggedIn) {
|
|
511
|
-
console.log("Not currently logged in.");
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
if (session.method === "env") {
|
|
515
|
-
console.log("You are logged in using environment variables. To log out, unset LOCALESS_TOKEN, LOCALESS_SPACE, and LOCALESS_ORIGIN.");
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
try {
|
|
519
|
-
await clearSession();
|
|
520
|
-
console.log("Successfully logged out.");
|
|
521
|
-
} catch (e) {
|
|
522
|
-
console.error("Failed to log out:", e);
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
// src/commands/types/index.ts
|
|
527
|
-
var import_commander4 = require("commander");
|
|
528
|
-
|
|
529
|
-
// src/commands/types/generate/index.ts
|
|
530
|
-
var import_commander3 = require("commander");
|
|
531
|
-
var import_orval = require("orval");
|
|
532
|
-
var import_node_path3 = require("path");
|
|
533
|
-
var import_node_process = __toESM(require("process"));
|
|
534
|
-
var TYPES_PATH = (0, import_node_path3.join)(import_node_process.default.cwd(), DEFAULT_CONFIG_DIR, "localess.ts");
|
|
535
|
-
var typesGenerateCommand = new import_commander3.Command("generate").description("Generate types for your schemas").option("-p, --path <path>", "Path to the file where to save the generated types. Default is .localess/localess.ts", TYPES_PATH).action(async (options) => {
|
|
536
|
-
console.log("Types in with options:", options);
|
|
537
|
-
const session = await getSession();
|
|
538
|
-
if (!session.isLoggedIn) {
|
|
539
|
-
console.error("Not logged in");
|
|
540
|
-
console.error('Please log in first using "localess login" command');
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
const client = localessClient({
|
|
544
|
-
origin: session.origin,
|
|
545
|
-
spaceId: session.space,
|
|
546
|
-
token: session.token
|
|
547
|
-
});
|
|
548
|
-
console.log("Fetching OpenAPI specification from Localess...");
|
|
549
|
-
const specification = await client.getOpenApi();
|
|
550
|
-
console.log("Generating types from OpenAPI specification...");
|
|
551
|
-
try {
|
|
552
|
-
await (0, import_orval.generate)({
|
|
553
|
-
input: {
|
|
554
|
-
target: specification
|
|
555
|
-
},
|
|
556
|
-
output: {
|
|
557
|
-
target: options.path,
|
|
558
|
-
client: "fetch",
|
|
559
|
-
mode: "single"
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
console.log(`Types generated successfully at ${options.path}`);
|
|
563
|
-
} catch (e) {
|
|
564
|
-
console.error(e);
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
|
|
568
|
-
// src/commands/types/index.ts
|
|
569
|
-
var typesCommand = new import_commander4.Command("types").description("Generate types for your schemas").addCommand(typesGenerateCommand);
|
|
570
|
-
|
|
571
|
-
// src/commands/translations/index.ts
|
|
572
|
-
var import_commander7 = require("commander");
|
|
573
|
-
|
|
574
|
-
// src/commands/translations/push/index.ts
|
|
575
|
-
var import_commander5 = require("commander");
|
|
576
|
-
|
|
577
|
-
// src/models/translations.ts
|
|
578
|
-
var TranslationUpdateType = /* @__PURE__ */ ((TranslationUpdateType2) => {
|
|
579
|
-
TranslationUpdateType2["ADD_MISSING"] = "add-missing";
|
|
580
|
-
TranslationUpdateType2["UPDATE_EXISTING"] = "update-existing";
|
|
581
|
-
TranslationUpdateType2["DELETE_MISSING"] = "delete-missing";
|
|
582
|
-
return TranslationUpdateType2;
|
|
583
|
-
})(TranslationUpdateType || {});
|
|
584
|
-
var TranslationFileFormat = /* @__PURE__ */ ((TranslationFileFormat2) => {
|
|
585
|
-
TranslationFileFormat2["FLAT"] = "flat";
|
|
586
|
-
TranslationFileFormat2["NESTED"] = "nested";
|
|
587
|
-
return TranslationFileFormat2;
|
|
588
|
-
})(TranslationFileFormat || {});
|
|
589
|
-
|
|
590
|
-
// src/models/translation.zod.ts
|
|
591
|
-
var import_zod = require("zod");
|
|
592
|
-
var zLocaleTranslationsSchema = import_zod.z.record(import_zod.z.string(), import_zod.z.string());
|
|
593
|
-
var zTranslationUpdateTypeSchema = import_zod.z.enum(["add-missing", "update-existing"]);
|
|
594
|
-
var zTranslationUpdateSchema = import_zod.z.object({
|
|
595
|
-
type: zTranslationUpdateTypeSchema,
|
|
596
|
-
values: zLocaleTranslationsSchema
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
// src/commands/translations/push/index.ts
|
|
600
|
-
var translationsPushCommand = new import_commander5.Command("push").argument("<locale>", "Locale to push").description("Push locale translations to Localess").requiredOption("-p, --path <path>", "Path to the translations file to push").option("-f, --format <format>", `File format. Possible values are : ${Object.values(TranslationFileFormat)}`, "flat" /* FLAT */).option("-t, --type <type>", `Push type. Possible values are : ${Object.values(TranslationUpdateType)}`, "add-missing" /* ADD_MISSING */).option("--dry-run", "Preview changes without applying them to Localess").action(async (locale, options) => {
|
|
601
|
-
console.log("Pushing translations with arguments:", locale);
|
|
602
|
-
console.log("Pushing translations with options:", options);
|
|
603
|
-
if (!zTranslationUpdateTypeSchema.safeParse(options.type).success) {
|
|
604
|
-
console.error("Invalid type provided. Possible values are :", Object.values(TranslationUpdateType));
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
const session = await getSession();
|
|
608
|
-
if (!session.isLoggedIn) {
|
|
609
|
-
console.error("Not logged in");
|
|
610
|
-
console.error('Please log in first using "localess login" command');
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
const client = localessClient({
|
|
614
|
-
origin: session.origin,
|
|
615
|
-
spaceId: session.space,
|
|
616
|
-
token: session.token
|
|
617
|
-
});
|
|
618
|
-
if (options.dryRun) {
|
|
619
|
-
console.warn("Dry run mode enabled: No changes will be made.");
|
|
620
|
-
}
|
|
621
|
-
if (options.format === "nested" /* NESTED */) {
|
|
622
|
-
console.error("Nested format is not implemented yet. Please use flat format for now.");
|
|
623
|
-
}
|
|
624
|
-
console.log("Reading translations file from:", options.path);
|
|
625
|
-
const fileContent = await readFile(options.path);
|
|
626
|
-
const translationValues = JSON.parse(fileContent);
|
|
627
|
-
const pResult = zLocaleTranslationsSchema.safeParse(translationValues);
|
|
628
|
-
if (!pResult.success) {
|
|
629
|
-
console.error("Invalid translations file format:", pResult.error);
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
console.log("Pushing translations to Localess with locale:", locale, "and type:", options.type);
|
|
633
|
-
const response = await client.updateTranslations(locale, options.type, translationValues, options.dryRun);
|
|
634
|
-
if (response) {
|
|
635
|
-
if (response.dryRun) {
|
|
636
|
-
console.log("Dry run results:");
|
|
637
|
-
}
|
|
638
|
-
console.log("Successfully pushed translations to Localess");
|
|
639
|
-
console.log("Summary:", response.message);
|
|
640
|
-
if (response.ids) {
|
|
641
|
-
console.log("Updated translation IDs:", response.ids);
|
|
642
|
-
}
|
|
643
|
-
} else {
|
|
644
|
-
console.log("Something went wrong while pushing translations to Localess");
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
|
|
648
|
-
// src/commands/translations/pull/index.ts
|
|
649
|
-
var import_commander6 = require("commander");
|
|
650
|
-
var translationsPullCommand = new import_commander6.Command("pull").argument("<locale>", "Locale to pull").description("Pull locale translations from Localess").requiredOption("-p, --path <path>", "Path where the translations file will be saved").option("-f, --format <format>", `File format. Possible values are : ${Object.values(TranslationFileFormat)}`, "flat" /* FLAT */).action(async (locale, options) => {
|
|
651
|
-
console.log("Pulling translations with arguments:", locale);
|
|
652
|
-
console.log("Pulling translations with options:", options);
|
|
653
|
-
if (!Object.values(TranslationFileFormat).includes(options.format)) {
|
|
654
|
-
console.error("Invalid format provided. Possible values are :", Object.values(TranslationFileFormat));
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
const session = await getSession();
|
|
658
|
-
if (!session.isLoggedIn) {
|
|
659
|
-
console.error("Not logged in");
|
|
660
|
-
console.error('Please log in first using "localess login" command');
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
const client = localessClient({
|
|
664
|
-
origin: session.origin,
|
|
665
|
-
spaceId: session.space,
|
|
666
|
-
token: session.token
|
|
667
|
-
});
|
|
668
|
-
console.log("Pulling translations from Localess for locale:", locale);
|
|
669
|
-
const translations = await client.getTranslations(locale);
|
|
670
|
-
console.log("Saving translations in file:", options.path);
|
|
671
|
-
if (options.format === "flat" /* FLAT */) {
|
|
672
|
-
await writeFile(options.path, JSON.stringify(translations, null, 2));
|
|
673
|
-
} else if (options.format === "nested" /* NESTED */) {
|
|
674
|
-
const nestedTranslations = dotToNestedObject(translations);
|
|
675
|
-
await writeFile(options.path, JSON.stringify(nestedTranslations, null, 2));
|
|
676
|
-
}
|
|
677
|
-
console.log("Successfully saved translations from Localess");
|
|
678
|
-
});
|
|
679
|
-
|
|
680
|
-
// src/commands/translations/index.ts
|
|
681
|
-
var translationsCommand = new import_commander7.Command("translations").description("Manage translations").addCommand(translationsPushCommand).addCommand(translationsPullCommand);
|
|
682
|
-
|
|
683
|
-
// src/program.ts
|
|
684
|
-
var program = new import_commander8.Command();
|
|
685
|
-
program.name("Localess CLI").description("CLI tool for Localess platform management").version("0.0.6");
|
|
686
|
-
program.addCommand(loginCommand);
|
|
687
|
-
program.addCommand(logoutCommand);
|
|
688
|
-
program.addCommand(translationsCommand);
|
|
689
|
-
program.addCommand(typesCommand);
|
|
690
|
-
|
|
691
|
-
// src/index.ts
|
|
692
|
-
try {
|
|
693
|
-
program.parse(process.argv);
|
|
694
|
-
} catch (e) {
|
|
695
|
-
console.error("Error executing command:", e instanceof Error ? e.message : e);
|
|
696
|
-
process.exit(1);
|
|
697
|
-
}
|