zlocalz
Version:
ZLocalz - TUI Locale Guardian for Flutter ARB l10n/i18n validation and translation with AI-powered fixes
191 lines • 7.03 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ICUView = void 0;
const blessed = __importStar(require("blessed"));
const parser_1 = require("@messageformat/parser");
class ICUView {
container;
tree;
constructor(parent) {
this.container = blessed.box({
parent,
top: 0,
left: 0,
width: '100%',
height: '100%',
hidden: true
});
this.tree = blessed.scrollabletext({
parent: this.container,
top: 0,
left: 0,
width: '100%',
height: '100%',
keys: true,
vi: true,
mouse: true,
tags: true,
scrollbar: {
ch: ' ',
track: { bg: '#333333' },
style: { inverse: true }
},
style: {
fg: 'white',
bg: '#1e1e1e'
}
});
}
setContent(targetValue, sourceValue) {
try {
const targetAST = (0, parser_1.parse)(targetValue);
const sourceAST = sourceValue ? (0, parser_1.parse)(sourceValue) : null;
const formatted = this.formatICU(targetAST, sourceAST);
this.tree.setContent(formatted);
}
catch (error) {
this.tree.setContent(`{red-fg}Error parsing ICU message:{/red-fg}\n\n${error}`);
}
}
formatICU(ast, sourceAST) {
const lines = ['{bold}ICU Message Structure{/bold}\n'];
if (sourceAST) {
lines.push('{cyan-fg}Source structure for comparison{/cyan-fg}');
}
const targetTree = this.buildTree(ast, 0);
const sourceTree = sourceAST ? this.buildTree(sourceAST, 0) : [];
lines.push('\n{bold}Target:{/bold}');
lines.push(...targetTree);
if (sourceTree.length > 0) {
lines.push('\n{bold}Source:{/bold}');
lines.push(...sourceTree);
}
const issues = this.findStructuralDifferences(ast, sourceAST);
if (issues.length > 0) {
lines.push('\n{yellow-fg}Structural differences:{/yellow-fg}');
lines.push(...issues.map(issue => ` • ${issue}`));
}
return lines.join('\n');
}
buildTree(node, depth) {
const indent = ' '.repeat(depth);
const lines = [];
if (Array.isArray(node)) {
node.forEach(item => {
lines.push(...this.buildTree(item, depth));
});
}
else if (node && typeof node === 'object') {
switch (node.type) {
case 'plural':
case 'select':
case 'selectordinal':
lines.push(`${indent}{magenta-fg}${node.type}{/magenta-fg} {${node.argument}}`);
if (node.options) {
Object.entries(node.options).forEach(([key, value]) => {
lines.push(`${indent} {cyan-fg}${key}:{/cyan-fg}`);
lines.push(...this.buildTree(value.value, depth + 2));
});
}
break;
case 'argument':
lines.push(`${indent}{green-fg}{${node.argument}}{/green-fg}`);
break;
case 'literal':
lines.push(`${indent}${node.value}`);
break;
default:
lines.push(`${indent}{gray-fg}[${node.type}]{/gray-fg}`);
}
}
else if (typeof node === 'string') {
lines.push(`${indent}${node}`);
}
return lines;
}
findStructuralDifferences(target, source) {
const issues = [];
if (!source)
return issues;
const targetBranches = this.extractBranches(target);
const sourceBranches = this.extractBranches(source);
for (const [type, branches] of sourceBranches) {
const targetTypeBranches = targetBranches.get(type);
if (!targetTypeBranches) {
issues.push(`Missing ${type} structure`);
continue;
}
const missingBranches = branches.filter(b => !targetTypeBranches.includes(b));
const extraBranches = targetTypeBranches.filter(b => !branches.includes(b));
if (missingBranches.length > 0) {
issues.push(`Missing ${type} branches: ${missingBranches.join(', ')}`);
}
if (extraBranches.length > 0) {
issues.push(`Extra ${type} branches: ${extraBranches.join(', ')}`);
}
}
return issues;
}
extractBranches(node) {
const branches = new Map();
const traverse = (n) => {
if (Array.isArray(n)) {
n.forEach(traverse);
}
else if (n && typeof n === 'object') {
if (n.type === 'plural' || n.type === 'select' || n.type === 'selectordinal') {
const keys = Object.keys(n.options || {}).sort();
branches.set(`${n.type}:${n.argument}`, keys);
}
if (n.value)
traverse(n.value);
if (n.options) {
Object.values(n.options).forEach((opt) => traverse(opt.value));
}
}
};
traverse(node);
return branches;
}
show() {
this.container.show();
}
hide() {
this.container.hide();
}
}
exports.ICUView = ICUView;
//# sourceMappingURL=icu-view.js.map