taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 9bde1c510f3522cfaf533d741cd96f8256035e75
parent 9c58a866775525817851280056322bca25b69c30
Author: Florian Dold <florian@dold.me>
Date:   Tue, 19 May 2026 14:25:00 +0200

pogen: use shared tsconfig, fix various issues

This package was previously compiled with less strict TypeScript
settings, leading to some missed typing issues in the code.

Diffstat:
Mpackages/pogen/bin/pogen | 2+-
Mpackages/pogen/package.json | 4+++-
Mpackages/pogen/src/potextract.ts | 68++++++++++++++++++++++++++++++++++++++++++--------------------------
Mpackages/pogen/tsconfig.json | 8++------
Mpnpm-lock.yaml | 8++++++++
5 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/packages/pogen/bin/pogen b/packages/pogen/bin/pogen @@ -1,2 +1,2 @@ #!/usr/bin/env -S node --trace-deprecation -require('../lib/pogen.js').main(); +(await import ('../lib/pogen.js')).main(); diff --git a/packages/pogen/package.json b/packages/pogen/package.json @@ -11,6 +11,7 @@ "test": "tsc && ava", "compile": "tsc" }, + "type": "module", "devDependencies": { "@types/gettext-parser": "^4.0.3", "ava": "^8.0.0", @@ -19,7 +20,8 @@ "dependencies": { "@types/node": "^18.11.17", "gettext-parser": "^8.0.0", - "glob": "^13.0.6" + "glob": "^13.0.6", + "tslib": "^2.8.1" }, "ava": { "files": [ diff --git a/packages/pogen/src/potextract.ts b/packages/pogen/src/potextract.ts @@ -17,9 +17,9 @@ /** * Imports. */ -import * as ts from "typescript"; import * as fs from "node:fs"; import * as path from "node:path"; +import * as ts from "typescript"; const DEFAULT_PO_HEADER = `# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER @@ -42,7 +42,7 @@ msgstr "" function wordwrap(str: string, width: number = 80): string[] { var regex = ".{1," + width + "}(\\s|$)|\\S+(\\s|$)"; - return str.match(RegExp(regex, "g")); + return str.match(RegExp(regex, "g")) ?? []; } function getTemplate(node: ts.Node): string { @@ -69,7 +69,7 @@ function getComment( node: ts.Node, ): string { let lc = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); - let lastComments: ts.CommentRange[]; + let lastComments: ts.CommentRange[] | undefined = undefined; for (let l = preLastTokLine; l < lastTokLine; l++) { let pos = ts.getPositionOfLineAndCharacter(sourceFile, l, 0); let comments = ts.getTrailingCommentRanges(sourceFile.text, pos); @@ -78,7 +78,7 @@ function getComment( } } if (!lastComments) { - return; + return ""; } let candidate = lastComments[lastComments.length - 1]; let candidateEndLine = ts.getLineAndCharacterOfPosition( @@ -86,7 +86,7 @@ function getComment( candidate.end, ).line; if (candidateEndLine != lc.line - 1) { - return; + return ""; } let text = sourceFile.text.slice(candidate.pos, candidate.end); switch (candidate.kind) { @@ -137,6 +137,7 @@ function getPath(node: ts.Node): { path: string[]; ctx: string } { ctx: str.text, }; } + break; } default: { // console.log("ASDASD", ts.SyntaxKind[node.kind], node); @@ -199,8 +200,11 @@ const SCREEN_INFO: ScreenInfo = { function formatScreenId( sourceFile: ts.SourceFile, outChunks: string[], - screenId: string, -) { + screenId: string | undefined, +): void { + if (!screenId) { + return; + } const screen = Number.parseInt(screenId, 10); if (!screen || Number.isNaN(screen)) { SCREEN_INFO.missing.add(sourceFile.fileName); @@ -255,23 +259,24 @@ function formatMsgLine(outChunks: string[], head: string, msg: string) { } } -function getJsxElementPath(node: ts.Node) { - let path; - let process = (childNode) => { +function getJsxElementPath(node: ts.Node): string[] { + let path: string[] | undefined = undefined; + let process = (childNode: ts.Node) => { switch (childNode.kind) { case ts.SyntaxKind.JsxOpeningElement: { let e = childNode as ts.JsxOpeningElement; - return (path = getPath(e.tagName).path); + path = getPath(e.tagName).path; + return path; } default: - break; + return undefined; } }; ts.forEachChild(node, process); - return path; + return path ?? []; } -function translateJsxExpression(node: ts.Expression, h) { +function translateJsxExpression(node: ts.Expression, h: number[]) { switch (node.kind) { case ts.SyntaxKind.StringLiteral: { let e = node as ts.StringLiteral; @@ -287,7 +292,7 @@ function trim(s: string) { } function getJsxAttribute(sour: ts.SourceFile, node: ts.Node) { - const result = {}; + const result: Record<string, any> = {}; ts.forEachChild(node, (childNode: ts.Node) => { switch (childNode.kind) { case ts.SyntaxKind.JsxOpeningElement: { @@ -309,9 +314,9 @@ function getJsxAttribute(sour: ts.SourceFile, node: ts.Node) { } function getJsxContent(node: ts.Node) { - let fragments = []; + let fragments: string[] = []; let holeNum = [1]; - let process = (childNode) => { + let process = (childNode: ts.Node) => { switch (childNode.kind) { case ts.SyntaxKind.JsxText: { let e = childNode as ts.JsxText; @@ -324,6 +329,7 @@ function getJsxContent(node: ts.Node) { t = t + " "; } fragments.push(t); + break; } case ts.SyntaxKind.JsxOpeningElement: break; @@ -333,7 +339,9 @@ function getJsxContent(node: ts.Node) { break; case ts.SyntaxKind.JsxExpression: { let e = childNode as ts.JsxExpression; - fragments.push(translateJsxExpression(e.expression, holeNum)); + if (!!e.expression) { + fragments.push(translateJsxExpression(e.expression, holeNum)); + } break; } case ts.SyntaxKind.JsxClosingElement: @@ -358,15 +366,16 @@ function getJsxContent(node: ts.Node) { return fragments.join("").trim().replace(/ +/g, " "); } -function getJsxSingular(node: ts.Node) { +function getJsxSingular(node: ts.Node): string | undefined { let res; - let process = (childNode) => { + let process = (childNode: ts.Node) => { switch (childNode.kind) { case ts.SyntaxKind.JsxElement: { let path = getJsxElementPath(childNode); if (arrayEq(path, ["i18n", "TranslateSingular"])) { res = getJsxContent(childNode); } + break; } default: break; @@ -376,15 +385,16 @@ function getJsxSingular(node: ts.Node) { return res; } -function getJsxPlural(node: ts.Node) { +function getJsxPlural(node: ts.Node): string | undefined { let res; - let process = (childNode) => { + let process = (childNode: ts.Node) => { switch (childNode.kind) { case ts.SyntaxKind.JsxElement: { let path = getJsxElementPath(childNode); if (arrayEq(path, ["i18n", "TranslatePlural"])) { res = getJsxContent(childNode); } + break; } default: break; @@ -395,10 +405,12 @@ function getJsxPlural(node: ts.Node) { } function searchScreenId(parents: ts.Node[], sourceFile: ts.SourceFile) { - var result = undefined; + var result: string | undefined = undefined; parents.forEach((parent) => { // console.log("parent => ", ts.SyntaxKind[parent.kind]); - if (result) return; + if (result) { + return; + } parent.forEachChild((node) => { // console.log(" children => ", ts.SyntaxKind[node.kind]); @@ -409,7 +421,7 @@ function searchScreenId(parents: ts.Node[], sourceFile: ts.SourceFile) { (d) => d.name.getText(sourceFile) === "TALER_SCREEN_ID", ); if (found) { - if (found.initializer.kind === ts.SyntaxKind.NumericLiteral) { + if (found?.initializer?.kind === ts.SyntaxKind.NumericLiteral) { const id = found.initializer.getText(sourceFile); result = id; } else { @@ -693,7 +705,7 @@ function searchIntoParents(directory: string, fileFlag: string) { return searchIntoParents(parent, fileFlag); } -export function potextract(searchPath:string = "./") { +export function potextract(searchPath: string = "./") { const configPath = ts.findConfigFile( searchPath, ts.sys.fileExists, @@ -716,6 +728,10 @@ export function potextract(searchPath:string = "./") { }, ); + if (!cmdline) { + throw Error("cound not parse command line"); + } + const prog = ts.createProgram({ options: cmdline.options, rootNames: cmdline.fileNames, diff --git a/packages/pogen/tsconfig.json b/packages/pogen/tsconfig.json @@ -1,12 +1,8 @@ { + "extends": "../../tsconfig.defaults.json", "compilerOptions": { - "module": "commonjs", - "target": "ES2020", - "noImplicitAny": false, "outDir": "lib", - "incremental": true, - "moduleResolution": "node", - "sourceMap": true, + "rootDir": "./src", "lib": ["ES2020"], "types": ["node"] }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml @@ -661,6 +661,9 @@ importers: glob: specifier: ^13.0.6 version: 13.0.6 + tslib: + specifier: ^2.8.1 + version: 2.8.1 devDependencies: '@types/gettext-parser': specifier: ^4.0.3 @@ -3785,6 +3788,9 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -7092,6 +7098,8 @@ snapshots: tslib@2.6.2: {} + tslib@2.8.1: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1