@fluenti/cli 0.6.2 → 0.6.3
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/cli/src/extract-path.d.ts +18 -0
- package/dist/cli/src/extract-workflow.d.ts +17 -0
- package/dist/cli.cjs +10 -10
- package/dist/cli.js +270 -299
- package/dist/{compile-C3VLvhUf.cjs → compile-1ie6pZBL.cjs} +1 -1
- package/dist/compile-worker.cjs +1 -1
- package/dist/doctor-BjxAnm7z.cjs +23 -0
- package/dist/{doctor-BqXXxyST.js → doctor-CLfvuKpJ.js} +288 -181
- package/dist/index.cjs +1 -1
- package/dist/index.js +17 -96
- package/dist/{tsx-extractor-AOjsbOmp.cjs → tsx-extractor-DFptqjVk.cjs} +1 -1
- package/dist/vue-extractor.cjs +1 -1
- package/package.json +2 -2
- package/dist/doctor-xp8WS8sr.cjs +0 -23
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import
|
|
1
|
+
import { t as e } from "./tsx-extractor-C-HZNobu.js";
|
|
2
|
+
import { createPluginRunner as t, hashMessage as n, resolveLocaleCodes as r } from "@fluenti/core/compiler";
|
|
3
|
+
import * as i from "gettext-parser";
|
|
4
|
+
import { loadConfig as a } from "@fluenti/core/config";
|
|
5
|
+
import { appendFileSync as o, existsSync as s, mkdirSync as c, readFileSync as l, statSync as u, writeFileSync as d } from "node:fs";
|
|
6
|
+
import * as f from "node:path";
|
|
7
|
+
import { dirname as p, extname as m, resolve as h } from "node:path";
|
|
8
|
+
import { Worker as g } from "node:worker_threads";
|
|
9
|
+
import { availableParallelism as _ } from "node:os";
|
|
10
|
+
import { fileURLToPath as v } from "node:url";
|
|
11
|
+
import y from "fast-glob";
|
|
12
|
+
import { createHash as b } from "node:crypto";
|
|
13
|
+
import x from "consola";
|
|
11
14
|
//#region src/catalog.ts
|
|
12
|
-
function
|
|
15
|
+
function S(e, t, n) {
|
|
13
16
|
let r = new Set(t.map((e) => e.id)), i = /* @__PURE__ */ new Set(), a = {}, o = 0, s = 0, c = 0;
|
|
14
17
|
for (let r of t) {
|
|
15
|
-
let t = e[r.id], c = t ? void 0 :
|
|
18
|
+
let t = e[r.id], c = t ? void 0 : C(e, r, i), l = `${r.origin.file}:${r.origin.line}`, u = t ?? c?.entry;
|
|
16
19
|
if (c && i.add(c.id), u) a[r.id] = {
|
|
17
20
|
...u,
|
|
18
21
|
message: r.message ?? u.message,
|
|
@@ -25,7 +28,7 @@ function g(e, t, n) {
|
|
|
25
28
|
let e = a[r.id];
|
|
26
29
|
a[r.id] = {
|
|
27
30
|
...e,
|
|
28
|
-
origin:
|
|
31
|
+
origin: ee(e.origin, l)
|
|
29
32
|
};
|
|
30
33
|
} else a[r.id] = {
|
|
31
34
|
message: r.message,
|
|
@@ -57,28 +60,28 @@ function g(e, t, n) {
|
|
|
57
60
|
}
|
|
58
61
|
};
|
|
59
62
|
}
|
|
60
|
-
function
|
|
63
|
+
function ee(e, t) {
|
|
61
64
|
if (!e) return t;
|
|
62
65
|
let n = [...new Set([...Array.isArray(e) ? e : [e], t])];
|
|
63
66
|
return n.length === 1 ? n[0] : n;
|
|
64
67
|
}
|
|
65
|
-
function
|
|
68
|
+
function C(e, t, n) {
|
|
66
69
|
if (!t.context) return;
|
|
67
70
|
let r = `${t.origin.file}:${t.origin.line}`;
|
|
68
|
-
for (let [i, a] of Object.entries(e)) if (!n.has(i) && a.context === void 0 && a.message === t.message &&
|
|
71
|
+
for (let [i, a] of Object.entries(e)) if (!n.has(i) && a.context === void 0 && a.message === t.message && te(a.origin, r)) return {
|
|
69
72
|
id: i,
|
|
70
73
|
entry: a
|
|
71
74
|
};
|
|
72
75
|
}
|
|
73
|
-
function
|
|
74
|
-
return e ? (Array.isArray(e) ? e : [e]).some((e) => e === t ||
|
|
76
|
+
function te(e, t) {
|
|
77
|
+
return e ? (Array.isArray(e) ? e : [e]).some((e) => e === t || w(e) === w(t)) : !1;
|
|
75
78
|
}
|
|
76
|
-
function
|
|
79
|
+
function w(e) {
|
|
77
80
|
return e.match(/^(.*):\d+$/)?.[1] ?? e;
|
|
78
81
|
}
|
|
79
82
|
//#endregion
|
|
80
83
|
//#region src/json-format.ts
|
|
81
|
-
function
|
|
84
|
+
function T(e) {
|
|
82
85
|
let t = JSON.parse(e), n = {};
|
|
83
86
|
for (let [e, r] of Object.entries(t)) if (typeof r == "object" && r) {
|
|
84
87
|
let t = r;
|
|
@@ -94,7 +97,7 @@ function x(e) {
|
|
|
94
97
|
}
|
|
95
98
|
return n;
|
|
96
99
|
}
|
|
97
|
-
function
|
|
100
|
+
function E(e) {
|
|
98
101
|
let t = {};
|
|
99
102
|
for (let [n, r] of Object.entries(e)) {
|
|
100
103
|
let e = {};
|
|
@@ -104,13 +107,13 @@ function ee(e) {
|
|
|
104
107
|
}
|
|
105
108
|
//#endregion
|
|
106
109
|
//#region src/po-format.ts
|
|
107
|
-
var
|
|
108
|
-
function
|
|
109
|
-
for (let [i, a] of Object.entries(
|
|
110
|
-
if (!
|
|
111
|
-
let a = i || o.msgctxt || void 0, s = o.msgstr?.[0] ?? void 0, c = o.comments?.reference ?? void 0, l = c?.includes("\n") ? c.split("\n").map((e) => e.trim()).filter(Boolean) : c?.includes(" ") ? c.split(/\s+/).filter(Boolean) : c, u = Array.isArray(l) && l.length === 1 ? l[0] : l, d = !r && (o.comments?.flag?.includes("fuzzy") ?? !1), { comment: f, customId: p, sourceMessage: m } =
|
|
112
|
-
|
|
113
|
-
message: h ??
|
|
110
|
+
var D = "fluenti-id:";
|
|
111
|
+
function O(e, t, r) {
|
|
112
|
+
for (let [i, a] of Object.entries(e)) for (let [e, o] of Object.entries(a)) {
|
|
113
|
+
if (!e) continue;
|
|
114
|
+
let a = i || o.msgctxt || void 0, s = o.msgstr?.[0] ?? void 0, c = o.comments?.reference ?? void 0, l = c?.includes("\n") ? c.split("\n").map((e) => e.trim()).filter(Boolean) : c?.includes(" ") ? c.split(/\s+/).filter(Boolean) : c, u = Array.isArray(l) && l.length === 1 ? l[0] : l, d = !r && (o.comments?.flag?.includes("fuzzy") ?? !1), { comment: f, customId: p, sourceMessage: m } = j(o.comments?.extracted), h = m && (p !== void 0 || n(m, a) === e) ? m : void 0, g = p ?? (h ? e : n(e, a));
|
|
115
|
+
t[g] = {
|
|
116
|
+
message: h ?? e,
|
|
114
117
|
...a === void 0 ? {} : { context: a },
|
|
115
118
|
...f === void 0 ? {} : { comment: f },
|
|
116
119
|
...s ? { translation: s } : {},
|
|
@@ -120,43 +123,43 @@ function C(t, n, r) {
|
|
|
120
123
|
};
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
|
-
function
|
|
124
|
-
let
|
|
125
|
-
return
|
|
126
|
+
function k(e) {
|
|
127
|
+
let t = i.po.parse(e), n = {};
|
|
128
|
+
return O(t.translations ?? {}, n, !1), t.obsolete && O(t.obsolete, n, !0), n;
|
|
126
129
|
}
|
|
127
|
-
function
|
|
128
|
-
let
|
|
130
|
+
function A(e) {
|
|
131
|
+
let t = { "": { "": {
|
|
129
132
|
msgid: "",
|
|
130
133
|
msgstr: ["Content-Type: text/plain; charset=UTF-8\n"]
|
|
131
|
-
} } },
|
|
132
|
-
for (let [
|
|
133
|
-
let
|
|
134
|
-
msgid: a.message !== void 0 &&
|
|
134
|
+
} } }, r = {};
|
|
135
|
+
for (let [i, a] of Object.entries(e)) {
|
|
136
|
+
let e = {
|
|
137
|
+
msgid: a.message !== void 0 && n(a.message, a.context) === i ? a.message ?? i : i,
|
|
135
138
|
...a.context === void 0 ? {} : { msgctxt: a.context },
|
|
136
139
|
msgstr: [a.translation ?? ""]
|
|
137
140
|
}, o = {};
|
|
138
141
|
a.origin && !a.obsolete && (o.reference = Array.isArray(a.origin) ? a.origin.join("\n") : a.origin);
|
|
139
|
-
let s =
|
|
140
|
-
if (s && (o.extracted = s), a.fuzzy && !a.obsolete && (o.flag = "fuzzy"), (o.reference || o.extracted || o.flag) && (
|
|
141
|
-
let
|
|
142
|
-
|
|
142
|
+
let s = re(i, a.message ?? i, a.context, a.comment);
|
|
143
|
+
if (s && (o.extracted = s), a.fuzzy && !a.obsolete && (o.flag = "fuzzy"), (o.reference || o.extracted || o.flag) && (e.comments = o), a.obsolete) {
|
|
144
|
+
let t = a.context ?? "";
|
|
145
|
+
r[t] ??= {}, r[t][e.msgid] = e;
|
|
143
146
|
} else {
|
|
144
|
-
let
|
|
145
|
-
|
|
147
|
+
let n = a.context ?? "";
|
|
148
|
+
t[n] ??= {}, t[n][e.msgid] = e;
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
let a = {
|
|
149
152
|
headers: { "Content-Type": "text/plain; charset=UTF-8" },
|
|
150
|
-
translations:
|
|
151
|
-
...Object.keys(
|
|
153
|
+
translations: t,
|
|
154
|
+
...Object.keys(r).length > 0 ? { obsolete: r } : {}
|
|
152
155
|
};
|
|
153
|
-
return
|
|
156
|
+
return i.po.compile(a).toString();
|
|
154
157
|
}
|
|
155
|
-
function
|
|
158
|
+
function j(e) {
|
|
156
159
|
if (!e) return {};
|
|
157
160
|
let t = e.split("\n").map((e) => e.trim()).filter(Boolean), n, r, i = [];
|
|
158
161
|
for (let e of t) {
|
|
159
|
-
if (e.startsWith(
|
|
162
|
+
if (e.startsWith(D)) {
|
|
160
163
|
n = e.slice(11).trim() || void 0;
|
|
161
164
|
continue;
|
|
162
165
|
}
|
|
@@ -165,7 +168,7 @@ function E(e) {
|
|
|
165
168
|
continue;
|
|
166
169
|
}
|
|
167
170
|
if (e.startsWith("Trans: ")) {
|
|
168
|
-
r =
|
|
171
|
+
r = ne(e.slice(7));
|
|
169
172
|
continue;
|
|
170
173
|
}
|
|
171
174
|
i.push(e);
|
|
@@ -176,7 +179,7 @@ function E(e) {
|
|
|
176
179
|
...r ? { sourceMessage: r } : {}
|
|
177
180
|
};
|
|
178
181
|
}
|
|
179
|
-
function
|
|
182
|
+
function ne(e) {
|
|
180
183
|
let t = [], n = 0;
|
|
181
184
|
return e.replace(/<\/?([a-zA-Z][\w-]*)>/g, (e, r) => {
|
|
182
185
|
let i = r;
|
|
@@ -194,17 +197,17 @@ function D(e) {
|
|
|
194
197
|
}), `<${a}>`;
|
|
195
198
|
});
|
|
196
199
|
}
|
|
197
|
-
function
|
|
200
|
+
function re(e, t, r, i) {
|
|
198
201
|
let a = [];
|
|
199
|
-
return i && a.push(i),
|
|
202
|
+
return i && a.push(i), e !== n(t, r) && (a.push(`${D} ${e}`), a.push(`msg\`${t}\``)), a.length > 0 ? a.join("\n") : void 0;
|
|
200
203
|
}
|
|
201
204
|
//#endregion
|
|
202
205
|
//#region src/parallel-compile.ts
|
|
203
|
-
var
|
|
204
|
-
function
|
|
205
|
-
return
|
|
206
|
+
var M = 3e4;
|
|
207
|
+
function N() {
|
|
208
|
+
return h(typeof __dirname < "u" ? __dirname : p(v(import.meta.url)), "compile-worker.js");
|
|
206
209
|
}
|
|
207
|
-
async function
|
|
210
|
+
async function P(e, t) {
|
|
208
211
|
if (e.length === 0) return [];
|
|
209
212
|
if (e.length === 1) {
|
|
210
213
|
let { compileCatalog: t } = await import("./compile-CZVpE5Md.js").then((e) => e.a), n = e[0], { code: r, stats: i } = t(n.catalog, n.locale, n.allIds, n.sourceLocale, n.options);
|
|
@@ -214,53 +217,53 @@ async function j(e, t) {
|
|
|
214
217
|
stats: i
|
|
215
218
|
}];
|
|
216
219
|
}
|
|
217
|
-
let n =
|
|
218
|
-
if (!
|
|
219
|
-
let r = t ?? Math.min(e.length,
|
|
220
|
+
let n = N();
|
|
221
|
+
if (!s(n)) return ie(e);
|
|
222
|
+
let r = t ?? Math.min(e.length, _()), i = [], a = [...e], o = !1;
|
|
220
223
|
return new Promise((e, t) => {
|
|
221
|
-
let
|
|
224
|
+
let s = 0;
|
|
222
225
|
function c() {
|
|
223
|
-
if (
|
|
224
|
-
let r =
|
|
226
|
+
if (o) return;
|
|
227
|
+
let r = a.shift();
|
|
225
228
|
if (!r) {
|
|
226
|
-
|
|
229
|
+
s === 0 && e(i);
|
|
227
230
|
return;
|
|
228
231
|
}
|
|
229
|
-
|
|
230
|
-
let l = new
|
|
231
|
-
|
|
232
|
-
},
|
|
232
|
+
s++;
|
|
233
|
+
let l = new g(n), u = setTimeout(() => {
|
|
234
|
+
o || (o = !0, s--, l.terminate(), t(/* @__PURE__ */ Error(`Worker timed out after ${M}ms compiling locale "${r.locale}"`)));
|
|
235
|
+
}, M);
|
|
233
236
|
l.on("message", (e) => {
|
|
234
|
-
if (clearTimeout(u), !
|
|
237
|
+
if (clearTimeout(u), !o) {
|
|
235
238
|
if (e.error) {
|
|
236
|
-
|
|
239
|
+
o = !0, s--, l.terminate(), t(/* @__PURE__ */ Error(`Failed to compile locale "${e.locale}": ${e.error}`));
|
|
237
240
|
return;
|
|
238
241
|
}
|
|
239
|
-
|
|
242
|
+
i.push({
|
|
240
243
|
locale: e.locale,
|
|
241
244
|
code: e.code,
|
|
242
245
|
stats: e.stats
|
|
243
|
-
}),
|
|
246
|
+
}), s--, l.terminate(), c();
|
|
244
247
|
}
|
|
245
248
|
}), l.on("error", (e) => {
|
|
246
|
-
clearTimeout(u),
|
|
249
|
+
clearTimeout(u), o || (o = !0, l.terminate(), t(/* @__PURE__ */ Error(`Worker error compiling locale "${r.locale}": ${e.message}`)));
|
|
247
250
|
}), l.on("exit", (e) => {
|
|
248
|
-
clearTimeout(u), e !== 0 && !
|
|
251
|
+
clearTimeout(u), e !== 0 && !o && (o = !0, t(/* @__PURE__ */ Error(`Worker exited with code ${e} while compiling locale "${r.locale}"`)));
|
|
249
252
|
});
|
|
250
|
-
let
|
|
253
|
+
let d = {
|
|
251
254
|
locale: r.locale,
|
|
252
255
|
catalog: r.catalog,
|
|
253
256
|
allIds: r.allIds,
|
|
254
257
|
sourceLocale: r.sourceLocale,
|
|
255
258
|
options: r.options
|
|
256
259
|
};
|
|
257
|
-
l.postMessage(
|
|
260
|
+
l.postMessage(d);
|
|
258
261
|
}
|
|
259
|
-
let l = Math.min(r,
|
|
262
|
+
let l = Math.min(r, a.length);
|
|
260
263
|
for (let e = 0; e < l; e++) c();
|
|
261
264
|
});
|
|
262
265
|
}
|
|
263
|
-
async function
|
|
266
|
+
async function ie(e) {
|
|
264
267
|
let { compileCatalog: t } = await import("./compile-CZVpE5Md.js").then((e) => e.a);
|
|
265
268
|
return Promise.all(e.map((e) => {
|
|
266
269
|
let { code: n, stats: r } = t(e.catalog, e.locale, e.allIds, e.sourceLocale, e.options);
|
|
@@ -273,23 +276,23 @@ async function te(e) {
|
|
|
273
276
|
}
|
|
274
277
|
//#endregion
|
|
275
278
|
//#region src/extract-cache.ts
|
|
276
|
-
var
|
|
279
|
+
var F = "1", ae = class {
|
|
277
280
|
data;
|
|
278
281
|
cachePath;
|
|
279
282
|
dirty = !1;
|
|
280
283
|
constructor(e, t) {
|
|
281
|
-
this.cachePath =
|
|
284
|
+
this.cachePath = h(t ? h(e, ".cache", t) : h(e, ".cache"), "extract-cache.json"), this.data = this.load();
|
|
282
285
|
}
|
|
283
286
|
get(e) {
|
|
284
287
|
let t = this.data.entries[e];
|
|
285
288
|
if (t) try {
|
|
286
|
-
let n =
|
|
289
|
+
let n = u(e);
|
|
287
290
|
if (n.mtimeMs === t.mtime && n.size === t.size) return t.messages;
|
|
288
291
|
} catch {}
|
|
289
292
|
}
|
|
290
293
|
set(e, t) {
|
|
291
294
|
try {
|
|
292
|
-
let n =
|
|
295
|
+
let n = u(e);
|
|
293
296
|
this.data.entries[e] = {
|
|
294
297
|
mtime: n.mtimeMs,
|
|
295
298
|
size: n.size,
|
|
@@ -302,7 +305,7 @@ var M = "1", N = class {
|
|
|
302
305
|
}
|
|
303
306
|
save() {
|
|
304
307
|
if (this.dirty) try {
|
|
305
|
-
|
|
308
|
+
c(p(this.cachePath), { recursive: !0 }), d(this.cachePath, JSON.stringify(this.data), "utf-8"), this.dirty = !1;
|
|
306
309
|
} catch {}
|
|
307
310
|
}
|
|
308
311
|
get size() {
|
|
@@ -310,30 +313,134 @@ var M = "1", N = class {
|
|
|
310
313
|
}
|
|
311
314
|
load() {
|
|
312
315
|
try {
|
|
313
|
-
if (
|
|
314
|
-
let e =
|
|
315
|
-
if (t.version ===
|
|
316
|
+
if (s(this.cachePath)) {
|
|
317
|
+
let e = l(this.cachePath, "utf-8"), t = JSON.parse(e);
|
|
318
|
+
if (t.version === F) return t;
|
|
316
319
|
}
|
|
317
320
|
} catch {}
|
|
318
321
|
return {
|
|
319
|
-
version:
|
|
322
|
+
version: F,
|
|
320
323
|
entries: {}
|
|
321
324
|
};
|
|
322
325
|
}
|
|
323
|
-
}
|
|
326
|
+
};
|
|
327
|
+
//#endregion
|
|
328
|
+
//#region src/extract-path.ts
|
|
329
|
+
function I(e) {
|
|
330
|
+
return e.split("\\").join("/");
|
|
331
|
+
}
|
|
332
|
+
function oe(e, t, n = f) {
|
|
333
|
+
let r = n.isAbsolute(t) ? n.normalize(t) : n.resolve(e, t), i = n.relative(e, r);
|
|
334
|
+
if (n.isAbsolute(i)) throw Error(`Cannot extract "${r}" relative to "${e}". The include glob resolved to a file on a different drive, so Fluenti cannot keep PO references relative on this platform.`);
|
|
335
|
+
return {
|
|
336
|
+
absoluteFile: r,
|
|
337
|
+
displayFile: I(i)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function L(e, t) {
|
|
341
|
+
let n = I(t), r = !1, i = e.map((e) => I(e.origin.file) === n ? e : (r = !0, {
|
|
342
|
+
...e,
|
|
343
|
+
origin: {
|
|
344
|
+
...e.origin,
|
|
345
|
+
file: n
|
|
346
|
+
}
|
|
347
|
+
}));
|
|
348
|
+
return {
|
|
349
|
+
messages: r ? i : [...e],
|
|
350
|
+
changed: r
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region src/extract-workflow.ts
|
|
355
|
+
function R(e) {
|
|
356
|
+
return b("md5").update(e).digest("hex").slice(0, 8);
|
|
357
|
+
}
|
|
358
|
+
function z(e, t) {
|
|
359
|
+
if (!s(e)) return {};
|
|
360
|
+
let n = l(e, "utf-8");
|
|
361
|
+
return t === "json" ? T(n) : k(n);
|
|
362
|
+
}
|
|
363
|
+
function B(e, t, n) {
|
|
364
|
+
let r = n === "json" ? E(t) : A(t);
|
|
365
|
+
try {
|
|
366
|
+
c(p(e), { recursive: !0 }), d(e, r, "utf-8");
|
|
367
|
+
} catch (t) {
|
|
368
|
+
let n = t instanceof Error ? t.message : String(t);
|
|
369
|
+
throw Error(`Failed to write catalog "${e}": ${n}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async function V(t, n, r) {
|
|
373
|
+
if (m(t) === ".vue") try {
|
|
374
|
+
let { extractFromVue: e } = await import("./vue-extractor.js");
|
|
375
|
+
return e(n, t, r);
|
|
376
|
+
} catch {
|
|
377
|
+
return [];
|
|
378
|
+
}
|
|
379
|
+
return e(n, t, r);
|
|
380
|
+
}
|
|
381
|
+
async function H(e, n, i) {
|
|
382
|
+
let a = r(n.locales), o = await y(n.include, {
|
|
383
|
+
cwd: e,
|
|
384
|
+
ignore: n.exclude ?? [],
|
|
385
|
+
absolute: !1
|
|
386
|
+
}), s = [], c = i?.useCache === !1 ? null : new ae(h(e, n.catalogDir), R(e)), u = 0, d = /* @__PURE__ */ new Set();
|
|
387
|
+
for (let t of o) {
|
|
388
|
+
let { absoluteFile: r, displayFile: i } = oe(e, t);
|
|
389
|
+
if (d.add(r), c) {
|
|
390
|
+
let e = c.get(r);
|
|
391
|
+
if (e) {
|
|
392
|
+
let t = L(e, i);
|
|
393
|
+
s.push(...t.messages), t.changed && c.set(r, t.messages), u++;
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
let a = L(await V(i, l(r, "utf-8"), n.idGenerator), i).messages;
|
|
398
|
+
s.push(...a), c && c.set(r, a);
|
|
399
|
+
}
|
|
400
|
+
c && (c.prune(d), c.save());
|
|
401
|
+
let f = n.plugins?.length ? t(n.plugins) : void 0;
|
|
402
|
+
if (f) {
|
|
403
|
+
let e = /* @__PURE__ */ new Map();
|
|
404
|
+
for (let t of s) e.set(t.id, t);
|
|
405
|
+
let t = {
|
|
406
|
+
messages: e,
|
|
407
|
+
sourceLocale: n.sourceLocale,
|
|
408
|
+
targetLocales: a.filter((e) => e !== n.sourceLocale),
|
|
409
|
+
config: n
|
|
410
|
+
};
|
|
411
|
+
await f.runAfterExtract(t);
|
|
412
|
+
}
|
|
413
|
+
let p = n.format === "json" ? ".json" : ".po", m = i?.clean ?? !1, g = i?.stripFuzzy ?? !1, _ = [];
|
|
414
|
+
for (let t of a) {
|
|
415
|
+
let r = h(e, n.catalogDir, `${t}${p}`), { catalog: i, result: a } = S(z(r, n.format), s, { stripFuzzy: g });
|
|
416
|
+
B(r, m ? Object.fromEntries(Object.entries(i).filter(([, e]) => !e.obsolete)) : i, n.format), _.push({
|
|
417
|
+
locale: t,
|
|
418
|
+
result: a
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
fileCount: o.length,
|
|
423
|
+
messageCount: s.length,
|
|
424
|
+
cacheHits: u,
|
|
425
|
+
localeResults: _
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region src/codemod.ts
|
|
430
|
+
var U = new Set([
|
|
324
431
|
"Trans",
|
|
325
432
|
"Plural",
|
|
326
433
|
"Select",
|
|
327
434
|
"DateTime",
|
|
328
435
|
"NumberFormat"
|
|
329
|
-
]),
|
|
436
|
+
]), W = [
|
|
330
437
|
"src/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
331
438
|
"app/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
332
439
|
"pages/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
333
440
|
"components/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
334
441
|
"layouts/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}"
|
|
335
442
|
];
|
|
336
|
-
function
|
|
443
|
+
function G(e) {
|
|
337
444
|
let t = e.trim(), n = t.startsWith("type "), r = (n ? t.slice(5).trim() : t).split(/\s+as\s+/);
|
|
338
445
|
return {
|
|
339
446
|
imported: r[0].trim(),
|
|
@@ -341,11 +448,11 @@ function I(e) {
|
|
|
341
448
|
isType: n
|
|
342
449
|
};
|
|
343
450
|
}
|
|
344
|
-
function
|
|
451
|
+
function K(e) {
|
|
345
452
|
let t = e.isType ? "type " : "";
|
|
346
453
|
return e.imported === e.local ? `${t}${e.imported}` : `${t}${e.imported} as ${e.local}`;
|
|
347
454
|
}
|
|
348
|
-
function
|
|
455
|
+
function q(e) {
|
|
349
456
|
let t = /* @__PURE__ */ new Set(), n = [];
|
|
350
457
|
for (let r of e) {
|
|
351
458
|
let e = `${r.isType ? "type:" : "value:"}${r.imported}:${r.local}`;
|
|
@@ -353,16 +460,16 @@ function R(e) {
|
|
|
353
460
|
}
|
|
354
461
|
return n;
|
|
355
462
|
}
|
|
356
|
-
function
|
|
463
|
+
function se(e, t) {
|
|
357
464
|
let n = RegExp(`import\\s*\\{([\\s\\S]*?)\\}\\s*from\\s*['"]${t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"];?\\n?`, "g"), r = [...e.matchAll(n)];
|
|
358
465
|
if (r.length <= 1) return e;
|
|
359
|
-
let i = `import { ${
|
|
466
|
+
let i = `import { ${q(r.flatMap((e) => e[1].split(",").map((e) => G(e)).filter((e) => e.imported.length > 0))).map(K).join(", ")} } from '${t}'\n`, a = !0;
|
|
360
467
|
return e.replace(n, () => a ? (a = !1, i) : "");
|
|
361
468
|
}
|
|
362
|
-
function
|
|
469
|
+
function J(e) {
|
|
363
470
|
let t = e, n = !1, r = !1;
|
|
364
471
|
if (t = t.replace(/import\s*\{([\s\S]*?)\}\s*from\s*['"](@fluenti\/(react|vue|solid)(?:\/components)?)['"];?/g, (e, t, i, a) => {
|
|
365
|
-
let o = t.split(",").map((e) => e.trim()).filter(Boolean).map(
|
|
472
|
+
let o = t.split(",").map((e) => e.trim()).filter(Boolean).map(G), s = [], c = [], l = [];
|
|
366
473
|
for (let e of o) {
|
|
367
474
|
let t = { ...e };
|
|
368
475
|
if (a === "solid" && t.imported === "createFluentiContext" && (t.imported = "createFluenti", t.local === "createFluentiContext" && (t.local = "createFluenti", r = !0)), t.imported === "interpolate") {
|
|
@@ -372,14 +479,14 @@ function B(e) {
|
|
|
372
479
|
});
|
|
373
480
|
continue;
|
|
374
481
|
}
|
|
375
|
-
if (!t.isType &&
|
|
482
|
+
if (!t.isType && U.has(t.imported) && i.endsWith("/components")) {
|
|
376
483
|
c.push(t);
|
|
377
484
|
continue;
|
|
378
485
|
}
|
|
379
486
|
s.push(t);
|
|
380
487
|
}
|
|
381
488
|
let u = [];
|
|
382
|
-
s.length > 0 && !i.endsWith("/components") && u.push(`import { ${
|
|
489
|
+
s.length > 0 && !i.endsWith("/components") && u.push(`import { ${q(s).map(K).join(", ")} } from '@fluenti/${a}'`), c.length > 0 && u.push(`import { ${q(c).map(K).join(", ")} } from '@fluenti/${a}/components'`), l.length > 0 && u.push(`import { ${q(l).map(K).join(", ")} } from '@fluenti/core/runtime'`), s.length > 0 && i.endsWith("/components") && u.unshift(`import { ${q(s).map(K).join(", ")} } from '@fluenti/${a}'`);
|
|
383
490
|
let d = u.join("\n");
|
|
384
491
|
return d !== e && (n = !0), d;
|
|
385
492
|
}), r) {
|
|
@@ -395,7 +502,7 @@ function B(e) {
|
|
|
395
502
|
"@fluenti/solid/components",
|
|
396
503
|
"@fluenti/core/runtime"
|
|
397
504
|
]) {
|
|
398
|
-
let r =
|
|
505
|
+
let r = se(t, e);
|
|
399
506
|
r !== t && (t = r, n = !0);
|
|
400
507
|
}
|
|
401
508
|
return {
|
|
@@ -403,8 +510,8 @@ function B(e) {
|
|
|
403
510
|
changed: n
|
|
404
511
|
};
|
|
405
512
|
}
|
|
406
|
-
async function
|
|
407
|
-
let t = await
|
|
513
|
+
async function ce(e) {
|
|
514
|
+
let t = await y(e.include && e.include.length > 0 ? e.include : W, {
|
|
408
515
|
cwd: e.cwd,
|
|
409
516
|
absolute: !1,
|
|
410
517
|
ignore: [
|
|
@@ -414,8 +521,8 @@ async function V(e) {
|
|
|
414
521
|
]
|
|
415
522
|
}), n = [];
|
|
416
523
|
for (let r of t) {
|
|
417
|
-
let t =
|
|
418
|
-
i.changed && (e.write &&
|
|
524
|
+
let t = h(e.cwd, r), i = J(l(t, "utf-8"));
|
|
525
|
+
i.changed && (e.write && d(t, i.code, "utf-8"), n.push({
|
|
419
526
|
file: r,
|
|
420
527
|
changed: !0
|
|
421
528
|
}));
|
|
@@ -427,12 +534,12 @@ async function V(e) {
|
|
|
427
534
|
}
|
|
428
535
|
//#endregion
|
|
429
536
|
//#region src/init.ts
|
|
430
|
-
var
|
|
431
|
-
function
|
|
432
|
-
if (!
|
|
537
|
+
var le = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{1,8})*$/;
|
|
538
|
+
function Y(e) {
|
|
539
|
+
if (!le.test(e)) throw Error(`Invalid locale format: "${e}"`);
|
|
433
540
|
return e;
|
|
434
541
|
}
|
|
435
|
-
var
|
|
542
|
+
var ue = [
|
|
436
543
|
{
|
|
437
544
|
dep: "next",
|
|
438
545
|
name: "nextjs",
|
|
@@ -464,8 +571,8 @@ var W = [
|
|
|
464
571
|
pluginPackage: "@fluenti/react"
|
|
465
572
|
}
|
|
466
573
|
];
|
|
467
|
-
function
|
|
468
|
-
for (let t of
|
|
574
|
+
function X(e) {
|
|
575
|
+
for (let t of ue) if (t.dep in e) return {
|
|
469
576
|
name: t.name,
|
|
470
577
|
pluginPackage: t.pluginPackage
|
|
471
578
|
};
|
|
@@ -474,7 +581,7 @@ function G(e) {
|
|
|
474
581
|
pluginPackage: null
|
|
475
582
|
};
|
|
476
583
|
}
|
|
477
|
-
function
|
|
584
|
+
function de(e) {
|
|
478
585
|
let t = e.locales.map((e) => JSON.stringify(e)).join(", ");
|
|
479
586
|
return `import { defineConfig } from '@fluenti/cli'
|
|
480
587
|
|
|
@@ -488,66 +595,66 @@ export default defineConfig({
|
|
|
488
595
|
})
|
|
489
596
|
`;
|
|
490
597
|
}
|
|
491
|
-
async function
|
|
492
|
-
let t =
|
|
493
|
-
if (!
|
|
494
|
-
|
|
598
|
+
async function fe(e) {
|
|
599
|
+
let t = h(e.cwd, "package.json");
|
|
600
|
+
if (!s(t)) {
|
|
601
|
+
x.error("No package.json found in current directory.");
|
|
495
602
|
return;
|
|
496
603
|
}
|
|
497
|
-
let n = JSON.parse(
|
|
604
|
+
let n = JSON.parse(l(t, "utf-8")), r = X({
|
|
498
605
|
...n.dependencies,
|
|
499
606
|
...n.devDependencies
|
|
500
607
|
});
|
|
501
|
-
|
|
502
|
-
let
|
|
503
|
-
if (i
|
|
504
|
-
|
|
608
|
+
x.info(`Detected framework: ${r.name}`), r.pluginPackage && x.info(`Recommended plugin: ${r.pluginPackage}`);
|
|
609
|
+
let i = h(e.cwd, "fluenti.config.ts");
|
|
610
|
+
if (s(i)) {
|
|
611
|
+
x.warn("fluenti.config.ts already exists. Skipping config generation.");
|
|
505
612
|
return;
|
|
506
613
|
}
|
|
507
|
-
let
|
|
614
|
+
let a = await x.prompt("Source locale?", {
|
|
508
615
|
type: "text",
|
|
509
616
|
default: "en",
|
|
510
617
|
placeholder: "en"
|
|
511
618
|
});
|
|
512
|
-
if (typeof
|
|
513
|
-
let
|
|
619
|
+
if (typeof a == "symbol") return;
|
|
620
|
+
let c = await x.prompt("Target locales (comma-separated)?", {
|
|
514
621
|
type: "text",
|
|
515
622
|
default: "ja,zh-CN",
|
|
516
623
|
placeholder: "ja,zh-CN"
|
|
517
624
|
});
|
|
518
|
-
if (typeof
|
|
519
|
-
let
|
|
625
|
+
if (typeof c == "symbol") return;
|
|
626
|
+
let u = await x.prompt("Catalog format?", {
|
|
520
627
|
type: "select",
|
|
521
628
|
options: ["po", "json"],
|
|
522
629
|
initial: "po"
|
|
523
630
|
});
|
|
524
|
-
if (typeof
|
|
525
|
-
let
|
|
526
|
-
|
|
527
|
-
for (let e of
|
|
528
|
-
|
|
529
|
-
sourceLocale:
|
|
530
|
-
locales: [
|
|
531
|
-
format:
|
|
532
|
-
}), "utf-8"),
|
|
533
|
-
let
|
|
534
|
-
|
|
535
|
-
let
|
|
536
|
-
if (
|
|
631
|
+
if (typeof u == "symbol") return;
|
|
632
|
+
let f = c.split(",").map((e) => e.trim()).filter(Boolean);
|
|
633
|
+
Y(a);
|
|
634
|
+
for (let e of f) Y(e);
|
|
635
|
+
d(i, de({
|
|
636
|
+
sourceLocale: a,
|
|
637
|
+
locales: [a, ...f.filter((e) => e !== a)],
|
|
638
|
+
format: u
|
|
639
|
+
}), "utf-8"), x.success("Created fluenti.config.ts");
|
|
640
|
+
let p = h(e.cwd, ".gitignore"), m = "src/locales/compiled/";
|
|
641
|
+
s(p) ? l(p, "utf-8").includes(m) || (o(p, `\n# Fluenti compiled catalogs\n${m}\n`), x.success("Updated .gitignore")) : (d(p, `# Fluenti compiled catalogs\n${m}\n`), x.success("Created .gitignore"));
|
|
642
|
+
let g = n.scripts ?? {}, _ = {}, v = !1;
|
|
643
|
+
if (g["i18n:extract"] || (_["i18n:extract"] = "fluenti extract", v = !0), g["i18n:compile"] || (_["i18n:compile"] = "fluenti compile", v = !0), v) {
|
|
537
644
|
let e = {
|
|
538
645
|
...n,
|
|
539
646
|
scripts: {
|
|
540
|
-
...
|
|
541
|
-
...
|
|
647
|
+
...g,
|
|
648
|
+
..._
|
|
542
649
|
}
|
|
543
650
|
};
|
|
544
|
-
|
|
651
|
+
d(t, JSON.stringify(e, null, 2) + "\n", "utf-8"), x.success("Added i18n:extract and i18n:compile scripts to package.json");
|
|
545
652
|
}
|
|
546
|
-
|
|
653
|
+
x.log(""), x.box({
|
|
547
654
|
title: "Next steps",
|
|
548
655
|
message: [
|
|
549
|
-
|
|
550
|
-
|
|
656
|
+
r.pluginPackage ? `1. Install: pnpm add -D ${r.pluginPackage} @fluenti/cli` : "1. Install: pnpm add -D @fluenti/cli",
|
|
657
|
+
r.name === "nextjs" ? "2. Add withFluenti() to your next.config.ts" : r.name === "unknown" ? "2. Configure your build tool with the framework Vite plugin or @fluenti/next" : "2. Add the Vite plugin to your vite.config.ts (e.g. fluentiVue() from @fluenti/vue/vite-plugin)",
|
|
551
658
|
"3. Run: npx fluenti extract",
|
|
552
659
|
"4. Translate your messages",
|
|
553
660
|
"5. Run: npx fluenti compile"
|
|
@@ -556,30 +663,30 @@ async function q(e) {
|
|
|
556
663
|
}
|
|
557
664
|
//#endregion
|
|
558
665
|
//#region src/doctor.ts
|
|
559
|
-
var
|
|
666
|
+
var pe = [
|
|
560
667
|
"src/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
561
668
|
"app/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
562
669
|
"pages/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
563
670
|
"components/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}",
|
|
564
671
|
"layouts/**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,vue,mdx}"
|
|
565
|
-
],
|
|
672
|
+
], me = /import\s*\{[\s\S]*?\binterpolate\b[\s\S]*?\}\s*from\s*['"]@fluenti\/(react|vue|solid)(?:\/components)?['"]/g, he = /from\s*['"]@fluenti\/core\/internal['"]/g;
|
|
566
673
|
function Z(e) {
|
|
567
|
-
return
|
|
674
|
+
return s(e) ? l(e, "utf-8") : void 0;
|
|
568
675
|
}
|
|
569
|
-
function
|
|
570
|
-
if (t) return
|
|
676
|
+
function ge(e, t) {
|
|
677
|
+
if (t) return h(e, t);
|
|
571
678
|
for (let t of [
|
|
572
679
|
"fluenti.config.ts",
|
|
573
680
|
"fluenti.config.mts",
|
|
574
681
|
"fluenti.config.js",
|
|
575
682
|
"fluenti.config.mjs"
|
|
576
683
|
]) {
|
|
577
|
-
let n =
|
|
578
|
-
if (
|
|
684
|
+
let n = h(e, t);
|
|
685
|
+
if (s(n)) return n;
|
|
579
686
|
}
|
|
580
687
|
}
|
|
581
|
-
async function
|
|
582
|
-
return
|
|
688
|
+
async function _e(e) {
|
|
689
|
+
return y(pe, {
|
|
583
690
|
cwd: e,
|
|
584
691
|
absolute: !1,
|
|
585
692
|
ignore: [
|
|
@@ -596,19 +703,19 @@ function Q(e, t, n, r) {
|
|
|
596
703
|
message: r
|
|
597
704
|
});
|
|
598
705
|
}
|
|
599
|
-
function
|
|
600
|
-
let t = Z(
|
|
706
|
+
function ve(e) {
|
|
707
|
+
let t = Z(h(e, "package.json"));
|
|
601
708
|
if (t) return JSON.parse(t);
|
|
602
709
|
}
|
|
603
|
-
function
|
|
710
|
+
function ye(e) {
|
|
604
711
|
return e ? e.includes("@fluenti/") && e.includes("vite-plugin") : !1;
|
|
605
712
|
}
|
|
606
713
|
function $(e, t) {
|
|
607
714
|
return [...e.matchAll(t)].length;
|
|
608
715
|
}
|
|
609
|
-
async function
|
|
610
|
-
let t = [],
|
|
611
|
-
if (!
|
|
716
|
+
async function be(e) {
|
|
717
|
+
let t = [], n = ve(e.cwd);
|
|
718
|
+
if (!n) return {
|
|
612
719
|
framework: "unknown",
|
|
613
720
|
findings: [{
|
|
614
721
|
severity: "error",
|
|
@@ -616,46 +723,46 @@ async function oe(e) {
|
|
|
616
723
|
message: "No package.json found in the current directory."
|
|
617
724
|
}]
|
|
618
725
|
};
|
|
619
|
-
let
|
|
620
|
-
...
|
|
621
|
-
...
|
|
622
|
-
}),
|
|
623
|
-
for (let t of
|
|
624
|
-
let n =
|
|
625
|
-
|
|
626
|
-
}
|
|
627
|
-
if (
|
|
726
|
+
let r = X({
|
|
727
|
+
...n.dependencies,
|
|
728
|
+
...n.devDependencies
|
|
729
|
+
}), i = ge(e.cwd, e.config), o = await _e(e.cwd), c = 0, u = 0, d = !1, f = !1;
|
|
730
|
+
for (let t of o) {
|
|
731
|
+
let n = l(h(e.cwd, t), "utf-8");
|
|
732
|
+
c += $(n, me), u += $(n, he), d ||= n.includes("@fluenti/"), f ||= n.includes("from '@fluenti/") && n.includes(" t`");
|
|
733
|
+
}
|
|
734
|
+
if (c > 0 && Q(t, "warning", "main-entry-interpolate", `Found ${c} import(s) of interpolate from framework packages. Import interpolate from @fluenti/core/runtime instead.`), u > 0 && Q(t, "warning", "core-internal-imports", `Found ${u} import(s) from @fluenti/core/internal. Use @fluenti/core/runtime or @fluenti/core/compiler.`), i || Q(t, "warning", "missing-config", "No fluenti.config.* file found."), r.name === "nextjs") {
|
|
628
735
|
let n = [
|
|
629
736
|
"next.config.ts",
|
|
630
737
|
"next.config.mjs",
|
|
631
738
|
"next.config.js"
|
|
632
|
-
].map((t) =>
|
|
633
|
-
|
|
739
|
+
].map((t) => h(e.cwd, t)).find((e) => s(e)), r = n ? Z(n) : void 0;
|
|
740
|
+
d && !r?.includes("withFluenti(") && Q(t, "error", "missing-with-fluenti", "Next.js project imports Fluenti but next.config does not call withFluenti().");
|
|
634
741
|
}
|
|
635
|
-
if (
|
|
742
|
+
if (r.name === "react" || r.name === "vue" || r.name === "solid") {
|
|
636
743
|
let n = [
|
|
637
744
|
"vite.config.ts",
|
|
638
745
|
"vite.config.mts",
|
|
639
746
|
"vite.config.js",
|
|
640
747
|
"vite.config.mjs"
|
|
641
|
-
].map((t) =>
|
|
642
|
-
(
|
|
643
|
-
}
|
|
644
|
-
if (
|
|
645
|
-
let
|
|
646
|
-
|
|
647
|
-
let c =
|
|
648
|
-
|
|
748
|
+
].map((t) => h(e.cwd, t)).find((e) => s(e)), r = n ? Z(n) : void 0;
|
|
749
|
+
(d || f) && !ye(r) && Q(t, "warning", "missing-vite-plugin", "Project imports Fluenti but vite.config does not appear to include a Fluenti Vite plugin.");
|
|
750
|
+
}
|
|
751
|
+
if (i && s(i)) try {
|
|
752
|
+
let n = await a(i), r = n.format === "json" ? ".json" : ".po", o = h(e.cwd, n.catalogDir, `${n.sourceLocale}${r}`);
|
|
753
|
+
s(o) || Q(t, "warning", "missing-source-catalog", `Source catalog not found: ${o}`);
|
|
754
|
+
let c = h(e.cwd, n.compileOutDir, "index.js");
|
|
755
|
+
s(c) || Q(t, "warning", "missing-compiled-catalogs", `Compiled catalogs not found at ${c}. Run "fluenti compile".`);
|
|
649
756
|
} catch (e) {
|
|
650
757
|
Q(t, "error", "invalid-config", `Failed to load Fluenti config: ${e instanceof Error ? e.message : String(e)}`);
|
|
651
758
|
}
|
|
652
759
|
return t.length === 0 && Q(t, "info", "ok", "No Fluenti migration or configuration issues detected."), {
|
|
653
|
-
framework:
|
|
760
|
+
framework: r.name,
|
|
654
761
|
findings: t,
|
|
655
|
-
...
|
|
762
|
+
...i ? { configPath: i } : {}
|
|
656
763
|
};
|
|
657
764
|
}
|
|
658
|
-
function
|
|
765
|
+
function xe(e) {
|
|
659
766
|
let t = [`Framework: ${e.framework}`];
|
|
660
767
|
e.configPath && t.push(`Config: ${e.configPath}`), t.push("");
|
|
661
768
|
for (let n of e.findings) {
|
|
@@ -665,4 +772,4 @@ function se(e) {
|
|
|
665
772
|
return t.join("\n");
|
|
666
773
|
}
|
|
667
774
|
//#endregion
|
|
668
|
-
export {
|
|
775
|
+
export { ce as a, a as c, T as d, E as f, J as i, k as l, be as n, H as o, S as p, fe as r, P as s, xe as t, A as u };
|