A lots of translation changes (Generate translation files)
parent
3ec5db38d8
commit
4511a30ade
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
FILE="${BASEDIR}/../compiler.ts"
|
||||
|
||||
npm run dtsgen -- $@
|
|
@ -0,0 +1,85 @@
|
|||
import * as ts from "typescript";
|
||||
import * as generator from "./generator";
|
||||
|
||||
import {readFileSync} from "fs";
|
||||
import * as glob from "glob";
|
||||
import * as path from "path";
|
||||
|
||||
const transformer = <T extends ts.Node>(context: ts.TransformationContext) => (rootNode: T) => {
|
||||
return generator.transform({
|
||||
use_window: false,
|
||||
replace_cache: true,
|
||||
verbose: true
|
||||
}, context, rootNode as any).node;
|
||||
};
|
||||
|
||||
|
||||
function compile(fileNames: string[], options: ts.CompilerOptions): void {
|
||||
const program: ts.Program = ts.createProgram(fileNames, options);
|
||||
|
||||
//(context: TransformationContext) => Transformer<T>;
|
||||
let emitResult = program.emit(undefined, undefined, undefined, undefined, {
|
||||
before: [ transformer ]
|
||||
});
|
||||
|
||||
let allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
||||
|
||||
allDiagnostics.forEach(diagnostic => {
|
||||
if (diagnostic.file) {
|
||||
let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
|
||||
diagnostic.start!
|
||||
);
|
||||
let message = ts.flattenDiagnosticMessageText(
|
||||
diagnostic.messageText,
|
||||
"\n"
|
||||
);
|
||||
console.log(
|
||||
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let exitCode = emitResult.emitSkipped ? 1 : 0;
|
||||
console.log(`Process exiting with code '${exitCode}'.`);
|
||||
process.exit(exitCode);
|
||||
}
|
||||
|
||||
console.log("Arguments: " + process.argv.slice(2));
|
||||
const config = ts.parseCommandLine(process.argv.slice(2), file => readFileSync(file).toString());
|
||||
console.dir(config);
|
||||
if(config.errors && config.errors.length > 0) {
|
||||
for(const error of config.errors)
|
||||
console.log(error.messageText);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if(config.options.project) {
|
||||
const project = ts.readConfigFile(config.options.project, file => readFileSync(file).toString()).config;
|
||||
const base_path = path.dirname(config.options.project) + "/";
|
||||
console.dir(project);
|
||||
|
||||
|
||||
const negate_files: string[] = [].concat.apply([], (project.exclude || []).map(file => glob.sync(base_path + file))).map(file => path.normalize(file));
|
||||
project.include.forEach(file => {
|
||||
glob.sync(base_path + file).forEach(_file => {
|
||||
_file = path.normalize(_file);
|
||||
for(const n_file of negate_files) {
|
||||
if(n_file == _file) {
|
||||
console.log("Skipping %s", _file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
config.fileNames.push(_file);
|
||||
});
|
||||
});
|
||||
|
||||
Object.assign(config.options, project.compilerOptions);
|
||||
console.log(config.options);
|
||||
}
|
||||
|
||||
compile(config.fileNames, config.options);
|
|
@ -0,0 +1,306 @@
|
|||
import * as ts from "typescript";
|
||||
import * as sha256 from "sha256";
|
||||
import {SyntaxKind} from "typescript";
|
||||
|
||||
|
||||
export function generate(file: ts.SourceFile, config: Configuration) : TranslationEntry[] {
|
||||
let result: TranslationEntry[] = [];
|
||||
|
||||
file.forEachChild(n => _generate(config, n, result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function report(node: ts.Node, message: string) {
|
||||
const sf = node.getSourceFile();
|
||||
let { line, character } = sf ? sf.getLineAndCharacterOfPosition(node.getStart()) : {line: -1, character: -1};
|
||||
console.log(`${(sf || {fileName: "unknown"}).fileName} (${line + 1},${character + 1}): ${message}`);
|
||||
}
|
||||
|
||||
function _generate(config: Configuration, node: ts.Node, result: TranslationEntry[]) {
|
||||
//console.log("Node: %s", SyntaxKind[node.kind]);
|
||||
|
||||
call_analize:
|
||||
if(ts.isCallExpression(node)) {
|
||||
const call = <ts.CallExpression>node;
|
||||
const call_name = call.expression["escapedText"] as string;
|
||||
if(call_name != "tr") break call_analize;
|
||||
|
||||
console.dir(call_name);
|
||||
|
||||
console.log("Parameters: %o", call.arguments.length);
|
||||
if(call.arguments.length > 1) {
|
||||
report(call, "Invalid argument count");
|
||||
node.forEachChild(n => _generate(config, n, result));
|
||||
return;
|
||||
}
|
||||
|
||||
const object = <ts.StringLiteral>call.arguments[0];
|
||||
if(object.kind != SyntaxKind.StringLiteral) {
|
||||
report(call, "Invalid argument: " + SyntaxKind[object.kind]);
|
||||
node.forEachChild(n => _generate(config, n, result));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Message: %o", object.text);
|
||||
|
||||
//FIXME
|
||||
if(config.replace_cache) {
|
||||
console.log("Update!");
|
||||
ts.updateCall(call, call.expression, call.typeArguments, [ts.createLiteral("PENIS!")]);
|
||||
}
|
||||
|
||||
const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
|
||||
result.push({
|
||||
filename: node.getSourceFile().fileName,
|
||||
line: line,
|
||||
character: character,
|
||||
message: object.text
|
||||
});
|
||||
}
|
||||
|
||||
node.forEachChild(n => _generate(config, n, result));
|
||||
}
|
||||
function create_unique_check(source_file: ts.SourceFile, variable: ts.Expression, variables: { name: string, node: ts.Node }[]) : ts.Node[] {
|
||||
const nodes: ts.Node[] = [], blocked_nodes: ts.Statement[] = [];
|
||||
|
||||
const node_path = (node: ts.Node) => {
|
||||
const sf = node.getSourceFile();
|
||||
let { line, character } = sf ? sf.getLineAndCharacterOfPosition(node.getStart()) : {line: -1, character: -1};
|
||||
return `${(sf || {fileName: "unknown"}).fileName} (${line + 1},${character + 1})`;
|
||||
};
|
||||
|
||||
const create_error = (variable_name: ts.Expression, variable_path: ts.Expression, other_path: ts.Expression) => {
|
||||
return [
|
||||
ts.createLiteral("Translation with generated name \""),
|
||||
variable_name,
|
||||
ts.createLiteral("\" already exists!\nIt has been already defined here: "),
|
||||
other_path,
|
||||
ts.createLiteral("\nAttempted to redefine here: "),
|
||||
variable_path,
|
||||
ts.createLiteral("\nRegenerate and/or fix your program!")
|
||||
].reduce((a, b) => ts.createBinary(a, SyntaxKind.PlusToken, b));
|
||||
};
|
||||
|
||||
let declarations_file: ts.Expression;
|
||||
const unique_check_label_name = "unique_translation_check";
|
||||
|
||||
/* initialization */
|
||||
{
|
||||
const declarations = ts.createElementAccess(variable, ts.createLiteral("declared"));
|
||||
nodes.push(ts.createAssignment(declarations, ts.createBinary(declarations, SyntaxKind.BarBarToken, ts.createAssignment(declarations, ts.createObjectLiteral()))));
|
||||
|
||||
declarations_file = ts.createElementAccess(variable, ts.createLiteral("declared_files"));
|
||||
nodes.push(ts.createAssignment(declarations_file, ts.createBinary(declarations_file, SyntaxKind.BarBarToken, ts.createAssignment(declarations_file, ts.createObjectLiteral()))));
|
||||
|
||||
variable = declarations;
|
||||
}
|
||||
|
||||
/* test file already loaded */
|
||||
{
|
||||
const unique_id = sha256(source_file.fileName + " | " + (Date.now() / 1000));
|
||||
const property = ts.createElementAccess(declarations_file, ts.createLiteral(unique_id));
|
||||
|
||||
const if_condition = ts.createBinary(property, SyntaxKind.ExclamationEqualsEqualsToken, ts.createIdentifier("undefined"));
|
||||
//
|
||||
let if_then: ts.Block;
|
||||
{
|
||||
const elements: ts.Statement[] = [];
|
||||
|
||||
const console = ts.createIdentifier("console.warn");
|
||||
elements.push(ts.createCall(console, [], [ts.createLiteral("This file has already been loaded!\nAre you executing scripts twice?") as any]));
|
||||
elements.push(ts.createBreak(unique_check_label_name));
|
||||
|
||||
if_then = ts.createBlock(elements);
|
||||
}
|
||||
|
||||
const if_else = ts.createAssignment(property, ts.createLiteral(unique_id));
|
||||
blocked_nodes.push(ts.createIf(if_condition, if_then, if_else as any));
|
||||
}
|
||||
|
||||
/* test if variable has been defined somewhere else */
|
||||
{
|
||||
const for_variable_name = ts.createLoopVariable();
|
||||
const for_variable_path = ts.createLoopVariable();
|
||||
const for_declaration = ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern([
|
||||
ts.createBindingElement(undefined, "name", for_variable_name, undefined),
|
||||
ts.createBindingElement(undefined, "path", for_variable_path, undefined)])
|
||||
, undefined, undefined)]);
|
||||
|
||||
let for_block: ts.Statement;
|
||||
{ //Create the for block
|
||||
const elements: ts.Statement[] = [];
|
||||
|
||||
|
||||
const property = ts.createElementAccess(variable, for_variable_name);
|
||||
const if_condition = ts.createBinary(property, SyntaxKind.ExclamationEqualsEqualsToken, ts.createIdentifier("undefined"));
|
||||
|
||||
//
|
||||
const if_then = ts.createThrow(create_error(for_variable_name, for_variable_path, property));
|
||||
const if_else = ts.createAssignment(property, for_variable_path);
|
||||
const if_valid = ts.createIf(if_condition, if_then, if_else as any);
|
||||
|
||||
elements.push(if_valid);
|
||||
|
||||
for_block = ts.createBlock(elements);
|
||||
}
|
||||
|
||||
let block = ts.createForOf(undefined,
|
||||
for_declaration, ts.createArrayLiteral(
|
||||
[...variables.map(e => ts.createObjectLiteral([
|
||||
ts.createPropertyAssignment("name", ts.createLiteral(e.name)),
|
||||
ts.createPropertyAssignment("path", ts.createLiteral(node_path(e.node)))
|
||||
]))
|
||||
])
|
||||
, for_block);
|
||||
block = ts.addSyntheticLeadingComment(block, SyntaxKind.MultiLineCommentTrivia, "Auto generated helper for testing if the translation keys are unique", true);
|
||||
blocked_nodes.push(block);
|
||||
}
|
||||
return [...nodes, ts.createLabel(unique_check_label_name, ts.createBlock(blocked_nodes))];
|
||||
}
|
||||
|
||||
export function transform(config: Configuration, context: ts.TransformationContext, node: ts.SourceFile) : TransformResult {
|
||||
const cache: VolatileTransformConfig = {} as any;
|
||||
cache.translations = [];
|
||||
|
||||
//Initialize nodes
|
||||
const extra_nodes: ts.Node[] = [];
|
||||
{
|
||||
cache.nodes = {} as any;
|
||||
if(config.use_window) {
|
||||
const window = ts.createIdentifier("window");
|
||||
let translation_map = ts.createPropertyAccess(window, ts.createIdentifier("_translations"));
|
||||
const new_translations = ts.createAssignment(translation_map, ts.createObjectLiteral());
|
||||
|
||||
let translation_map_init: ts.Expression = ts.createBinary(translation_map, ts.SyntaxKind.BarBarToken, new_translations);
|
||||
translation_map_init = ts.createParen(translation_map_init);
|
||||
|
||||
cache.nodes = {
|
||||
translation_map: translation_map,
|
||||
translation_map_init: translation_map_init
|
||||
};
|
||||
} else {
|
||||
const variable_name = "_translations";
|
||||
const variable_map = ts.createIdentifier(variable_name);
|
||||
|
||||
const inline_if = ts.createBinary(ts.createBinary(ts.createTypeOf(variable_map), SyntaxKind.ExclamationEqualsEqualsToken, ts.createLiteral("undefined")), ts.SyntaxKind.BarBarToken, ts.createAssignment(variable_map, ts.createObjectLiteral()));
|
||||
|
||||
cache.nodes = {
|
||||
translation_map: variable_map,
|
||||
translation_map_init: variable_map
|
||||
};
|
||||
|
||||
//ts.createVariableDeclarationList([ts.createVariableDeclaration(variable_name)], ts.NodeFlags.Let)
|
||||
extra_nodes.push(inline_if);
|
||||
}
|
||||
}
|
||||
|
||||
const generated_names: { name: string, node: ts.Node }[] = [];
|
||||
cache.name_generator = (config, node, message) => {
|
||||
const characters = "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
let name = "";
|
||||
while(name.length < 8) {
|
||||
const char = characters[Math.floor(Math.random() * characters.length)];
|
||||
name = name + char;
|
||||
if(name[0] >= '0' && name[0] <= '9')
|
||||
name = name.substr(1) || "";
|
||||
}
|
||||
|
||||
//FIXME
|
||||
//if(generated_names.indexOf(name) != -1)
|
||||
// return cache.name_generator(config, node, message);
|
||||
|
||||
generated_names.push({name: name, node: node});
|
||||
return name;
|
||||
};
|
||||
|
||||
function visit(node: ts.Node): ts.Node {
|
||||
node = ts.visitEachChild(node, visit, context);
|
||||
return replace_processor(config, cache, node);
|
||||
}
|
||||
node = ts.visitNode(node, visit);
|
||||
extra_nodes.push(...create_unique_check(node, cache.nodes.translation_map_init, generated_names));
|
||||
|
||||
node = ts.updateSourceFileNode(node, [...(extra_nodes as any[]), ...node.statements], node.isDeclarationFile, node.referencedFiles, node.typeReferenceDirectives, node.hasNoDefaultLib, node.referencedFiles);
|
||||
|
||||
const result: TransformResult = {} as any;
|
||||
result.node = node;
|
||||
result.translations = cache.translations;
|
||||
return result;
|
||||
}
|
||||
|
||||
export function replace_processor(config: Configuration, cache: VolatileTransformConfig, node: ts.Node) : ts.Node {
|
||||
if(config.verbose)
|
||||
console.log("Process %s", SyntaxKind[node.kind]);
|
||||
if(ts.isCallExpression(node)) {
|
||||
const call = <ts.CallExpression>node;
|
||||
const call_name = call.expression["escapedText"] as string;
|
||||
if(call_name != "tr") return node;
|
||||
|
||||
if(config.verbose) {
|
||||
console.dir(call_name);
|
||||
console.log("Parameters: %o", call.arguments.length);
|
||||
}
|
||||
if(call.arguments.length > 1) {
|
||||
report(call, "Invalid argument count");
|
||||
return node;
|
||||
}
|
||||
|
||||
const object = <ts.StringLiteral>call.arguments[0];
|
||||
if(object.kind != SyntaxKind.StringLiteral) {
|
||||
report(call, "Invalid argument: " + SyntaxKind[object.kind]);
|
||||
return node;
|
||||
}
|
||||
|
||||
if(config.verbose)
|
||||
console.log("Message: %o", object.text || object.getText());
|
||||
|
||||
const variable_name = ts.createIdentifier(cache.name_generator(config, node, object.text || object.getText()));
|
||||
const variable_init = ts.createPropertyAccess(cache.nodes.translation_map_init, variable_name);
|
||||
|
||||
const variable = ts.createPropertyAccess(cache.nodes.translation_map, variable_name);
|
||||
const new_variable = ts.createAssignment(variable, call);
|
||||
|
||||
const source_file = node.getSourceFile();
|
||||
let { line, character } = source_file ? source_file.getLineAndCharacterOfPosition(node.getStart()) : {line: -1, character: -1};
|
||||
|
||||
cache.translations.push({
|
||||
message: object.text || object.getText(),
|
||||
line: line,
|
||||
character: character,
|
||||
filename: (source_file || {fileName: "unknown"}).fileName
|
||||
});
|
||||
|
||||
return ts.createBinary(variable_init, ts.SyntaxKind.BarBarToken, new_variable);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export interface TranslationEntry {
|
||||
filename: string;
|
||||
line: number;
|
||||
character: number;
|
||||
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface Configuration {
|
||||
use_window?: boolean;
|
||||
replace_cache?: boolean;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
export interface TransformResult {
|
||||
node: ts.SourceFile;
|
||||
translations: TranslationEntry[];
|
||||
}
|
||||
|
||||
interface VolatileTransformConfig {
|
||||
nodes: {
|
||||
translation_map: ts.Expression;
|
||||
translation_map_init: ts.Expression;
|
||||
};
|
||||
|
||||
name_generator: (config: Configuration, node: ts.Node, message: string) => string;
|
||||
translations: TranslationEntry[];
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
import * as ts from "typescript";
|
||||
import * as generator from "./generator";
|
||||
import {readFileSync, writeFileSync} from "fs";
|
||||
import * as path from "path";
|
||||
import * as glob from "glob";
|
||||
import {isArray} from "util";
|
||||
|
||||
console.log("TR GEN!");
|
||||
|
||||
/*
|
||||
const files = ["/home/wolverindev/TeaSpeak/TeaSpeak/Web-Client/build/trgen/test/test_01.ts"];
|
||||
files.forEach(file => {
|
||||
let source = ts.createSourceFile(
|
||||
file,
|
||||
readFileSync(file).toString(),
|
||||
ts.ScriptTarget.ES2016,
|
||||
true
|
||||
);
|
||||
|
||||
generator.generate(source);
|
||||
});
|
||||
*/
|
||||
|
||||
interface Config {
|
||||
source_files?: string[];
|
||||
excluded_files?: string[];
|
||||
target_file?: string;
|
||||
verbose?: boolean;
|
||||
|
||||
base_bath?: string;
|
||||
file_config?: string;
|
||||
}
|
||||
|
||||
let config: Config = {};
|
||||
|
||||
let args = process.argv.slice(2);
|
||||
while(args.length > 0) {
|
||||
if(args[0] == "-f" || args[0] == "--file") {
|
||||
(config.source_files || (config.source_files = [])).push(args[1]);
|
||||
args = args.slice(2);
|
||||
} else if(args[0] == "-e" || args[0] == "--exclude") {
|
||||
(config.excluded_files || (config.excluded_files = [])).push(args[1]);
|
||||
args = args.slice(2);
|
||||
} else if(args[0] == "-d" || args[0] == "--destination") {
|
||||
config.target_file = args[1];
|
||||
args = args.slice(2);
|
||||
} else if(args[0] == "-v" || args[0] == "--verbose") {
|
||||
config.verbose = true;
|
||||
args = args.slice(1);
|
||||
} else if(args[0] == "-c" || args[0] == "--config") {
|
||||
config.file_config = args[1];
|
||||
config.base_bath = path.normalize(path.dirname(config.file_config)) + "/";
|
||||
args = args.slice(2);
|
||||
} else {
|
||||
console.error("Invalid command line option \"%s\"", args[0]);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
config.base_bath = config.base_bath || "";
|
||||
|
||||
|
||||
if(config.verbose) {
|
||||
console.log("Base path: " + config.base_bath);
|
||||
console.log("Input files:");
|
||||
for(const file of config.source_files)
|
||||
console.log(" - " + file);
|
||||
console.log("Target file: " + config.target_file;
|
||||
}
|
||||
|
||||
const negate_files: string[] = [].concat.apply([], (config.excluded_files || []).map(file => glob.sync(config.base_bath + file))).map(file => path.normalize(file));
|
||||
|
||||
let result = "";
|
||||
|
||||
function print(nodes: ts.Node[] | ts.SourceFile) : string {
|
||||
if(!isArray(nodes) && nodes.kind == ts.SyntaxKind.SourceFile)
|
||||
nodes = (<ts.SourceFile>nodes).getChildren();
|
||||
const dummy_file = ts.createSourceFile(
|
||||
"dummy_file",
|
||||
"",
|
||||
ts.ScriptTarget.ES2016,
|
||||
false,
|
||||
ts.ScriptKind.TS
|
||||
);
|
||||
|
||||
const printer = ts.createPrinter({
|
||||
newLine: ts.NewLineKind.LineFeed
|
||||
});
|
||||
|
||||
return printer.printList(
|
||||
ts.ListFormat.SpaceBetweenBraces | ts.ListFormat.MultiLine | ts.ListFormat.PreferNewLine,
|
||||
nodes as any,
|
||||
dummy_file
|
||||
);
|
||||
}
|
||||
|
||||
config.source_files.forEach(file => {
|
||||
if(config.verbose)
|
||||
console.log("iterating over %s", file)
|
||||
glob.sync(config.base_bath + file).forEach(_file => {
|
||||
_file = path.normalize(_file);
|
||||
for(const n_file of negate_files) {
|
||||
if(n_file == _file) {
|
||||
console.log("Skipping %s", _file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let source = ts.createSourceFile(
|
||||
_file,
|
||||
readFileSync(_file).toString(),
|
||||
ts.ScriptTarget.ES2016,
|
||||
true
|
||||
);
|
||||
console.log(print(source));
|
||||
|
||||
console.log("Compile " + _file);
|
||||
|
||||
const messages = generator.generate(source, {
|
||||
replace_cache: true
|
||||
});
|
||||
messages.forEach(message => {
|
||||
console.log(message);
|
||||
});
|
||||
|
||||
console.log("PRINT!");
|
||||
console.log(print(source));
|
||||
/*
|
||||
result += "\n\n" + decl.print(decl.generate(source, {
|
||||
remove_private: false
|
||||
}));
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
mkdirp(path.normalize(path.dirname(base_path + "/" + target_file)), error => {
|
||||
if(error)
|
||||
throw error;
|
||||
writeFileSync(base_path + "/" + target_file, result);
|
||||
});
|
||||
*/
|
|
@ -0,0 +1,27 @@
|
|||
function tr(message: string) : string {
|
||||
console.log("Message: " + message);
|
||||
return message;
|
||||
}
|
||||
|
||||
const x = tr("yyy");
|
||||
function y() {
|
||||
const y = tr(tr("yyy"));
|
||||
}
|
||||
|
||||
console.log("XXX: " + tr("XXX"));
|
||||
console.log("YYY: " + tr("YYY"));
|
||||
|
||||
var z = 1 + 2 + 3;
|
||||
|
||||
debugger;
|
||||
debugger;
|
||||
debugger;
|
||||
debugger;
|
||||
const zzz = true ? "yyy" : "bbb";
|
||||
|
||||
const y
|
||||
debugger;
|
||||
debugger;
|
||||
debugger;
|
||||
debugger;
|
||||
const { a } = {a : ""};
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"moduleResolution": "node",
|
||||
"module": "commonjs",
|
||||
"lib": ["es6"],
|
||||
|
||||
"typeRoots": [],
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"generator.ts",
|
||||
"index.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import * as ts from "typescript";
|
||||
import * as generator from "./generator";
|
||||
import {PluginConfig} from "ttypescript/lib/PluginCreator";
|
||||
import {writeFileSync} from "fs";
|
||||
|
||||
interface Config {
|
||||
target_file?: string;
|
||||
verbose?: boolean;
|
||||
}
|
||||
|
||||
//(program: ts.Program, config?: PluginConfig) => ts.TransformerFactory
|
||||
let process_config: Config;
|
||||
export default function(program: ts.Program, config?: PluginConfig) : (context: ts.TransformationContext) => (sourceFile: ts.SourceFile) => ts.SourceFile {
|
||||
process_config = config as any || {};
|
||||
|
||||
if(process_config.verbose)
|
||||
console.log("TRGen transformer called");
|
||||
|
||||
process.on('exit', function () {
|
||||
if(process_config.target_file) {
|
||||
if(process_config.verbose)
|
||||
console.log("Writing translation file to " + process_config.target_file);
|
||||
|
||||
writeFileSync(process_config.target_file, JSON.stringify(translations, null, 2));
|
||||
}
|
||||
});
|
||||
|
||||
return ctx => transformer(ctx);
|
||||
}
|
||||
|
||||
const translations: generator.TranslationEntry[] = [];
|
||||
const transformer = (context: ts.TransformationContext) => (rootNode: ts.SourceFile) => {
|
||||
console.log("Processing " + rootNode.fileName);
|
||||
const result = generator.transform({
|
||||
use_window: false,
|
||||
replace_cache: true
|
||||
}, context, rootNode);
|
||||
translations.push(...result.translations);
|
||||
return result.node;
|
||||
};
|
|
@ -88,6 +88,15 @@
|
|||
"integrity": "sha1-IAmrVDLtH14ZGPfGsAC8d4VJshY=",
|
||||
"dev": true
|
||||
},
|
||||
"@types/sha256": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/sha256/-/sha256-0.2.0.tgz",
|
||||
"integrity": "sha512-QYMr6HuxTQunFWRLZpGopbkgQFoFWOmKTBGgNSYiWMqU/CWnQSTo3edyHvgsRXsOWtOSOG/cmDptPzgCeOsQGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "9.6.25"
|
||||
}
|
||||
},
|
||||
"@types/undertaker": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "http://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.0.tgz",
|
||||
|
@ -250,6 +259,12 @@
|
|||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||
"dev": true
|
||||
},
|
||||
"arrify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||
"dev": true
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
|
@ -636,6 +651,18 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"convert-hex": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-hex/-/convert-hex-0.1.0.tgz",
|
||||
"integrity": "sha1-CMBFaJIsJ3drii6BqV05M2LqC2U=",
|
||||
"dev": true
|
||||
},
|
||||
"convert-string": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz",
|
||||
"integrity": "sha1-ec5BqbsNA7z3LNxqjzxW+7xkQQo=",
|
||||
"dev": true
|
||||
},
|
||||
"copy-descriptor": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
|
@ -767,6 +794,12 @@
|
|||
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"duplexer2": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
|
||||
|
@ -2674,6 +2707,12 @@
|
|||
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
|
||||
"dev": true
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
|
||||
"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
|
||||
"dev": true
|
||||
},
|
||||
"make-iterator": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
|
||||
|
@ -3495,6 +3534,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"sha256": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/sha256/-/sha256-0.2.0.tgz",
|
||||
"integrity": "sha1-c6C0GNqrcDW/+G6EkeNjQS/CqwU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"convert-hex": "0.1.0",
|
||||
"convert-string": "0.1.0"
|
||||
}
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
|
||||
|
@ -3657,6 +3706,24 @@
|
|||
"urix": "0.1.0"
|
||||
}
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz",
|
||||
"integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "1.1.1",
|
||||
"source-map": "0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-map-url": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
|
||||
|
@ -3931,6 +3998,32 @@
|
|||
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
|
||||
"dev": true
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.2.0.tgz",
|
||||
"integrity": "sha512-ZNT+OEGfUNVMGkpIaDJJ44Zq3Yr0bkU/ugN1PHbU+/01Z7UV1fsELRiTx1KuQNvQ1A3pGh3y25iYF6jXgxV21A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arrify": "1.0.1",
|
||||
"buffer-from": "1.1.1",
|
||||
"diff": "3.5.0",
|
||||
"make-error": "1.3.5",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"source-map-support": "0.5.9",
|
||||
"yn": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ttypescript": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/ttypescript/-/ttypescript-1.5.5.tgz",
|
||||
"integrity": "sha512-ke01qTl2su6pzE9T9b1BgmtAq5kVqXzpiP4x0wiIme0nG+suR+eiZTC4tWA6EKn1mHaH4b86G4QOOhLIxEH9FA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"resolve": "1.8.1",
|
||||
"ts-node": "6.2.0"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
@ -4248,6 +4341,12 @@
|
|||
"requires": {
|
||||
"fd-slicer": "1.0.1"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
|
||||
"integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"scripts": {
|
||||
"compile-sass": "sass --update .:.",
|
||||
"build-worker": "tsc -p shared/js/workers/tsconfig_worker_codec.json",
|
||||
"dtsgen": "node build/dtsgen/index.js"
|
||||
"dtsgen": "node build/dtsgen/index.js",
|
||||
"trgen": "node build/trgen/index.js"
|
||||
},
|
||||
"author": "TeaSpeak (WolverinDEV)",
|
||||
"license": "ISC",
|
||||
|
@ -17,10 +18,13 @@
|
|||
"@types/jquery": "3.3.5",
|
||||
"@types/moment": "^2.13.0",
|
||||
"@types/node": "^9.4.6",
|
||||
"@types/sha256": "^0.2.0",
|
||||
"@types/websocket": "0.0.38",
|
||||
"electron": "^3.0.2",
|
||||
"gulp": "^3.9.1",
|
||||
"sass": "^1.14.1",
|
||||
"sha256": "^0.2.0",
|
||||
"ttypescript": "^1.5.5",
|
||||
"typescript": "^3.1.1"
|
||||
},
|
||||
"repository": {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -98,7 +98,7 @@ class TSClient {
|
|||
helpers.hashPassword(password.password).then(password => {
|
||||
this.serverConnection.startConnection({host, port}, new HandshakeHandler(identity, name, password));
|
||||
}).catch(error => {
|
||||
createErrorModal(tr("Error while hashing password"), tr("Failed to hash server password!<br>" + error).open();
|
||||
createErrorModal(tr("Error while hashing password"), tr("Failed to hash server password!<br>") + error).open();
|
||||
})
|
||||
} else
|
||||
this.serverConnection.startConnection({host, port}, new HandshakeHandler(identity, name, password ? password.password : undefined));
|
||||
|
|
|
@ -78,6 +78,10 @@ function setup_jsrender() : boolean {
|
|||
return moment(arguments[0]).format(arguments[1]);
|
||||
});
|
||||
|
||||
js_render.views.tags("tr", (...arguments) => {
|
||||
return tr(arguments[0]);
|
||||
});
|
||||
|
||||
$(".jsrender-template").each((idx, _entry) => {
|
||||
if(!js_render.templates(_entry.id, _entry.innerHTML)) { //, _entry.innerHTML
|
||||
console.error("Failed to cache template " + _entry.id + " for js render!");
|
||||
|
|
|
@ -3,7 +3,15 @@
|
|||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"sourceMap": true
|
||||
"sourceMap": true,
|
||||
"plugins": [ /* ttypescript */
|
||||
{
|
||||
"transform": "../../build/trgen/ttsc_transformer.js",
|
||||
"type": "program",
|
||||
"target_file": "../generated/i18n.translation",
|
||||
"verbose": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"../js/workers"
|
||||
|
|
Loading…
Reference in New Issue