@verbaly/compiler 0.26.0 → 0.27.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/dist/{claude-C-ETlqsW.js → claude-h9WA0ppg.js} +4 -2
- package/dist/claude-h9WA0ppg.js.map +1 -0
- package/dist/cli.js +131 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.js +75 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/claude-C-ETlqsW.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -48,12 +48,14 @@ interface TranslateRequest {
|
|
|
48
48
|
sourceLocale: string;
|
|
49
49
|
targetLocale: string;
|
|
50
50
|
messages: Record<string, string>;
|
|
51
|
+
origins?: Record<string, string[]>;
|
|
51
52
|
}
|
|
52
53
|
type TranslateProvider = (request: TranslateRequest) => Promise<Record<string, string>>;
|
|
53
54
|
interface TranslateOptions {
|
|
54
55
|
locales?: string[];
|
|
55
56
|
batchSize?: number;
|
|
56
57
|
dryRun?: boolean;
|
|
58
|
+
origins?: Record<string, string[]>;
|
|
57
59
|
}
|
|
58
60
|
interface TranslateResult {
|
|
59
61
|
translated: Record<string, string[]>;
|
|
@@ -192,6 +194,15 @@ interface DoctorResult {
|
|
|
192
194
|
}
|
|
193
195
|
declare function doctor(cfg: ResolvedConfig): Promise<DoctorResult>;
|
|
194
196
|
//#endregion
|
|
197
|
+
//#region src/drafts.d.ts
|
|
198
|
+
declare const DRAFTS_FILE = ".verbaly-drafts.json";
|
|
199
|
+
type Drafts = Record<string, string[]>;
|
|
200
|
+
declare function loadDrafts(cfg: ResolvedConfig): Drafts;
|
|
201
|
+
declare function saveDrafts(cfg: ResolvedConfig, drafts: Drafts): void;
|
|
202
|
+
declare function markDrafts(drafts: Drafts, locale: string, keys: string[]): void;
|
|
203
|
+
declare function clearDrafts(drafts: Drafts, locale: string, keys?: string[]): void;
|
|
204
|
+
declare function effectiveDrafts(drafts: Drafts, catalogs: Catalogs): Drafts;
|
|
205
|
+
//#endregion
|
|
195
206
|
//#region src/exchange.d.ts
|
|
196
207
|
type ExchangeFormat = 'xliff' | 'csv';
|
|
197
208
|
type MobileFormat = 'android-xml' | 'ios-strings';
|
|
@@ -323,13 +334,14 @@ interface LocaleStatus {
|
|
|
323
334
|
locale: string;
|
|
324
335
|
translated: number;
|
|
325
336
|
total: number;
|
|
337
|
+
drafts: number;
|
|
326
338
|
}
|
|
327
339
|
interface StatusResult {
|
|
328
340
|
messages: number;
|
|
329
341
|
source: string;
|
|
330
342
|
locales: LocaleStatus[];
|
|
331
343
|
}
|
|
332
|
-
declare function status(cfg: ResolvedConfig, catalogs: Catalogs, registry: MessageRegistry): StatusResult;
|
|
344
|
+
declare function status(cfg: ResolvedConfig, catalogs: Catalogs, registry: MessageRegistry, drafts?: Drafts): StatusResult;
|
|
333
345
|
declare function formatStatusResult(result: StatusResult): string;
|
|
334
346
|
//#endregion
|
|
335
347
|
//#region src/watch.d.ts
|
|
@@ -369,5 +381,5 @@ interface WrapCodeResult {
|
|
|
369
381
|
}
|
|
370
382
|
declare function wrapCode(code: string, file: string): WrapCodeResult;
|
|
371
383
|
//#endregion
|
|
372
|
-
export { type Alternate, type Analysis, type AnalyzeOptions, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, type DoctorEntry, type DoctorResult, type ExchangeFormat, type ExportFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, LOCALE_MODULE_PREFIX, type LocaleStatus, MessageRegistry, type MissingEntry, type MobileFormat, PSEUDO_LOCALE, type ParamType, type PluginOptions, RESOLVED_VIRTUAL_ID, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type RuntimeModuleOptions, SFC_FILE_RE, SOURCE_FILE_RE, type StatusResult, 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, type WatchProjectOptions, type WrapCodeResult, type WrapEntry, type WrapOptions, type WrapResult, type WrapSkip, analyze, analyzeFile, analyzeSfc, catalogPath, check, claudeProvider, collectParams, createSourceFilter, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, formatStatusResult, generateDts, generateLocaleModule, generateRuntimeModule, githubCheckAnnotations, importCatalogs, init, isMobileFormat, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, status, structureMatches, syncCatalogs, targetLocales, transformCode, transformSource, translateCatalogs, watchProject, wrapCode, wrapProject, writeCatalog, writeDts };
|
|
384
|
+
export { type Alternate, type Analysis, type AnalyzeOptions, type Catalog, type Catalogs, type CheckResult, type ClaudeProviderOptions, DRAFTS_FILE, type DoctorEntry, type DoctorResult, type Drafts, type ExchangeFormat, type ExportFormat, type ExportOptions, type ExportResult, type ExportedFile, type ImportOptions, type ImportResult, type InitOptions, type InitResult, LOCALE_MODULE_PREFIX, type LocaleStatus, MessageRegistry, type MissingEntry, type MobileFormat, PSEUDO_LOCALE, type ParamType, type PluginOptions, RESOLVED_VIRTUAL_ID, type RenderConfig, type RenderHtmlOptions, type RenderHtmlResult, type RenderSiteOptions, type RenderSiteResult, type ResolvedConfig, type RuntimeModuleOptions, SFC_FILE_RE, SOURCE_FILE_RE, type StatusResult, 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, type WatchProjectOptions, type WrapCodeResult, type WrapEntry, type WrapOptions, type WrapResult, type WrapSkip, analyze, analyzeFile, analyzeSfc, catalogPath, check, claudeProvider, clearDrafts, collectParams, createSourceFilter, detectBundler, doctor, effectiveDrafts, exportCatalogs, extractProject, findConfigFile, formatCheckResult, formatStatusResult, generateDts, generateLocaleModule, generateRuntimeModule, githubCheckAnnotations, importCatalogs, init, isMobileFormat, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadDrafts, loadVirtualModule, markDrafts, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, saveDrafts, serializeCatalog, stableKey, status, structureMatches, syncCatalogs, targetLocales, transformCode, transformSource, translateCatalogs, watchProject, wrapCode, wrapProject, writeCatalog, writeDts };
|
|
373
385
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -824,7 +824,7 @@ function resolveConfig(config = {}) {
|
|
|
824
824
|
const sourceLocale = config.sourceLocale ?? "en";
|
|
825
825
|
const locales = /* @__PURE__ */ new Set([sourceLocale, ...config.locales ?? []]);
|
|
826
826
|
if (existsSync(dir)) {
|
|
827
|
-
for (const file of readdirSync(dir)) if (file.endsWith(".json") && file !== `en-XA.json`) locales.add(file.slice(0, -5));
|
|
827
|
+
for (const file of readdirSync(dir)) if (file.endsWith(".json") && !file.startsWith(".") && file !== `en-XA.json`) locales.add(file.slice(0, -5));
|
|
828
828
|
}
|
|
829
829
|
return {
|
|
830
830
|
root,
|
|
@@ -1211,6 +1211,66 @@ function readDeps(root) {
|
|
|
1211
1211
|
}
|
|
1212
1212
|
}
|
|
1213
1213
|
//#endregion
|
|
1214
|
+
//#region src/drafts.ts
|
|
1215
|
+
const DRAFTS_FILE = ".verbaly-drafts.json";
|
|
1216
|
+
function draftsPath(cfg) {
|
|
1217
|
+
return join(cfg.dir, DRAFTS_FILE);
|
|
1218
|
+
}
|
|
1219
|
+
function loadDrafts(cfg) {
|
|
1220
|
+
let content;
|
|
1221
|
+
try {
|
|
1222
|
+
content = readFileSync(draftsPath(cfg), "utf8");
|
|
1223
|
+
} catch {
|
|
1224
|
+
return {};
|
|
1225
|
+
}
|
|
1226
|
+
try {
|
|
1227
|
+
return JSON.parse(content.replace(/^\uFEFF/, ""));
|
|
1228
|
+
} catch (error) {
|
|
1229
|
+
throw new Error(`[verbaly] ${draftsPath(cfg)} is not valid JSON, fix or delete the file`, { cause: error });
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
function serializeDrafts(drafts) {
|
|
1233
|
+
const sorted = {};
|
|
1234
|
+
for (const locale of Object.keys(drafts).sort()) {
|
|
1235
|
+
const keys = [...new Set(drafts[locale])].sort();
|
|
1236
|
+
if (keys.length) sorted[locale] = keys;
|
|
1237
|
+
}
|
|
1238
|
+
return JSON.stringify(sorted, null, 2) + "\n";
|
|
1239
|
+
}
|
|
1240
|
+
function saveDrafts(cfg, drafts) {
|
|
1241
|
+
const serialized = serializeDrafts(drafts);
|
|
1242
|
+
const path = draftsPath(cfg);
|
|
1243
|
+
try {
|
|
1244
|
+
if (readFileSync(path, "utf8") === serialized) return;
|
|
1245
|
+
} catch {
|
|
1246
|
+
mkdirSync(cfg.dir, { recursive: true });
|
|
1247
|
+
}
|
|
1248
|
+
writeFileSync(path, serialized);
|
|
1249
|
+
}
|
|
1250
|
+
function markDrafts(drafts, locale, keys) {
|
|
1251
|
+
if (!keys.length) return;
|
|
1252
|
+
drafts[locale] = [.../* @__PURE__ */ new Set([...drafts[locale] ?? [], ...keys])];
|
|
1253
|
+
}
|
|
1254
|
+
function clearDrafts(drafts, locale, keys) {
|
|
1255
|
+
if (!drafts[locale]) return;
|
|
1256
|
+
if (!keys) {
|
|
1257
|
+
delete drafts[locale];
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
const drop = new Set(keys);
|
|
1261
|
+
drafts[locale] = drafts[locale].filter((key) => !drop.has(key));
|
|
1262
|
+
if (!drafts[locale].length) delete drafts[locale];
|
|
1263
|
+
}
|
|
1264
|
+
function effectiveDrafts(drafts, catalogs) {
|
|
1265
|
+
const out = {};
|
|
1266
|
+
for (const [locale, keys] of Object.entries(drafts)) {
|
|
1267
|
+
const catalog = catalogs[locale] ?? {};
|
|
1268
|
+
const live = keys.filter((key) => catalog[key]);
|
|
1269
|
+
if (live.length) out[locale] = live;
|
|
1270
|
+
}
|
|
1271
|
+
return out;
|
|
1272
|
+
}
|
|
1273
|
+
//#endregion
|
|
1214
1274
|
//#region src/mobile.ts
|
|
1215
1275
|
function androidValuesDir(locale, sourceLocale) {
|
|
1216
1276
|
if (locale === sourceLocale) return "values";
|
|
@@ -1271,10 +1331,12 @@ async function translateCatalogs(cfg, catalogs, provider, options = {}) {
|
|
|
1271
1331
|
for (let i = 0; i < missing.length; i += batchSize) {
|
|
1272
1332
|
const keys = missing.slice(i, i + batchSize);
|
|
1273
1333
|
const messages = Object.fromEntries(keys.map((key) => [key, source[key]]));
|
|
1334
|
+
const origins = options.origins ? Object.fromEntries(keys.filter((key) => options.origins[key]).map((key) => [key, options.origins[key]])) : void 0;
|
|
1274
1335
|
const out = await provider({
|
|
1275
1336
|
sourceLocale: cfg.sourceLocale,
|
|
1276
1337
|
targetLocale: locale,
|
|
1277
|
-
messages
|
|
1338
|
+
messages,
|
|
1339
|
+
origins
|
|
1278
1340
|
});
|
|
1279
1341
|
for (const key of keys) {
|
|
1280
1342
|
const text = out[key];
|
|
@@ -1551,7 +1613,9 @@ function claudeProvider(options = {}) {
|
|
|
1551
1613
|
};
|
|
1552
1614
|
}
|
|
1553
1615
|
function buildPrompt(request) {
|
|
1554
|
-
|
|
1616
|
+
const origins = request.origins;
|
|
1617
|
+
const context = origins && Object.keys(origins).length ? `\n\nWhere each string appears (context for tone and length, do not translate these paths):\n` + Object.entries(origins).map(([key, files]) => ` ${key}: ${files.join(", ")}`).join("\n") : "";
|
|
1618
|
+
return `Translate each value from "${request.sourceLocale}" to "${request.targetLocale}". Return a JSON object with the same keys and translated values.\n\n` + JSON.stringify(request.messages, null, 2) + context;
|
|
1555
1619
|
}
|
|
1556
1620
|
function batchFormat(request) {
|
|
1557
1621
|
const keys = Object.keys(request.messages);
|
|
@@ -1845,9 +1909,10 @@ function decodeEntities(text) {
|
|
|
1845
1909
|
}
|
|
1846
1910
|
//#endregion
|
|
1847
1911
|
//#region src/status.ts
|
|
1848
|
-
function status(cfg, catalogs, registry) {
|
|
1912
|
+
function status(cfg, catalogs, registry, drafts = {}) {
|
|
1849
1913
|
const source = catalogs[cfg.sourceLocale] ?? {};
|
|
1850
1914
|
const needed = /* @__PURE__ */ new Set([...registry.messages().keys(), ...Object.keys(source)]);
|
|
1915
|
+
const live = effectiveDrafts(drafts, catalogs);
|
|
1851
1916
|
const locales = [];
|
|
1852
1917
|
for (const locale of cfg.locales) {
|
|
1853
1918
|
if (locale === cfg.sourceLocale) continue;
|
|
@@ -1856,7 +1921,8 @@ function status(cfg, catalogs, registry) {
|
|
|
1856
1921
|
locales.push({
|
|
1857
1922
|
locale,
|
|
1858
1923
|
translated,
|
|
1859
|
-
total: needed.size
|
|
1924
|
+
total: needed.size,
|
|
1925
|
+
drafts: live[locale]?.length ?? 0
|
|
1860
1926
|
});
|
|
1861
1927
|
}
|
|
1862
1928
|
return {
|
|
@@ -1871,10 +1937,11 @@ function formatStatusResult(result) {
|
|
|
1871
1937
|
lines.push(" no target locales (add locales to your config)");
|
|
1872
1938
|
return lines.join("\n");
|
|
1873
1939
|
}
|
|
1874
|
-
for (const { locale, translated, total } of result.locales) {
|
|
1940
|
+
for (const { locale, translated, total, drafts } of result.locales) {
|
|
1875
1941
|
const pct = total === 0 ? 100 : Math.floor(translated / total * 100);
|
|
1876
1942
|
const mark = translated === total ? " ✓" : "";
|
|
1877
|
-
|
|
1943
|
+
const draftNote = drafts > 0 ? `, ${drafts} unreviewed` : "";
|
|
1944
|
+
lines.push(` ${locale}: ${translated}/${total} translated (${pct}%${draftNote})${mark}`);
|
|
1878
1945
|
}
|
|
1879
1946
|
return lines.join("\n");
|
|
1880
1947
|
}
|
|
@@ -2132,6 +2199,6 @@ function line(node) {
|
|
|
2132
2199
|
return node.loc?.start?.line ?? 1;
|
|
2133
2200
|
}
|
|
2134
2201
|
//#endregion
|
|
2135
|
-
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, createSourceFilter, detectBundler, doctor, exportCatalogs, extractProject, findConfigFile, formatCheckResult, formatStatusResult, generateDts, generateLocaleModule, generateRuntimeModule, githubCheckAnnotations, importCatalogs, init, isMobileFormat, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadVirtualModule, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, serializeCatalog, stableKey, status, structureMatches, syncCatalogs, targetLocales, transformCode, transformSource, translateCatalogs, watchProject, wrapCode, wrapProject, writeCatalog, writeDts };
|
|
2202
|
+
export { DRAFTS_FILE, LOCALE_MODULE_PREFIX, MessageRegistry, PSEUDO_LOCALE, RESOLVED_VIRTUAL_ID, SFC_FILE_RE, SOURCE_FILE_RE, VIRTUAL_ID, analyze, analyzeFile, analyzeSfc, catalogPath, check, claudeProvider, clearDrafts, collectParams, createSourceFilter, detectBundler, doctor, effectiveDrafts, exportCatalogs, extractProject, findConfigFile, formatCheckResult, formatStatusResult, generateDts, generateLocaleModule, generateRuntimeModule, githubCheckAnnotations, importCatalogs, init, isMobileFormat, isTransformTarget, loadCatalogs, loadConfig, loadConfigFile, loadDrafts, loadVirtualModule, markDrafts, parseExchangeFile, pruneCatalogs, pseudoCatalogs, pseudoLocalize, readCatalog, renderHtml, renderParamType, renderSite, resolveConfig, resolveVirtualId, runBuildGate, saveDrafts, serializeCatalog, stableKey, status, structureMatches, syncCatalogs, targetLocales, transformCode, transformSource, translateCatalogs, watchProject, wrapCode, wrapProject, writeCatalog, writeDts };
|
|
2136
2203
|
|
|
2137
2204
|
//# sourceMappingURL=index.js.map
|