@verbaly/compiler 0.18.0 → 0.20.0
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/README.md +1 -1
- package/dist/cli.js +157 -49
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.js +158 -36
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ interface TaggedMessage {
|
|
|
23
23
|
name: string;
|
|
24
24
|
components: TransComponent[];
|
|
25
25
|
};
|
|
26
|
+
singleQuote?: boolean;
|
|
26
27
|
}
|
|
27
28
|
interface UsedKey {
|
|
28
29
|
key: string;
|
|
@@ -32,7 +33,15 @@ interface Analysis {
|
|
|
32
33
|
tagged: TaggedMessage[];
|
|
33
34
|
usedKeys: UsedKey[];
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
+
interface AnalyzeOptions {
|
|
37
|
+
tNames?: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
declare function analyze(code: string, file: string, options?: AnalyzeOptions): Analysis;
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/sfc.d.ts
|
|
42
|
+
declare const SFC_FILE_RE: RegExp;
|
|
43
|
+
declare function analyzeFile(code: string, file: string): Analysis;
|
|
44
|
+
declare function analyzeSfc(code: string, file: string): Analysis;
|
|
36
45
|
//#endregion
|
|
37
46
|
//#region src/translate.d.ts
|
|
38
47
|
interface TranslateRequest {
|
|
@@ -133,7 +142,11 @@ declare function formatCheckResult(result: CheckResult): string;
|
|
|
133
142
|
//#endregion
|
|
134
143
|
//#region src/codegen.d.ts
|
|
135
144
|
declare const VIRTUAL_ID = "virtual:verbaly";
|
|
136
|
-
|
|
145
|
+
interface RuntimeModuleOptions {
|
|
146
|
+
localeImport?: (locale: string) => string;
|
|
147
|
+
extraExports?: string;
|
|
148
|
+
}
|
|
149
|
+
declare function generateRuntimeModule(cfg: ResolvedConfig, options?: RuntimeModuleOptions): string;
|
|
137
150
|
declare function generateLocaleModule(catalog: Catalog): string;
|
|
138
151
|
declare function generateDts(entries: Map<string, string>): string;
|
|
139
152
|
declare function writeDts(cfg: ResolvedConfig, entries: Map<string, string>): void;
|
|
@@ -289,5 +302,5 @@ interface TransformResult {
|
|
|
289
302
|
}
|
|
290
303
|
declare function transformCode(code: string, file: string, analysis?: Analysis): TransformResult | null;
|
|
291
304
|
//#endregion
|
|
292
|
-
export { type Alternate, type Analysis, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type ExchangeFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, LOCALE_MODULE_PREFIX, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, RESOLVED_VIRTUAL_ID, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, SOURCE_FILE_RE, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
|
|
305
|
+
export { type Alternate, type Analysis, type AnalyzeOptions, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type ExchangeFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, LOCALE_MODULE_PREFIX, MessageRegistry, type MissingEntry, PSEUDO_LOCALE, type ParamType, RESOLVED_VIRTUAL_ID, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type RuntimeModuleOptions, SFC_FILE_RE, SOURCE_FILE_RE, type SyncResult, type TaggedMessage, type TaggedParam, type TransComponent, type TransformResult, type TranslateConfig, type TranslateOptions, type TranslateProvider, type TranslateRequest, type TranslateResult, type UnknownEntry, type UsedKey, VIRTUAL_ID, type VerbalyConfig, analyze, analyzeFile, analyzeSfc, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
|
|
293
306
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,9 @@ const SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
19
19
|
"innerComments",
|
|
20
20
|
"extra"
|
|
21
21
|
]);
|
|
22
|
-
|
|
22
|
+
const DEFAULT_T_NAMES = ["t"];
|
|
23
|
+
function analyze(code, file, options = {}) {
|
|
24
|
+
const names = new Set(options.tNames ?? DEFAULT_T_NAMES);
|
|
23
25
|
const ast = parse(code, {
|
|
24
26
|
sourceType: "module",
|
|
25
27
|
errorRecovery: true,
|
|
@@ -30,10 +32,10 @@ function analyze(code, file) {
|
|
|
30
32
|
walk(ast.program, (node) => {
|
|
31
33
|
if (node.type === "TaggedTemplateExpression") {
|
|
32
34
|
const tag = node.tag;
|
|
33
|
-
const explicit = explicitId(tag);
|
|
34
|
-
if (!explicit && !isTReference(tag)) return;
|
|
35
|
+
const explicit = explicitId(tag, names);
|
|
36
|
+
if (!explicit && !isTReference(tag, names)) return;
|
|
35
37
|
const quasi = node.quasi;
|
|
36
|
-
const message = buildMessage(code, quasi);
|
|
38
|
+
const message = buildMessage(code, quasi, names);
|
|
37
39
|
if (!message) return;
|
|
38
40
|
tagged.push({
|
|
39
41
|
key: explicit ? explicit.key : stableKey(message.text),
|
|
@@ -47,20 +49,20 @@ function analyze(code, file) {
|
|
|
47
49
|
});
|
|
48
50
|
} else if (node.type === "CallExpression") {
|
|
49
51
|
const callee = node.callee;
|
|
50
|
-
if (!isTReference(callee)) return;
|
|
52
|
+
if (!isTReference(callee, names)) return;
|
|
51
53
|
const first = node.arguments[0];
|
|
52
54
|
if (first?.type === "StringLiteral") usedKeys.push({
|
|
53
55
|
key: first.value,
|
|
54
56
|
file
|
|
55
57
|
});
|
|
56
|
-
} else if (node.type === "JSXElement") handleTrans(code, node, file, tagged, usedKeys);
|
|
58
|
+
} else if (node.type === "JSXElement") handleTrans(code, node, file, tagged, usedKeys, names);
|
|
57
59
|
});
|
|
58
60
|
return {
|
|
59
61
|
tagged,
|
|
60
62
|
usedKeys
|
|
61
63
|
};
|
|
62
64
|
}
|
|
63
|
-
function handleTrans(code, node, file, tagged, usedKeys) {
|
|
65
|
+
function handleTrans(code, node, file, tagged, usedKeys, names) {
|
|
64
66
|
const opening = node.openingElement;
|
|
65
67
|
const nameNode = opening.name;
|
|
66
68
|
if (nameNode.type !== "JSXIdentifier" || nameNode.name !== "Trans") return;
|
|
@@ -72,7 +74,7 @@ function handleTrans(code, node, file, tagged, usedKeys) {
|
|
|
72
74
|
if (value?.type !== "StringLiteral") return;
|
|
73
75
|
const id = value.value;
|
|
74
76
|
if (attrs.length === 1 && children?.length) {
|
|
75
|
-
const built = buildTransMessage(code, children);
|
|
77
|
+
const built = buildTransMessage(code, children, names);
|
|
76
78
|
if (built?.text.trim()) {
|
|
77
79
|
tagged.push({
|
|
78
80
|
key: id,
|
|
@@ -99,7 +101,7 @@ function handleTrans(code, node, file, tagged, usedKeys) {
|
|
|
99
101
|
}
|
|
100
102
|
if (attrs.length > 0) return;
|
|
101
103
|
if (!children?.length) return;
|
|
102
|
-
const built = buildTransMessage(code, children);
|
|
104
|
+
const built = buildTransMessage(code, children, names);
|
|
103
105
|
if (!built || !built.text.trim()) return;
|
|
104
106
|
tagged.push({
|
|
105
107
|
key: stableKey(built.text),
|
|
@@ -116,14 +118,14 @@ function handleTrans(code, node, file, tagged, usedKeys) {
|
|
|
116
118
|
}
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
|
-
function explicitId(tag) {
|
|
121
|
+
function explicitId(tag, names) {
|
|
120
122
|
if (tag.type !== "CallExpression") return void 0;
|
|
121
123
|
const callee = tag.callee;
|
|
122
124
|
if (callee.type !== "MemberExpression" || callee.computed) return void 0;
|
|
123
125
|
const prop = callee.property;
|
|
124
126
|
if (prop.type !== "Identifier" || prop.name !== "id") return void 0;
|
|
125
127
|
const obj = callee.object;
|
|
126
|
-
if (!isTReference(obj)) return void 0;
|
|
128
|
+
if (!isTReference(obj, names)) return void 0;
|
|
127
129
|
const args = tag.arguments;
|
|
128
130
|
const first = args[0];
|
|
129
131
|
if (args.length !== 1 || first?.type !== "StringLiteral") return void 0;
|
|
@@ -133,7 +135,7 @@ function explicitId(tag) {
|
|
|
133
135
|
refEnd: obj.end
|
|
134
136
|
};
|
|
135
137
|
}
|
|
136
|
-
function buildTransMessage(code, children) {
|
|
138
|
+
function buildTransMessage(code, children, names) {
|
|
137
139
|
const params = [];
|
|
138
140
|
const components = [];
|
|
139
141
|
const takenParams = /* @__PURE__ */ new Map();
|
|
@@ -148,7 +150,7 @@ function buildTransMessage(code, children) {
|
|
|
148
150
|
text += escapeText(expr.value);
|
|
149
151
|
continue;
|
|
150
152
|
}
|
|
151
|
-
if (containsTaggedT(expr)) return void 0;
|
|
153
|
+
if (containsTaggedT(expr, names)) return void 0;
|
|
152
154
|
const source = code.slice(expr.start, expr.end);
|
|
153
155
|
const name = uniqueName(deriveName(expr, params.length), source, takenParams);
|
|
154
156
|
params.push({
|
|
@@ -201,24 +203,24 @@ function selfClosedSource(code, opening) {
|
|
|
201
203
|
const src = code.slice(opening.start, opening.end);
|
|
202
204
|
return src.endsWith("/>") ? src : `${src.slice(0, -1).trimEnd()} />`;
|
|
203
205
|
}
|
|
204
|
-
function containsTaggedT(node) {
|
|
206
|
+
function containsTaggedT(node, names) {
|
|
205
207
|
let found = false;
|
|
206
208
|
walk(node, (n) => {
|
|
207
209
|
if (n.type !== "TaggedTemplateExpression") return;
|
|
208
210
|
const tag = n.tag;
|
|
209
|
-
if (isTReference(tag) || explicitId(tag)) found = true;
|
|
211
|
+
if (isTReference(tag, names) || explicitId(tag, names)) found = true;
|
|
210
212
|
});
|
|
211
213
|
return found;
|
|
212
214
|
}
|
|
213
|
-
function isTReference(node) {
|
|
214
|
-
if (node.type === "Identifier") return node.name
|
|
215
|
+
function isTReference(node, names) {
|
|
216
|
+
if (node.type === "Identifier") return names.has(node.name);
|
|
215
217
|
if (node.type === "MemberExpression" && !node.computed) {
|
|
216
218
|
const prop = node.property;
|
|
217
|
-
return prop.type === "Identifier" && prop.name
|
|
219
|
+
return prop.type === "Identifier" && names.has(prop.name);
|
|
218
220
|
}
|
|
219
221
|
return false;
|
|
220
222
|
}
|
|
221
|
-
function buildMessage(code, quasi) {
|
|
223
|
+
function buildMessage(code, quasi, names) {
|
|
222
224
|
const quasis = quasi.quasis;
|
|
223
225
|
const expressions = quasi.expressions;
|
|
224
226
|
const params = [];
|
|
@@ -227,7 +229,7 @@ function buildMessage(code, quasi) {
|
|
|
227
229
|
for (let i = 0; i < expressions.length; i++) {
|
|
228
230
|
const expr = expressions[i];
|
|
229
231
|
if (!expr) return void 0;
|
|
230
|
-
if (containsTaggedT(expr)) return void 0;
|
|
232
|
+
if (containsTaggedT(expr, names)) return void 0;
|
|
231
233
|
const source = code.slice(expr.start, expr.end);
|
|
232
234
|
const name = uniqueName(deriveName(expr, i), source, taken);
|
|
233
235
|
params.push({
|
|
@@ -281,6 +283,111 @@ function isNode(value) {
|
|
|
281
283
|
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
282
284
|
}
|
|
283
285
|
//#endregion
|
|
286
|
+
//#region src/sfc.ts
|
|
287
|
+
const SFC_FILE_RE = /\.(?:svelte|vue)$/;
|
|
288
|
+
function analyzeFile(code, file) {
|
|
289
|
+
return SFC_FILE_RE.test(file) ? analyzeSfc(code, file) : analyze(code, file);
|
|
290
|
+
}
|
|
291
|
+
const SCRIPT_RE = /(<script\b[^>]*>)([\s\S]*?)(<\/script\s*>)/gi;
|
|
292
|
+
const STYLE_RE = /<style\b[^>]*>[\s\S]*?<\/style\s*>/gi;
|
|
293
|
+
const COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
294
|
+
const CANDIDATE_SVELTE = /(?<![\w$])\$?t(?=[`(]|\.id\()/g;
|
|
295
|
+
const CANDIDATE_VUE = /(?<![\w$])t(?=[`(]|\.id\()/g;
|
|
296
|
+
function analyzeSfc(code, file) {
|
|
297
|
+
const svelte = file.endsWith(".svelte");
|
|
298
|
+
const options = svelte ? { tNames: ["t", "$t"] } : void 0;
|
|
299
|
+
const tagged = [];
|
|
300
|
+
const usedKeys = [];
|
|
301
|
+
for (const match of code.matchAll(SCRIPT_RE)) {
|
|
302
|
+
const content = match[2];
|
|
303
|
+
if (!content) continue;
|
|
304
|
+
merge(analyzeSegment(content, file, options), match.index + match[1].length, false);
|
|
305
|
+
}
|
|
306
|
+
const markup = blank(blank(blank(code, SCRIPT_RE), STYLE_RE), COMMENT_RE);
|
|
307
|
+
const candidates = svelte ? CANDIDATE_SVELTE : CANDIDATE_VUE;
|
|
308
|
+
let consumedTo = 0;
|
|
309
|
+
for (const match of markup.matchAll(candidates)) {
|
|
310
|
+
const start = match.index;
|
|
311
|
+
if (start < consumedTo) continue;
|
|
312
|
+
const end = expressionExtent(markup, start);
|
|
313
|
+
if (end === void 0) continue;
|
|
314
|
+
merge(analyzeSegment(code.slice(start, end), file, options), start, true);
|
|
315
|
+
consumedTo = end;
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
tagged,
|
|
319
|
+
usedKeys
|
|
320
|
+
};
|
|
321
|
+
function merge(analysis, offset, markupSegment) {
|
|
322
|
+
if (!analysis) return;
|
|
323
|
+
for (const msg of analysis.tagged) tagged.push({
|
|
324
|
+
...msg,
|
|
325
|
+
start: msg.start + offset,
|
|
326
|
+
end: msg.end + offset,
|
|
327
|
+
tagStart: msg.tagStart + offset,
|
|
328
|
+
tagEnd: msg.tagEnd + offset,
|
|
329
|
+
params: msg.params.map((p) => ({
|
|
330
|
+
...p,
|
|
331
|
+
start: p.start + offset,
|
|
332
|
+
end: p.end + offset
|
|
333
|
+
})),
|
|
334
|
+
...markupSegment && { singleQuote: true }
|
|
335
|
+
});
|
|
336
|
+
usedKeys.push(...analysis.usedKeys);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function analyzeSegment(code, file, options) {
|
|
340
|
+
try {
|
|
341
|
+
return analyze(code, file, options);
|
|
342
|
+
} catch {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function blank(source, re) {
|
|
347
|
+
return source.replace(re, (m) => " ".repeat(m.length));
|
|
348
|
+
}
|
|
349
|
+
function expressionExtent(code, start) {
|
|
350
|
+
let i = start;
|
|
351
|
+
if (code[i] === "$") i += 1;
|
|
352
|
+
i += 1;
|
|
353
|
+
if (code.startsWith(".id(", i)) {
|
|
354
|
+
const close = balancedEnd(code, i + 3);
|
|
355
|
+
if (close === void 0 || code[close] !== "`") return void 0;
|
|
356
|
+
return balancedEnd(code, close);
|
|
357
|
+
}
|
|
358
|
+
if (code[i] === "`" || code[i] === "(") return balancedEnd(code, i);
|
|
359
|
+
}
|
|
360
|
+
function balancedEnd(code, open) {
|
|
361
|
+
const stack = [];
|
|
362
|
+
let i = open;
|
|
363
|
+
while (i < code.length) {
|
|
364
|
+
const ch = code[i];
|
|
365
|
+
if (stack[stack.length - 1] === "`") {
|
|
366
|
+
if (ch === "\\") i += 1;
|
|
367
|
+
else if (ch === "`") stack.pop();
|
|
368
|
+
else if (ch === "$" && code[i + 1] === "{") {
|
|
369
|
+
stack.push("{");
|
|
370
|
+
i += 1;
|
|
371
|
+
}
|
|
372
|
+
} else if (ch === "'" || ch === "\"") i = stringEnd(code, i);
|
|
373
|
+
else if (ch === "`" || ch === "(" || ch === "{") stack.push(ch);
|
|
374
|
+
else if (ch === ")" || ch === "}") {
|
|
375
|
+
if (stack[stack.length - 1] !== (ch === ")" ? "(" : "{")) return void 0;
|
|
376
|
+
stack.pop();
|
|
377
|
+
}
|
|
378
|
+
i += 1;
|
|
379
|
+
if (stack.length === 0) return i;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function stringEnd(code, start) {
|
|
383
|
+
const quote = code[start];
|
|
384
|
+
let i = start + 1;
|
|
385
|
+
while (i < code.length) if (code[i] === "\\") i += 2;
|
|
386
|
+
else if (code[i] === quote) return i;
|
|
387
|
+
else i += 1;
|
|
388
|
+
return code.length;
|
|
389
|
+
}
|
|
390
|
+
//#endregion
|
|
284
391
|
//#region src/catalog.ts
|
|
285
392
|
function catalogPath(cfg, locale) {
|
|
286
393
|
return join(cfg.dir, `${locale}.json`);
|
|
@@ -409,25 +516,35 @@ function renderParamType(types) {
|
|
|
409
516
|
//#endregion
|
|
410
517
|
//#region src/codegen.ts
|
|
411
518
|
const VIRTUAL_ID = "virtual:verbaly";
|
|
412
|
-
function generateRuntimeModule(cfg) {
|
|
519
|
+
function generateRuntimeModule(cfg, options = {}) {
|
|
520
|
+
const importPath = options.localeImport ?? ((locale) => `virtual:verbaly/locale/${locale}`);
|
|
413
521
|
const others = cfg.locales.filter((locale) => locale !== cfg.sourceLocale);
|
|
414
522
|
const src = JSON.stringify(cfg.sourceLocale);
|
|
415
|
-
const loaders = others.map((locale) => `
|
|
523
|
+
const loaders = others.map((locale) => ` ${JSON.stringify(locale)}: () => import('${importPath(locale)}'),`).join("\n");
|
|
416
524
|
return `import { createVerbaly } from 'verbaly';
|
|
417
|
-
import source from '${
|
|
525
|
+
import source from '${importPath(cfg.sourceLocale)}';
|
|
418
526
|
|
|
419
527
|
export const sourceLocale = ${src};
|
|
420
528
|
export const locales = ${JSON.stringify(cfg.locales)};
|
|
421
529
|
|
|
422
|
-
|
|
530
|
+
const localeLoaders = {
|
|
531
|
+
${loaders}
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// raw catalog access: SSR integrations serialize it across the client boundary
|
|
535
|
+
export async function loadMessages(locale) {
|
|
536
|
+
if (locale === ${src}) return source;
|
|
537
|
+
const loader = localeLoaders[locale];
|
|
538
|
+
return loader ? (await loader()).default : {};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// per-request/per-instance factory (SSR): the singleton below is browser/SPA-only
|
|
423
542
|
export function createInstance(options) {
|
|
424
543
|
return createVerbaly({
|
|
425
544
|
locale: ${src},
|
|
426
545
|
fallback: ${src},
|
|
427
546
|
messages: { [${src}]: source },
|
|
428
|
-
loaders:
|
|
429
|
-
${loaders}
|
|
430
|
-
},
|
|
547
|
+
loaders: localeLoaders,
|
|
431
548
|
...options,
|
|
432
549
|
});
|
|
433
550
|
}
|
|
@@ -456,7 +573,7 @@ export async function setLocale(locale) {
|
|
|
456
573
|
await v.loadLocale(locale);
|
|
457
574
|
v.setLocale(locale);
|
|
458
575
|
}
|
|
459
|
-
`;
|
|
576
|
+
${options.extraExports ?? ""}`;
|
|
460
577
|
}
|
|
461
578
|
function generateLocaleModule(catalog) {
|
|
462
579
|
return `export default ${JSON.stringify(catalog)};\n`;
|
|
@@ -471,7 +588,7 @@ function generateDts(entries) {
|
|
|
471
588
|
lines.push(` ${JSON.stringify(key)}: { ${fields} };`);
|
|
472
589
|
}
|
|
473
590
|
}
|
|
474
|
-
return `// generated by verbaly
|
|
591
|
+
return `// generated by verbaly: do not edit
|
|
475
592
|
declare module 'virtual:verbaly' {
|
|
476
593
|
export interface VerbalyMessages {
|
|
477
594
|
${lines.join("\n")}
|
|
@@ -482,6 +599,7 @@ ${lines.join("\n")}
|
|
|
482
599
|
|
|
483
600
|
export const sourceLocale: string;
|
|
484
601
|
export const locales: string[];
|
|
602
|
+
export function loadMessages(locale: string): Promise<Record<string, string>>;
|
|
485
603
|
export function createInstance(
|
|
486
604
|
options?: import('verbaly').VerbalyOptions<VerbalyKey>,
|
|
487
605
|
): import('verbaly').Verbaly<VerbalyKey>;
|
|
@@ -648,7 +766,7 @@ function resolveConfig(config = {}) {
|
|
|
648
766
|
dir,
|
|
649
767
|
sourceLocale,
|
|
650
768
|
locales: [...locales],
|
|
651
|
-
include: config.include ?? ["src/**/*.{js,jsx,ts,tsx,mjs,mts}"],
|
|
769
|
+
include: config.include ?? ["{src,app}/**/*.{js,jsx,ts,tsx,mjs,mts,svelte,vue}"],
|
|
652
770
|
exclude: config.exclude ?? ["**/node_modules/**", "**/dist/**"],
|
|
653
771
|
translate: config.translate ?? {},
|
|
654
772
|
render: config.render ?? {}
|
|
@@ -707,7 +825,7 @@ function definedOnly(config) {
|
|
|
707
825
|
//#region src/plugin.ts
|
|
708
826
|
const RESOLVED_VIRTUAL_ID = "\0virtual:verbaly";
|
|
709
827
|
const LOCALE_MODULE_PREFIX = `${RESOLVED_VIRTUAL_ID}/locale/`;
|
|
710
|
-
const SOURCE_FILE_RE = /\.[cm]?[jt]sx
|
|
828
|
+
const SOURCE_FILE_RE = /\.(?:[cm]?[jt]sx?|svelte|vue)$/;
|
|
711
829
|
function resolveVirtualId(id) {
|
|
712
830
|
if (id === "virtual:verbaly" || id.startsWith(`virtual:verbaly/`)) return "\0" + id;
|
|
713
831
|
}
|
|
@@ -763,7 +881,7 @@ async function extractProject(cfg) {
|
|
|
763
881
|
absolute: true
|
|
764
882
|
});
|
|
765
883
|
const registry = new MessageRegistry();
|
|
766
|
-
for (const file of files) registry.update(file,
|
|
884
|
+
for (const file of files) registry.update(file, analyzeFile(readFileSync(file, "utf8"), file));
|
|
767
885
|
return registry;
|
|
768
886
|
}
|
|
769
887
|
function syncCatalogs(cfg, catalogs, registry) {
|
|
@@ -1529,14 +1647,18 @@ function decodeEntities(text) {
|
|
|
1529
1647
|
}
|
|
1530
1648
|
//#endregion
|
|
1531
1649
|
//#region src/transform.ts
|
|
1650
|
+
function quote(text, single) {
|
|
1651
|
+
if (!single) return JSON.stringify(text);
|
|
1652
|
+
return `'${text.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
1653
|
+
}
|
|
1532
1654
|
function transformCode(code, file, analysis) {
|
|
1533
|
-
const { tagged } = analysis ??
|
|
1655
|
+
const { tagged } = analysis ?? analyzeFile(code, file);
|
|
1534
1656
|
if (tagged.length === 0) return null;
|
|
1535
1657
|
const s = new MagicString(code);
|
|
1536
1658
|
for (const msg of tagged) {
|
|
1537
1659
|
const seen = /* @__PURE__ */ new Set();
|
|
1538
1660
|
const entries = msg.params.filter((p) => !seen.has(p.name) && seen.add(p.name));
|
|
1539
|
-
const pairs = entries.map((p) => `${
|
|
1661
|
+
const pairs = entries.map((p) => `${quote(p.name, msg.singleQuote)}: ${code.slice(p.start, p.end)}`).join(", ");
|
|
1540
1662
|
if (msg.jsx) {
|
|
1541
1663
|
const values = entries.length ? ` values={{ ${pairs} }}` : "";
|
|
1542
1664
|
const components = msg.jsx.components.length ? ` components={{ ${msg.jsx.components.map((c) => `${JSON.stringify(c.name)}: ${c.source}`).join(", ")} }}` : "";
|
|
@@ -1545,7 +1667,7 @@ function transformCode(code, file, analysis) {
|
|
|
1545
1667
|
}
|
|
1546
1668
|
const tagSource = code.slice(msg.tagStart, msg.tagEnd);
|
|
1547
1669
|
const args = entries.length ? `, { ${pairs} }` : "";
|
|
1548
|
-
s.overwrite(msg.start, msg.end, `${tagSource}(${
|
|
1670
|
+
s.overwrite(msg.start, msg.end, `${tagSource}(${quote(msg.key, msg.singleQuote)}${args})`);
|
|
1549
1671
|
}
|
|
1550
1672
|
return {
|
|
1551
1673
|
code: s.toString(),
|
|
@@ -1553,6 +1675,6 @@ function transformCode(code, file, analysis) {
|
|
|
1553
1675
|
};
|
|
1554
1676
|
}
|
|
1555
1677
|
//#endregion
|
|
1556
|
-
export { LOCALE_MODULE_PREFIX, MessageRegistry, PSEUDO_LOCALE, RESOLVED_VIRTUAL_ID, SOURCE_FILE_RE, VIRTUAL_ID, analyze, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
|
|
1678
|
+
export { LOCALE_MODULE_PREFIX, MessageRegistry, PSEUDO_LOCALE, RESOLVED_VIRTUAL_ID, SFC_FILE_RE, SOURCE_FILE_RE, VIRTUAL_ID, analyze, analyzeFile, analyzeSfc, catalogPath, check, claudeProvider, collectParams, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, generateDts, generateLocaleModule, generateRuntimeModule, importCatalogs, init, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, structureMatches, syncCatalogs, targetLocales, transformCode, translateCatalogs, writeCatalog, writeDts };
|
|
1557
1679
|
|
|
1558
1680
|
//# sourceMappingURL=index.js.map
|