commit 4fca497be9a2dae7127aa928d03c1ced487092fc parent a2eedcd72f22aa526d3c0fc9d54b6e0442fabb8b Author: Florian Dold <dold@taler.net> Date: Fri, 31 Jul 2026 12:55:41 +0200 qa: fix the problems the trimmed lint configuration reports Mostly mechanical: keys on mapped elements, braces around case bodies that declare bindings, primitive type names, redundant regex escapes and dead statements. Diffstat:
113 files changed, 288 insertions(+), 329 deletions(-)
diff --git a/packages/idb-bridge/src/util/validateKeyPath.ts b/packages/idb-bridge/src/util/validateKeyPath.ts @@ -42,7 +42,12 @@ export const validateKeyPath = ( // https://mathiasbynens.be/demo/javascript-identifier-regex for ECMAScript 5.1 / Unicode v7.0.0, with // reserved words at beginning removed // tslint:disable-next-line max-line-length + // Taken verbatim from that page, so it is not ours to reformat: the + // redundant escapes and the surrogate pairs written out as separate + // ranges are how the generator emits it, and "fixing" either would mean + // hand-editing a table we cannot re-derive. const validIdentifierRegex = + // eslint-disable-next-line no-useless-escape, no-misleading-character-class /^(?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])(?:[\$0-9A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC])*$/; if (myKeyPath.length >= 1 && validIdentifierRegex.test(myKeyPath)) { return; diff --git a/packages/libeufin-bank-webui/src/pages/PaytoWireTransferForm.tsx b/packages/libeufin-bank-webui/src/pages/PaytoWireTransferForm.tsx @@ -394,6 +394,7 @@ export function PaytoWireTransferForm({ </label> { //FIXME: add QR support + // eslint-disable-next-line no-constant-binary-expression false && ( <label data-checked={inputType === "qr"} diff --git a/packages/libeufin-bank-webui/src/pages/SolveMFA.tsx b/packages/libeufin-bank-webui/src/pages/SolveMFA.tsx @@ -428,7 +428,7 @@ function SolveMFAChallenges({ )} </span> </h2> - {currentChallenge.challenges.map((challenge) => { + {currentChallenge.challenges.map((challenge, idx) => { const time = retransmission[challenge.challenge_id] ?? AbsoluteTime.now(); const alreadySent = !AbsoluteTime.isExpired(time); @@ -446,7 +446,7 @@ function SolveMFAChallenges({ : sendMessage.withArgs(challenge); return ( - <div class="rounded-xl border px-2 my-2"> + <div key={idx} class="rounded-xl border px-2 my-2"> <dl class="divide-y divide-gray-100"> <div class="px-4 py-2 sm:grid sm:gap-4 sm:px-0"> <dt class="text-sm font-medium leading-6 text-gray-900"> diff --git a/packages/libeufin-bank-webui/src/pages/WithdrawalQRCode.tsx b/packages/libeufin-bank-webui/src/pages/WithdrawalQRCode.tsx @@ -176,6 +176,8 @@ export function WithdrawalQRCode({ > <i18n.Translate>Close</i18n.Translate> </a> + {/* FIXME: kept until the wallet-ui hand-off is settled. */} + {/* eslint-disable-next-line no-constant-condition */} {origin === "from-wallet-ui" && false ? ( <a href={talerWithdrawUri} diff --git a/packages/libeufin-bank-webui/src/pages/account/ShowAccountDetails.tsx b/packages/libeufin-bank-webui/src/pages/account/ShowAccountDetails.tsx @@ -180,7 +180,6 @@ export function ShowAccountDetails({ const baseURL = url.href; const revenueURL = new URL(baseURL); revenueURL.username = account; - revenueURL.password; const ac = Paytos.fromString(result.body.payto_uri); const payto = ac.tag === "error" || !ac.value.targetType ? undefined : ac.value; diff --git a/packages/libeufin-bank-webui/src/utils.ts b/packages/libeufin-bank-webui/src/utils.ts @@ -332,7 +332,7 @@ function calculate_iban_checksum(str: string): number { return result; } -export const USERNAME_REGEX = /^[a-zA-Z0-9\-\.\_\~]*$/; +export const USERNAME_REGEX = /^[a-zA-Z0-9\-._~]*$/; // [a-zA-Z0-9\\-\\._~]+ export function validateTalerBank( account: string, diff --git a/packages/merchant-backend-ui/build.mjs b/packages/merchant-backend-ui/build.mjs @@ -20,7 +20,6 @@ import path from "node:path"; import fs from "node:fs"; import { execSync } from 'node:child_process'; -// eslint-disable-next-line no-undef const BASE = process.cwd(); const preact = path.join( diff --git a/packages/merchant-backend-ui/src/components/Application.tsx b/packages/merchant-backend-ui/src/components/Application.tsx @@ -19,8 +19,8 @@ * @author Sebastian Javier Marchano (sebasjm) */ import { ComponentChildren, h, VNode } from "preact"; -import { TranslationProvider } from "../context/translations"; -import { strings } from "../i18n/strings"; +import { TranslationProvider } from "../context/translations.js"; +import { strings } from "../i18n/strings.js"; interface Props { children: ComponentChildren; diff --git a/packages/merchant-backend-ui/src/context/translations.ts b/packages/merchant-backend-ui/src/context/translations.ts @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { i18n, setupI18n } from "../utils/i18n"; +import { i18n, setupI18n } from "../utils/i18n.js"; import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext } from "preact/hooks"; import { Locale } from "date-fns"; diff --git a/packages/merchant-backend-ui/src/pages/OfferRefund.examples.ts b/packages/merchant-backend-ui/src/pages/OfferRefund.examples.ts @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Props } from "./OfferRefund"; +import { Props } from "./OfferRefund.js"; export const exampleData: { [name: string]: Props } = { Simplest: { diff --git a/packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx b/packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx @@ -20,8 +20,8 @@ */ import { h, VNode, FunctionalComponent } from 'preact'; -import { createSVG } from '../components/QR'; -import { OfferRefund as TestedComponent } from './OfferRefund'; +import { createSVG } from '../components/QR.js'; +import { OfferRefund as TestedComponent } from './OfferRefund.js'; export default { diff --git a/packages/merchant-backend-ui/src/pages/OfferRefund.tsx b/packages/merchant-backend-ui/src/pages/OfferRefund.tsx @@ -21,13 +21,13 @@ import { Fragment, h, render, VNode } from "preact"; import { render as renderToString } from "preact-render-to-string"; import { useEffect } from "preact/hooks"; -import { Footer } from "../components/Footer"; -import { createSVG, QR } from "../components/QR"; +import { Footer } from "../components/Footer.js"; +import { createSVG, QR } from "../components/QR.js"; import "../css/pure-min.css"; import "../css/style.css"; -import { Page, QRPlaceholder, WalletLink } from "../styled"; -import { Application } from "../components/Application"; -import { useTranslationContext } from "../context/translations"; +import { Page, QRPlaceholder, WalletLink } from "../styled/index.js"; +import { Application } from "../components/Application.js"; +import { useTranslationContext } from "../context/translations.js"; /** * This page creates a refund offer QR code diff --git a/packages/merchant-backend-ui/src/pages/RequestPayment.examples.ts b/packages/merchant-backend-ui/src/pages/RequestPayment.examples.ts @@ -19,7 +19,7 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Props } from "./RequestPayment"; +import { Props } from "./RequestPayment.js"; export const exampleData: { [name: string]: Props } = { Simplest: { diff --git a/packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx b/packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx @@ -20,8 +20,8 @@ */ import { FunctionalComponent, h } from "preact"; -import { createSVG } from "../components/QR"; -import { RequestPayment as TestedComponent } from "./RequestPayment"; +import { createSVG } from "../components/QR.js"; +import { RequestPayment as TestedComponent } from "./RequestPayment.js"; export default { title: "RequestPayment", diff --git a/packages/merchant-backend-ui/src/pages/RequestPayment.tsx b/packages/merchant-backend-ui/src/pages/RequestPayment.tsx @@ -21,13 +21,13 @@ import { Fragment, h, render, VNode } from "preact"; import { render as renderToString } from "preact-render-to-string"; import { useEffect } from "preact/hooks"; -import { Footer } from "../components/Footer"; -import { createSVG, QR } from "../components/QR"; +import { Footer } from "../components/Footer.js"; +import { createSVG, QR } from "../components/QR.js"; import "../css/pure-min.css"; import "../css/style.css"; -import { Page, QRPlaceholder, WalletLink } from "../styled"; -import { Application } from "../components/Application"; -import { useTranslationContext } from "../context/translations"; +import { Page, QRPlaceholder, WalletLink } from "../styled/index.js"; +import { Application } from "../components/Application.js"; +import { useTranslationContext } from "../context/translations.js"; /** * This page creates a payment request QR code diff --git a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts @@ -19,8 +19,8 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { MerchantBackend } from '../declaration'; -import { Props } from './ShowOrderDetails'; +import { MerchantBackend } from '../declaration.js'; +import { Props } from './ShowOrderDetails.js'; const defaultContractTerms: MerchantBackend.ContractTerms = { diff --git a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx @@ -20,7 +20,7 @@ */ import { FunctionalComponent, h } from 'preact'; -import { ShowOrderDetails as TestedComponent } from './ShowOrderDetails'; +import { ShowOrderDetails as TestedComponent } from './ShowOrderDetails.js'; import { exampleData } from './ShowOrderDetails.examples'; export default { diff --git a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx @@ -22,14 +22,14 @@ import { format, formatDuration } from "date-fns"; import { intervalToDuration } from "date-fns/esm"; import { Fragment, h, render, VNode } from "preact"; import { render as renderToString } from "preact-render-to-string"; -import { Footer } from "../components/Footer"; +import { Footer } from "../components/Footer.js"; import "../css/pure-min.css"; import "../css/style.css"; import type { MerchantBackend } from "../declaration"; -import { Page, InfoBox, TableExpanded, TableSimple } from "../styled"; -import { TIME_DATE_FORMAT } from "../utils"; -import { Application } from "../components/Application"; -import { useTranslationContext } from "../context/translations"; +import { Page, InfoBox, TableExpanded, TableSimple } from "../styled/index.js"; +import { TIME_DATE_FORMAT } from "../utils.js"; +import { Application } from "../components/Application.js"; +import { useTranslationContext } from "../context/translations.js"; /** * This page creates a payment request QR code diff --git a/packages/merchant-backend-ui/src/render-examples.ts b/packages/merchant-backend-ui/src/render-examples.ts @@ -79,7 +79,6 @@ templateFiles.forEach((templateFile) => { // console.log(`- skipping ${testName}: no examples found`); // return; // } - // eslint-disable-next-line @typescript-eslint/no-var-requires // const pepe = `./${exampleFileName}.ts` // const { exampleData } = require(pepe); diff --git a/packages/pogen/src/po2ts.ts b/packages/pogen/src/po2ts.ts @@ -20,7 +20,7 @@ import * as gettextParser from "gettext-parser"; import * as fs from "node:fs"; -import glob = require("glob"); +import * as glob from "glob"; //types defined by the po2json library type Header = { diff --git a/packages/pogen/src/pogen.ts b/packages/pogen/src/pogen.ts @@ -1,7 +1,7 @@ import { potextract } from "./potextract.js"; import * as child_process from "child_process"; import * as fs from "node:fs"; -import glob = require("glob"); +import * as glob from "glob"; import { po2ts } from "./po2ts.js"; function usage(): never { diff --git a/packages/pogen/src/potextract.ts b/packages/pogen/src/potextract.ts @@ -49,7 +49,7 @@ function getTemplate(node: ts.Node): string { switch (node.kind) { case ts.SyntaxKind.FirstTemplateToken: return (<any>node).text; - case ts.SyntaxKind.TemplateExpression: + case ts.SyntaxKind.TemplateExpression: { let te = <ts.TemplateExpression>node; let textFragments = [te.head.text]; for (let tsp of te.templateSpans) { @@ -57,6 +57,7 @@ function getTemplate(node: ts.Node): string { textFragments.push(tsp.literal.text.replace(/%/g, "%%")); } return textFragments.join(""); + } default: return "(pogen.ts: unable to parse)"; } @@ -188,7 +189,7 @@ function processTaggedTemplateExpression( type ScreenInfo = { fileMap: Record<string, Set<string>>; - missing: Set<String>; + missing: Set<string>; maxId: number; }; const SCREEN_INFO: ScreenInfo = { @@ -346,7 +347,7 @@ function getJsxContent(node: ts.Node) { } case ts.SyntaxKind.JsxClosingElement: break; - default: + default: { console.log("unhandled node type: ", childNode.kind); let lc = ts.getLineAndCharacterOfPosition( childNode.getSourceFile(), @@ -360,6 +361,7 @@ function getJsxContent(node: ts.Node) { }`, ); break; + } } }; ts.forEachChild(node, process); @@ -455,7 +457,7 @@ function processNode( const { line } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); try { switch (node.kind) { - case ts.SyntaxKind.JsxElement: + case ts.SyntaxKind.JsxElement: { let path = getJsxElementPath(node); // <i18n.Translate>text</i18n.Translate> if (arrayEq(path, ["i18n", "Translate"])) { @@ -528,6 +530,7 @@ function processNode( } } break; + } case ts.SyntaxKind.CallExpression: { // might be i18n.plural(i18n[.X]`...`, i18n[.X]`...`) let ce = <ts.CallExpression>node; diff --git a/packages/taler-auditor-webui/src/InstanceRoutes.tsx b/packages/taler-auditor-webui/src/InstanceRoutes.tsx @@ -119,7 +119,7 @@ function getInstanceTitle(path: string): TestProps { return { title: `Operating status`, endpoint: "helper", entity: null }; case Paths.detail_view: return { title: `Inconsistencies`, endpoint: "helper", entity: null }; - case Paths.amount_arithmethic_inconsistency_list: + case Paths.amount_arithmethic_inconsistency_list: { let amountArithmeticInconsistency: AuditorBackend.AmountArithmeticInconsistency.ClassAmountArithmeticInconsistency = {} as AuditorBackend.AmountArithmeticInconsistency.ClassAmountArithmeticInconsistency; return { @@ -127,6 +127,7 @@ function getInstanceTitle(path: string): TestProps { endpoint: "amount-arithmetic-inconsistency", entity: amountArithmeticInconsistency, }; + } case Paths.bad_sig_losses_list: return { title: `Bad Sig Losses`, @@ -247,7 +248,7 @@ function getInstanceTitle(path: string): TestProps { endpoint: "row-minor-inconsistencies", entity: null, }; - case Paths.wire_format_inconsistency_list: + case Paths.wire_format_inconsistency_list: { let wireFormatInconsistency: AuditorBackend.WireFormatInconsistency.ClassWireFormatInconsistency = {} as AuditorBackend.WireFormatInconsistency.ClassWireFormatInconsistency; return { @@ -255,6 +256,7 @@ function getInstanceTitle(path: string): TestProps { endpoint: "wire-format-inconsistency", entity: wireFormatInconsistency, }; + } case Paths.wire_out_inconsistency_list: return { title: "Wire out inconsistencies", diff --git a/packages/taler-auditor-webui/src/paths/default/Table.tsx b/packages/taler-auditor-webui/src/paths/default/Table.tsx @@ -98,10 +98,10 @@ function Table({ data, onSuppress }: TableProps): VNode { <tbody> {data.map((key: Entity, value: string) => { return ( - <tr> - {Object.keys(data[0]).map((i: Entity) => { + <tr key={value}> + {Object.keys(data[0]).map((i: Entity, idx) => { return ( - <Fragment> + <Fragment key={idx}> <td>{key[i] == false ? "false" : key[i]}</td> </Fragment> ); diff --git a/packages/taler-auditor-webui/src/paths/finance/ListPage.tsx b/packages/taler-auditor-webui/src/paths/finance/ListPage.tsx @@ -70,7 +70,7 @@ export function ListPage(data: any): VNode { <b>Gain/Loss</b> </td> </tr> - {data["data"]["data"][0].map((x: any) => { + {data["data"]["data"][0].map((x: any, idx: number) => { const key = Object.keys(x.data)[0]; let value = Object.values(x.data)[0]; const paramName = @@ -88,7 +88,7 @@ export function ListPage(data: any): VNode { else value = Object.keys(value).length; return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{paramName}</td> <td class="has-text-right"> <p @@ -112,7 +112,7 @@ export function ListPage(data: any): VNode { ); } else { return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{paramName}</td> <td class="has-text-right"> <p @@ -199,7 +199,7 @@ export function ListPage(data: any): VNode { <b>Value</b> </td> </tr> - {balances.map((x: any) => { + {balances.map((x: any, idx: number) => { let key = x.balance_key; let balanceName = key[0].toUpperCase() + @@ -213,7 +213,7 @@ export function ListPage(data: any): VNode { if (coinBalances.includes(balanceName)) { let value = x.balance_value.replace(":", " "); return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{balanceName}</td> <td> <p>{value}</p> @@ -235,7 +235,7 @@ export function ListPage(data: any): VNode { <b>Value</b> </td> </tr> - {balances.map((x: any) => { + {balances.map((x: any, idx: number) => { let key = x.balance_key; let balanceName = key[0].toUpperCase() + @@ -249,7 +249,7 @@ export function ListPage(data: any): VNode { if (reserveBalances.includes(balanceName)) { let value = x.balance_value.replace(":", " "); return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{balanceName}</td> <td> <p>{value}</p> diff --git a/packages/taler-auditor-webui/src/paths/login/index.tsx b/packages/taler-auditor-webui/src/paths/login/index.tsx @@ -37,8 +37,6 @@ export function LoginPage(): VNode { const doLogin = useCallback( async function doLoginImpl() { const result = useBackendToken(); - if (!result.ok) { - } if (result.ok) { //TODO fixme const { token } = useBackendTokenContext(); diff --git a/packages/taler-auditor-webui/src/paths/operations/ListPage.tsx b/packages/taler-auditor-webui/src/paths/operations/ListPage.tsx @@ -46,7 +46,7 @@ export function ListPage(data: any): VNode { <b>Diagnostic</b> </td> </tr> - {data["data"]["data"][0].map((x: any) => { + {data["data"]["data"][0].map((x: any, idx: number) => { const key = Object.keys(x.data)[0]; let value = Object.values(x.data)[0]; console.log(value); @@ -60,7 +60,7 @@ export function ListPage(data: any): VNode { .join(" ") .slice(1, key.length); return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{paramName}</td> <td className="has-text-right"> <p diff --git a/packages/taler-auditor-webui/src/paths/security/ListPage.tsx b/packages/taler-auditor-webui/src/paths/security/ListPage.tsx @@ -43,7 +43,7 @@ export function ListPage(data: any): VNode { <b>Expiration dates</b> </td> </tr> - {data["data"]["data"][0].map((x: any) => { + {data["data"]["data"][0].map((x: any, idx: number) => { const key = Object.keys(x.data)[0]; let value = Object.values(x.data)[0]; if (value === undefined) value = 0; @@ -56,7 +56,7 @@ export function ListPage(data: any): VNode { .join(" ") .slice(1, key.length); return ( - <tr class="is-link"> + <tr key={idx} class="is-link"> <td>{paramName}</td> <td class="has-text-right"> <p diff --git a/packages/taler-exchange-aml-webui/src/hooks/officer.ts b/packages/taler-exchange-aml-webui/src/hooks/officer.ts @@ -116,7 +116,6 @@ export function useOfficer(): OfficerState { lib: { exchange: api }, } = useExchangeApiContext(); const [pref] = usePreferences(); - pref.keepSessionAfterReload; // dev account, is kept on reloaded. const sessionStorage = useLocalStorage(DEV_ACCOUNT_KEY); const session = useMemo(() => { diff --git a/packages/taler-exchange-aml-webui/src/pages/AccountDetails.tsx b/packages/taler-exchange-aml-webui/src/pages/AccountDetails.tsx @@ -61,12 +61,12 @@ export function ShowProperties(props: { } return ( <> - {keys.map((x) => { + {keys.map((x, idx) => { if (properties[x] == null) { return null; } return ( - <p> + <p key={idx}> {x}: {properties[x]} </p> ); @@ -408,9 +408,10 @@ export function AccountDetails({ <h1 class="text-base font-semibold leading-6 text-black"> <i18n.Translate>Current active measures</i18n.Translate> </h1> - {legistimizations.body.map((d) => { + {legistimizations.body.map((d, idx) => { return ( <ShowLegistimizationInfo + key={idx} since={AbsoluteTime.fromProtocolTimestamp(d.start_time)} completed={d.is_finished} legitimization={d.measures} diff --git a/packages/taler-exchange-aml-webui/src/pages/AccountList.tsx b/packages/taler-exchange-aml-webui/src/pages/AccountList.tsx @@ -378,7 +378,7 @@ export function AccountList({ const paramsDesc = Object.entries(uri.params).map( ([name, value]) => { return ( - <div> + <div key={name}> {name}: {value} </div> ); diff --git a/packages/taler-exchange-aml-webui/src/pages/Search.tsx b/packages/taler-exchange-aml-webui/src/pages/Search.tsx @@ -115,7 +115,7 @@ export function Search({ return <WalletForm onSearch={setPayto} />; } default: { - assertUnreachable(paytoForm.status.result.paytoType); + return assertUnreachable(paytoForm.status.result.paytoType); } } })()} @@ -185,7 +185,7 @@ function ShowResult({ </i18n.Translate> ); default: - assertUnreachable(d.case); + return assertUnreachable(d.case); } }} /> @@ -639,7 +639,7 @@ function translatePaytoErrorResult( case PaytoType.Void: return i18n.str`Void address is missing`; default: - assertUnreachable(tt); + return assertUnreachable(tt); } } case PaytoParseError.INVALID_TARGET_PATH: { @@ -662,7 +662,7 @@ function translatePaytoErrorResult( i18n, )}`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } case PaytoType.TalerBank: { @@ -672,7 +672,7 @@ function translatePaytoErrorResult( case 1: return i18n.str`Invalid account`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } case PaytoType.TalerReserve: { @@ -685,7 +685,7 @@ function translatePaytoErrorResult( i18n, )}`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } case PaytoType.TalerReserveHttp: { @@ -698,7 +698,7 @@ function translatePaytoErrorResult( i18n, )}`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } case PaytoType.Ethereum: { @@ -706,7 +706,7 @@ function translatePaytoErrorResult( case 0: return i18n.str`Invalid address`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } case PaytoType.Cyclos: { @@ -714,11 +714,11 @@ function translatePaytoErrorResult( case 0: return i18n.str`Invalid host`; default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } default: - assertUnreachable(result.detail); + return assertUnreachable(result.detail); } } } diff --git a/packages/taler-exchange-aml-webui/src/pages/decision/Measures.tsx b/packages/taler-exchange-aml-webui/src/pages/decision/Measures.tsx @@ -109,7 +109,6 @@ export function Measures(): VNode { {!allMeasures.length ? undefined : ( <ActiveMeasureForm editMeasure={(template) => { - template.name!; setAddMeasure({ isNew: true, template, diff --git a/packages/taler-exchange-kyc-webui/src/pages/Start.tsx b/packages/taler-exchange-kyc-webui/src/pages/Start.tsx @@ -122,6 +122,7 @@ function ShowReqList({ {requirements.map((req, idx) => { return ( <RequirementRow + key={idx} requirement={req} onFormSelected={() => { onFormSelected(req); diff --git a/packages/taler-harness/src/harness/environments.ts b/packages/taler-harness/src/harness/environments.ts @@ -1305,7 +1305,7 @@ export async function postAmlDecision( newRules: LegitimizationRuleSet; newMeasures?: string; properties?: AccountProperties; - attributes?: Object; + attributes?: object; attributes_expiration?: TalerProtocolTimestamp; events?: string[]; }, diff --git a/packages/taler-harness/src/harness/faultInjection.ts b/packages/taler-harness/src/harness/faultInjection.ts @@ -92,7 +92,7 @@ export class FaultProxy { const faultReqContext: FaultInjectionRequestContext = { dropRequest: false, - method: req.method!!, + method: req.method!, requestHeaders: req.headers, requestUrl, requestBody: requestBuffer, @@ -165,7 +165,7 @@ export class FaultProxy { dropResponse: false, responseBody: responseBuffer, responseHeaders: proxyResp.headers, - statusCode: proxyResp.statusCode!!, + statusCode: proxyResp.statusCode!, }; for (const faultSpec of this.currentFaultSpecs) { const modResponse = faultSpec.modifyResponse; diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts @@ -199,7 +199,7 @@ export async function sh( function shellescape(args: string[]) { const ret = args.map((s) => { - if (/[^A-Za-z0-9_\/:=-]/.test(s)) { + if (/[^A-Za-z0-9_/:=-]/.test(s)) { s = "'" + s.replace(/'/g, "'\\''") + "'"; s = s.replace(/^(?:'')+/g, "").replace(/\\'''/g, "\\'"); } @@ -2711,7 +2711,6 @@ export class MerchantService implements MerchantServiceInterface { headers, }); await expectSuccessResponseOrThrow(resp); - this.configFilename; const merchantApi = new TalerMerchantInstanceHttpClient( this.makeInstanceBaseUrl(instanceConfig.id), ); diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts @@ -1850,7 +1850,7 @@ talerHarnessCli.subcommand("tvgcheck", "tvgcheck").action(async (args) => { continue; } if (inBlindSigningSection) { - const m = line.match(/ (\w+) (\w+)/); + const m = line.match(/ {2}(\w+) (\w+)/); if (!m) { console.log("bad format"); process.exit(2); diff --git a/packages/taler-harness/src/integrationtests/test-kyc-amp-failure.ts b/packages/taler-harness/src/integrationtests/test-kyc-amp-failure.ts @@ -59,8 +59,6 @@ function adjustExchangeConfig(config: Configuration) { "command", "taler-harness aml-program run-program --name fail", ); - - config.setString; } /** diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-external.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-external.ts @@ -59,7 +59,7 @@ export async function runWithdrawalExternalTest(t: GlobalTestState) { const acceptResp = await walletClient.call( WalletApiOperation.AcceptBankIntegratedWithdrawal, { - exchangeBaseUrl: detResp.defaultExchangeBaseUrl!!, + exchangeBaseUrl: detResp.defaultExchangeBaseUrl!, talerWithdrawUri, }, ); diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -568,7 +568,7 @@ function purgeSharedTestEnvironment() { logger.warn("could not list available postgres databases"); return; } - if (psqlRes.output[1]!!.indexOf("taler-integrationtest-shared") >= 0) { + if (psqlRes.output[1]!.indexOf("taler-integrationtest-shared") >= 0) { const dropRes = spawnSync("dropdb", ["taler-integrationtest-shared"], { encoding: "utf-8", }); diff --git a/packages/taler-merchant-webui/src/components/SolveMFA.tsx b/packages/taler-merchant-webui/src/components/SolveMFA.tsx @@ -365,7 +365,7 @@ function SolveChallenge({ </ConfirmModal> ); } -export function SolveChallengeDialog({}: {}): VNode { +export function SolveChallengeDialog(_props: {}): VNode { const mfa = useMerchantChallengeHandlerContext(); const { i18n } = useTranslationContext(); if (!mfa.pending) return <Fragment />; @@ -566,6 +566,7 @@ function SolveMFAChallenges({ {requirement.challenges.map((challenge, idx) => { return ( <label + key={idx} class="radio" style={{ display: "flex", margin: 0, marginTop: 16 }} > diff --git a/packages/taler-merchant-webui/src/components/form/InputCode.tsx b/packages/taler-merchant-webui/src/components/form/InputCode.tsx @@ -107,7 +107,7 @@ export function InputCode<T>({ const prevHaveDash = dashesIndex.indexOf(idx - 1) !== -1; const haveDash = dashesIndex.indexOf(idx) !== -1; return ( - <Fragment> + <Fragment key={idx}> <input id={String(idx)} {...(inputExtra as any)} diff --git a/packages/taler-merchant-webui/src/components/menu/SideBar.tsx b/packages/taler-merchant-webui/src/components/menu/SideBar.tsx @@ -110,8 +110,10 @@ export function Sidebar({ mobile }: Props): VNode { switchCurrency(ev.currentTarget.value); }} > - {cList.map((c) => ( - <option selected={c === currency?.id}>{c}</option> + {cList.map((c, idx) => ( + <option key={idx} selected={c === currency?.id}> + {c} + </option> ))} </select> </div> diff --git a/packages/taler-merchant-webui/src/hooks/exchanges.ts b/packages/taler-merchant-webui/src/hooks/exchanges.ts @@ -35,7 +35,7 @@ export function revalidateExchanges() { export function useBackendExchanges() { const { lib } = useSessionContext(); - async function fetcher([]: [AccessToken, string]) { + async function fetcher(_args: [AccessToken, string]) { const list = await lib.instance.listExchanges(); if (list.type === "ok") { list.body.exchanges.sort(importantFirst); diff --git a/packages/taler-merchant-webui/src/hooks/testing.tsx b/packages/taler-merchant-webui/src/hooks/testing.tsx @@ -56,7 +56,7 @@ export class ApiMockEnvironment extends MockEnvironment { } mockApiIfNeeded(): void { - null; // do nothing + // do nothing } public buildTestingContext(): FunctionalComponent<{ diff --git a/packages/taler-merchant-webui/src/lang.ts b/packages/taler-merchant-webui/src/lang.ts @@ -79,7 +79,7 @@ msgstr "" #: src/Application.tsx:230 #, c-format -msgid "Supported version \"%1$s\", server version \"%2$s\"." +msgid "Supported version "%1$s", server version "%2$s"." msgstr "" `; const msgs = Object.entries( diff --git a/packages/taler-merchant-webui/src/paths/instance/accounts/create/index.tsx b/packages/taler-merchant-webui/src/paths/instance/accounts/create/index.tsx @@ -93,39 +93,34 @@ export async function testRevenueAPI( } : undefined; - try { - const config = await api.getConfig(auth); + const config = await api.getConfig(auth); - if (config.type === "fail") { - return config; - } + if (config.type === "fail") { + return config; + } - const resp = await api.getHistory(auth); - if (resp.type === "fail") { - return resp; - } + const resp = await api.getHistory(auth); + if (resp.type === "fail") { + return resp; + } - if (!resp.body.credit_account) { - return { - type: "fail" as const, - case: TestRevenueErrorType.CANT_VALIDATE, - detail: undefined, - response: dummyHttpResponse, - }; - } - const str = resp.body.credit_account as Paytos.FullPaytoString; - const uri = Paytos.fromString(str); - if (uri.tag === "error") { - return { - type: "fail" as const, - case: TestRevenueErrorType.BAD_PAYTO, - detail: undefined, - response: dummyHttpResponse, - }; - } - return opFixedSuccess(dummyHttpResponse, uri.value); - } catch (err) { - // FIXME: should we return some other error code here? - throw err; + if (!resp.body.credit_account) { + return { + type: "fail" as const, + case: TestRevenueErrorType.CANT_VALIDATE, + detail: undefined, + response: dummyHttpResponse, + }; + } + const str = resp.body.credit_account as Paytos.FullPaytoString; + const uri = Paytos.fromString(str); + if (uri.tag === "error") { + return { + type: "fail" as const, + case: TestRevenueErrorType.BAD_PAYTO, + detail: undefined, + response: dummyHttpResponse, + }; } + return opFixedSuccess(dummyHttpResponse, uri.value); } diff --git a/packages/taler-merchant-webui/src/paths/instance/kyc/list/index.tsx b/packages/taler-merchant-webui/src/paths/instance/kyc/list/index.tsx @@ -125,7 +125,7 @@ function ShowInstructionForKycRedirect({ const { i18n } = useTranslationContext(); const [{ showDebugInfo }] = useCommonPreferences(); switch (e.status) { - case TalerMerchantApi.MerchantAccountKycStatus.KYC_WIRE_REQUIRED: + case TalerMerchantApi.MerchantAccountKycStatus.KYC_WIRE_REQUIRED: { const uri = Paytos.fromString(e.payto_uri); if (uri.tag === "error") { return ( @@ -155,6 +155,7 @@ function ShowInstructionForKycRedirect({ wireAccountHash={e.h_wire} /> ); + } case TalerMerchantApi.MerchantAccountKycStatus.NO_EXCHANGE_KEY: { return ( <ConfirmModal diff --git a/packages/taler-merchant-webui/src/paths/instance/orders/create/CreatePage.tsx b/packages/taler-merchant-webui/src/paths/instance/orders/create/CreatePage.tsx @@ -1251,7 +1251,7 @@ export function RenderChoices({ return prev; }, {} as TokenCount); const tOutput = (c.outputs ?? []) - .map((i) => { + .map((i, idx) => { switch (i.type) { case OrderOutputType.Token: return i.token_family_slug; @@ -1269,7 +1269,7 @@ export function RenderChoices({ return prev; }, {} as TokenCount); return ( - <tr> + <tr key={idx}> <td> <RenderAmountBulma value={Amounts.parseOrThrow(c.amount)} diff --git a/packages/taler-merchant-webui/src/paths/instance/statistics/list/index.tsx b/packages/taler-merchant-webui/src/paths/instance/statistics/list/index.tsx @@ -73,7 +73,7 @@ export type RelevantTimeUnit = | "quarter" | "year"; -export default function Statistics({}: Props): VNode { +export default function Statistics(_props: Props): VNode { const lastMonthAbs = AbsoluteTime.subtractDuraction( AbsoluteTime.now(), Duration.fromSpec({ months: 1 }), diff --git a/packages/taler-merchant-webui/src/paths/instance/update/DeletePage.tsx b/packages/taler-merchant-webui/src/paths/instance/update/DeletePage.tsx @@ -84,7 +84,7 @@ export function DeletePage({ instanceId, onBack, onDeleted }: Props): VNode { }); return resp; }, - !session.token ? undefined : [session.token, form.purge!!, []], + !session.token ? undefined : [session.token, form.purge!, []], ); remove.onSuccess = onDeleted; diff --git a/packages/taler-merchant-webui/src/utils/constants.ts b/packages/taler-merchant-webui/src/utils/constants.ts @@ -21,7 +21,7 @@ //https://tools.ietf.org/html/rfc8905 export const PAYTO_REGEX = - /^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-\.\~\(\)@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-\.\~\(\)@_%:!$'*+,;=]*&?)*$/; + /^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-.~()@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-.~()@_%:!$'*+,;=]*&?)*$/; export const PAYTO_WIRE_METHOD_LOOKUP = /payto:\/\/([a-zA-Z][a-zA-Z0-9-.]+)\/.*/; @@ -33,7 +33,7 @@ export const CROCKFORD_BASE32_REGEX = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+[*~$=U]*$/; export const URL_REGEX = - /^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/; + /^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w.-]+)(?::(\d+))?)\/$/; const PAGINATED_LIST_SIZE = 20; // when doing paginated request, ask for one more diff --git a/packages/taler-util/src/codec.ts b/packages/taler-util/src/codec.ts @@ -21,8 +21,6 @@ import { Logger } from "./logging.js"; * Type-safe codecs for converting from/to JSON. */ -/* eslint-disable @typescript-eslint/ban-types */ - const logger = new Logger("codec.ts"); /** diff --git a/packages/taler-util/src/http-client/bank-core.ts b/packages/taler-util/src/http-client/bank-core.ts @@ -1030,7 +1030,7 @@ export class TalerCoreBankHttpClient { return opUnknownHttpFailure(resp, details); } } - case HttpStatusCode.NotImplemented: + case HttpStatusCode.NotImplemented: { const details = await readTalerErrorResponse(resp); switch (details.code) { case TalerErrorCode.BANK_TAN_CHANNEL_NOT_SUPPORTED: @@ -1038,6 +1038,7 @@ export class TalerCoreBankHttpClient { default: return opKnownHttpFailure(resp.status, resp); } + } default: return opUnknownHttpFailure(resp); } diff --git a/packages/taler-util/src/http-client/donau-client.ts b/packages/taler-util/src/http-client/donau-client.ts @@ -30,7 +30,8 @@ import { opUnknownHttpFailure, } from "../operation.js"; -import { AccessToken, Codec, codecForAny } from "../index.js"; +import { Codec, codecForAny } from "../codec.js"; +import { AccessToken } from "../types-taler-common.js"; import { BlindedDonationReceiptSignatures, Charities, @@ -103,10 +104,11 @@ export class DonauHttpClient { method: "GET", }); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { const buffer = await resp.bytes(); const uintar = new Uint8Array(buffer); return opFixedSuccess(resp, uintar); + } case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts @@ -133,20 +133,15 @@ import { pathSegment, } from "./utils.js"; -import { - AmountJson, - Amounts, - CancellationToken, - Duration, - Logger, - LongpollQueue, - PaytoHash, - TalerErrorCode, - opKnownFailureWithBody, - opKnownTalerFailure, - signAmlDecision, - signAmlQuery, -} from "../index.js"; +import { CancellationToken } from "../CancellationToken.js"; +import { AmountJson, Amounts } from "../amounts.js"; +import { Logger } from "../logging.js"; +import { LongpollQueue } from "../longpoll-queue.js"; +import { opKnownFailureWithBody, opKnownTalerFailure } from "../operation.js"; +import { PaytoHash } from "../payto.js"; +import { TalerErrorCode } from "../taler-error-codes.js"; +import { signAmlDecision, signAmlQuery } from "../taler-signatures.js"; +import { Duration } from "../time.js"; import { AbsoluteTime } from "../time.js"; import { EmptyObject } from "../types-taler-wallet.js"; @@ -270,10 +265,11 @@ export class TalerExchangeHttpClient { async getSeed() { const resp = await this.fetch("seed"); switch (resp.status) { - case HttpStatusCode.Ok: + case HttpStatusCode.Ok: { const buffer = await resp.bytes(); const uintar = new Uint8Array(buffer); return opFixedSuccess(resp, uintar); + } case HttpStatusCode.NotFound: return opKnownHttpFailure(resp.status, resp); default: diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts @@ -349,7 +349,7 @@ export namespace Paytos { /** * @param str */ - export function parseEthereumAddress(str: String): EthAddrString | undefined { + export function parseEthereumAddress(str: string): EthAddrString | undefined { if (!str) { return undefined; } diff --git a/packages/taler-util/src/performance.ts b/packages/taler-util/src/performance.ts @@ -22,7 +22,7 @@ /** * Imports. */ -import { assertUnreachable } from "./index.js"; +import { assertUnreachable } from "./errors.js"; import { ObservabilityEvent, ObservabilityEventType } from "./notifications.js"; export enum PerformanceStatType { @@ -205,7 +205,7 @@ export namespace PerformanceTable { const limited: PerformanceTable = {}; for (const k of Object.keys(tab)) { const key = k as keyof typeof tab; - limited[key] = tab[key]!!.slice(0, n); + limited[key] = tab[key]!.slice(0, n); } return limited; } @@ -222,13 +222,13 @@ export namespace PerformanceTable { return; } - const index = tab[stat.type]!!.findIndex((el) => + const index = tab[stat.type]!.findIndex((el) => PerformanceStat.equals(el, stat), ); if (index === -1) { tab[stat.type]?.push(stat); } else { - const existing = tab[stat.type]!![index]; + const existing = tab[stat.type]![index]; existing.maxDurationMs = Math.max( existing.maxDurationMs, stat.maxDurationMs, @@ -243,7 +243,7 @@ export namespace PerformanceTable { existing.avgDurationMs = Math.floor( existing.totalDurationMs / existing.count, ); - tab[stat.type]!![index] = existing; + tab[stat.type]![index] = existing; } } @@ -253,7 +253,7 @@ export namespace PerformanceTable { function sort(tab: PerformanceTable) { for (const k of Object.keys(tab)) { const key = k as keyof typeof tab; - tab[key]!!.sort((a, b) => b.avgDurationMs - a.avgDurationMs); + tab[key]!.sort((a, b) => b.avgDurationMs - a.avgDurationMs); } } diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts @@ -843,10 +843,10 @@ function parseRestore( }); } - let isHttp = false; + const isHttp = url.startsWith("http://"); const withoutScheme = url.startsWith("https://") ? url.substring(8) - : (isHttp = url.startsWith("http://")) + : isHttp ? url.substring(7) : url; @@ -1178,7 +1178,6 @@ function encodeUriSegment(s: string): string { // Tab, LF and CR are among them because the URL parser removes them before // parsing, which would otherwise turn "..\t" back into a dot segment. return s.replace( - // eslint-disable-next-line no-control-regex /[%/?#\t\n\r]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`, ); diff --git a/packages/taler-util/src/twrpc-impl.node.ts b/packages/taler-util/src/twrpc-impl.node.ts @@ -83,6 +83,8 @@ export async function connectRpc<T>(args: RpcConnectArgs<T>): Promise<T> { if (strippedLine == "%message") { parsingBody = "message"; } else if (strippedLine == "%hello-from-server") { + // Recognised and ignored: the greeting carries no payload, but + // it must not fall through to the unknown-request warning. } else if (strippedLine.startsWith("%error:")) { client.end(); res.onDisconnect(); diff --git a/packages/taler-util/src/types-taler-challenger.ts b/packages/taler-util/src/types-taler-challenger.ts @@ -123,7 +123,7 @@ export interface ChallengeCreateResponse { attempts_left: Integer; // the address that is being validated, might be shown or not - address: Object; + address: object; // true if we just retransmitted the challenge, false if we sent a // challenge recently and thus refused to transmit it again this time; @@ -194,7 +194,7 @@ export interface ChallengerInfoResponse { // Address that was validated. // Key-value pairs, details depend on the // address_type. - address: Object; + address: object; // Type of the address. address_type: string; diff --git a/packages/taler-util/src/types-taler-exchange.ts b/packages/taler-util/src/types-taler-exchange.ts @@ -1767,7 +1767,7 @@ export interface MeasureInformation { prog_name?: string; // Context for the check. Optional. - context?: Object; + context?: object; // Operation that this measure relates to. // NULL if unknown. Useful as a hint to the @@ -1867,7 +1867,7 @@ export interface KycDetail { // The collected KYC data. NULL if the attribute data could not // be decrypted (internal error of the exchange, likely the // attribute key was changed). - attributes?: Object; + attributes?: object; // Time when the KYC data was collected collection_time: Timestamp; @@ -2122,7 +2122,7 @@ export interface KycRequirementInformation { // Object with arbitrary additional context, completely depends on // the specific form. - context?: Object; + context?: object; // Map from IETF BCP 47 language tags to localized // description texts. @@ -2365,7 +2365,7 @@ export interface AmlDecisionRequest { // The object *must* contain high-entropy salt, // as the hash of the attributes will be // stored in plain text. - attributes?: Object; + attributes?: object; // Expiration timestamp of the attributes. // Mandatory if attributes are present. diff --git a/packages/taler-util/src/types-taler-kyc-aml.ts b/packages/taler-util/src/types-taler-kyc-aml.ts @@ -15,15 +15,17 @@ */ import { - AccountProperties, - buildCodecForObject, Codec, - codecForAccountProperties, + buildCodecForObject, codecForAny, codecForList, codecOptional, +} from "./codec.js"; +import { + AccountProperties, LegitimizationRuleSet, -} from "./index.js"; + codecForAccountProperties, +} from "./types-taler-exchange.js"; import { Timestamp } from "./types-taler-common.js"; // https://docs.taler.net/taler-kyc-manual.html#implementing-your-own-aml-programs @@ -128,7 +130,7 @@ export interface AmlHistoryEntry { decider_pub: string; // Properties associated with the account by the decision. - properties: Object; + properties: object; // New set of legitimization rules that was put in place. new_rules: LegitimizationRuleSet; @@ -168,7 +170,7 @@ export interface KycHistoryEntry { // The collected KYC data. // NULL if the attribute data could not // be decrypted or was not yet collected. - attributes?: Object; + attributes?: object; // Time when the KYC data was collected collection_time: Timestamp; diff --git a/packages/taler-util/src/types-taler-prepared-transfer.ts b/packages/taler-util/src/types-taler-prepared-transfer.ts @@ -29,7 +29,6 @@ import { codecForStringURL, codecOptional, } from "./codec.js"; -import { TalerPreparedTransferApi } from "./index.js"; import { codecForTimestamp, TalerProtocolTimestamp } from "./time.js"; import { AmountString, @@ -146,7 +145,7 @@ export interface Unregistration { } export const codeForSubjectFormat = - (): Codec<TalerPreparedTransferApi.SubjectFormat> => + (): Codec<SubjectFormat> => codecForEither( codecForConstString("SIMPLE"), codecForConstString("URI"), @@ -154,8 +153,8 @@ export const codeForSubjectFormat = ); export const codecForPreparedTransferConfig = - (): Codec<TalerPreparedTransferApi.PreparedTransferConfig> => - buildCodecForObject<TalerPreparedTransferApi.PreparedTransferConfig>() + (): Codec<PreparedTransferConfig> => + buildCodecForObject<PreparedTransferConfig>() .property("currency", codecForString()) .property("implementation", codecOptional(codecForString())) .property("name", codecForConstString("taler-prepared-transfer")) @@ -164,8 +163,8 @@ export const codecForPreparedTransferConfig = .build("TalerPreparedTransferApi.PreparedTransferConfig"); export const codecForRegistrationRequest = - (): Codec<TalerPreparedTransferApi.RegistrationRequest> => - buildCodecForObject<TalerPreparedTransferApi.RegistrationRequest>() + (): Codec<RegistrationRequest> => + buildCodecForObject<RegistrationRequest>() .property("credit_amount", codecForAmountString()) .property( "type", @@ -183,8 +182,8 @@ export const codecForRegistrationRequest = .build("TalerWireGatewayApi.RegistrationRequest"); export const codecForTransferSubject = - (): Codec<TalerPreparedTransferApi.TransferSubject> => - buildCodecForUnion<TalerPreparedTransferApi.TransferSubject>() + (): Codec<TransferSubject> => + buildCodecForUnion<TransferSubject>() .discriminateOn("type") .alternative("SIMPLE", codecForSimpleSubject()) .alternative("URI", codecForUriSubject()) @@ -192,39 +191,39 @@ export const codecForTransferSubject = .build("TalerPreparedTransferApi.TransferSubject"); export const codecForSimpleSubject = - (): Codec<TalerPreparedTransferApi.SimpleSubject> => - buildCodecForObject<TalerPreparedTransferApi.SimpleSubject>() + (): Codec<SimpleSubject> => + buildCodecForObject<SimpleSubject>() .property("type", codecForConstString("SIMPLE")) .property("credit_amount", codecForAmountString()) .property("subject", codecForString()) .build("TalerPreparedTransferApi.SimpleSubject"); export const codecForUriSubject = - (): Codec<TalerPreparedTransferApi.UriSubject> => - buildCodecForObject<TalerPreparedTransferApi.UriSubject>() + (): Codec<UriSubject> => + buildCodecForObject<UriSubject>() .property("type", codecForConstString("URI")) .property("credit_amount", codecForAmountString()) .property("uri", codecForStringURL()) .build("TalerPreparedTransferApi.UriSubject"); export const codecForSwissQrBillSubject = - (): Codec<TalerPreparedTransferApi.SwissQrBillSubject> => - buildCodecForObject<TalerPreparedTransferApi.SwissQrBillSubject>() + (): Codec<SwissQrBillSubject> => + buildCodecForObject<SwissQrBillSubject>() .property("type", codecForConstString("CH_QR_BILL")) .property("credit_amount", codecForAmountString()) .property("qr_reference_number", codecForString()) .build("TalerPreparedTransferApi.SwissQrBillSubject"); export const codecForRegistrationResponse = - (): Codec<TalerPreparedTransferApi.RegistrationResponse> => - buildCodecForObject<TalerPreparedTransferApi.RegistrationResponse>() + (): Codec<RegistrationResponse> => + buildCodecForObject<RegistrationResponse>() .property("subjects", codecForList(codecForTransferSubject())) .property("expiration", codecForTimestamp) .build("TalerWireGatewayApi.RegistrationResponse"); export const codecForUnregistration = - (): Codec<TalerPreparedTransferApi.Unregistration> => - buildCodecForObject<TalerPreparedTransferApi.Unregistration>() + (): Codec<Unregistration> => + buildCodecForObject<Unregistration>() .property("timestamp", codecForTimestamp) .property("authorization_pub", codecForEddsaPublicKey()) .property("authorization_sig", codecForEddsaSignature()) diff --git a/packages/taler-util/src/types-taler-wire-gateway.ts b/packages/taler-util/src/types-taler-wire-gateway.ts @@ -32,9 +32,8 @@ import { } from "./codec.js"; import { EddsaSignature, - TalerWireGatewayApi, codecForEddsaSignature, -} from "./index.js"; +} from "./types-taler-common.js"; import { PaytoString, codecForPaytoString } from "./payto.js"; import { codecForTimestamp } from "./time.js"; import { @@ -374,8 +373,8 @@ export interface BankWireTransferStatus { } export const codecForWireConfigResponse = - (): Codec<TalerWireGatewayApi.WireConfig> => - buildCodecForObject<TalerWireGatewayApi.WireConfig>() + (): Codec<WireConfig> => + buildCodecForObject<WireConfig>() .property("currency", codecForString()) .property("implementation", codecOptional(codecForString())) .property("name", codecForConstString("taler-wire-gateway")) @@ -384,15 +383,15 @@ export const codecForWireConfigResponse = .build("TalerWireGatewayApi.WireConfig"); export const codecForTransferResponse = - (): Codec<TalerWireGatewayApi.TransferResponse> => - buildCodecForObject<TalerWireGatewayApi.TransferResponse>() + (): Codec<TransferResponse> => + buildCodecForObject<TransferResponse>() .property("row_id", codecForNumber()) .property("timestamp", codecForTimestamp) .build("TalerWireGatewayApi.TransferResponse"); export const codecForIncomingHistory = - (): Codec<TalerWireGatewayApi.IncomingHistory> => - buildCodecForObject<TalerWireGatewayApi.IncomingHistory>() + (): Codec<IncomingHistory> => + buildCodecForObject<IncomingHistory>() .property("credit_account", codecOptional(codecForPaytoString())) .property( "incoming_transactions", @@ -401,8 +400,8 @@ export const codecForIncomingHistory = .build("TalerWireGatewayApi.IncomingHistory"); export const codecForIncomingBankTransaction = - (): Codec<TalerWireGatewayApi.IncomingBankTransaction> => - buildCodecForUnion<TalerWireGatewayApi.IncomingBankTransaction>() + (): Codec<IncomingBankTransaction> => + buildCodecForUnion<IncomingBankTransaction>() .discriminateOn("type") .alternative("RESERVE", codecForIncomingReserveTransaction()) .alternative("KYCAUTH", codecForIncomingKycAuthTransaction()) @@ -410,8 +409,8 @@ export const codecForIncomingBankTransaction = .build("TalerWireGatewayApi.IncomingBankTransaction"); export const codecForIncomingReserveTransaction = - (): Codec<TalerWireGatewayApi.IncomingReserveTransaction> => - buildCodecForObject<TalerWireGatewayApi.IncomingReserveTransaction>() + (): Codec<IncomingReserveTransaction> => + buildCodecForObject<IncomingReserveTransaction>() .property("amount", codecForAmountString()) .property("date", codecForTimestamp) .property("debit_account", codecForPaytoString()) @@ -423,8 +422,8 @@ export const codecForIncomingReserveTransaction = .build("TalerWireGatewayApi.IncomingReserveTransaction"); export const codecForIncomingKycAuthTransaction = - (): Codec<TalerWireGatewayApi.IncomingKycAuthTransaction> => - buildCodecForObject<TalerWireGatewayApi.IncomingKycAuthTransaction>() + (): Codec<IncomingKycAuthTransaction> => + buildCodecForObject<IncomingKycAuthTransaction>() .property("amount", codecForAmountString()) .property("date", codecForTimestamp) .property("debit_account", codecForPaytoString()) @@ -436,8 +435,8 @@ export const codecForIncomingKycAuthTransaction = .build("TalerWireGatewayApi.IncomingKycAuthTransaction"); export const codecForIncomingWadTransaction = - (): Codec<TalerWireGatewayApi.IncomingWadTransaction> => - buildCodecForObject<TalerWireGatewayApi.IncomingWadTransaction>() + (): Codec<IncomingWadTransaction> => + buildCodecForObject<IncomingWadTransaction>() .property("amount", codecForAmountString()) .property("date", codecForTimestamp) .property("debit_account", codecForPaytoString()) @@ -450,8 +449,8 @@ export const codecForIncomingWadTransaction = .build("TalerWireGatewayApi.IncomingWadTransaction"); export const codecForOutgoingHistory = - (): Codec<TalerWireGatewayApi.OutgoingHistory> => - buildCodecForObject<TalerWireGatewayApi.OutgoingHistory>() + (): Codec<OutgoingHistory> => + buildCodecForObject<OutgoingHistory>() .property("debit_account", codecOptional(codecForPaytoString())) .property( "outgoing_transactions", @@ -460,8 +459,8 @@ export const codecForOutgoingHistory = .build("TalerWireGatewayApi.OutgoingHistory"); export const codecForOutgoingBankTransaction = - (): Codec<TalerWireGatewayApi.OutgoingBankTransaction> => - buildCodecForObject<TalerWireGatewayApi.OutgoingBankTransaction>() + (): Codec<OutgoingBankTransaction> => + buildCodecForObject<OutgoingBankTransaction>() .property("row_id", codecForNumber()) .property("date", codecForTimestamp) .property("amount", codecForAmountString()) @@ -471,22 +470,22 @@ export const codecForOutgoingBankTransaction = .build("TalerWireGatewayApi.OutgoingBankTransaction"); export const codecForAddIncomingResponse = - (): Codec<TalerWireGatewayApi.AddIncomingResponse> => - buildCodecForObject<TalerWireGatewayApi.AddIncomingResponse>() + (): Codec<AddIncomingResponse> => + buildCodecForObject<AddIncomingResponse>() .property("row_id", codecForNumber()) .property("timestamp", codecForTimestamp) .build("TalerWireGatewayApi.AddIncomingResponse"); export const codecForBankWireTransferList = - (): Codec<TalerWireGatewayApi.BankWireTransferList> => - buildCodecForObject<TalerWireGatewayApi.BankWireTransferList>() + (): Codec<BankWireTransferList> => + buildCodecForObject<BankWireTransferList>() .property("debit_account", codecForPaytoString()) .property("transfers", codecForList(codecForBankWireTransferListStatus())) .build("TalerWireGatewayApi.BankWireTransferList"); export const codecForBankWireTransferStatus = - (): Codec<TalerWireGatewayApi.BankWireTransferStatus> => - buildCodecForObject<TalerWireGatewayApi.BankWireTransferStatus>() + (): Codec<BankWireTransferStatus> => + buildCodecForObject<BankWireTransferStatus>() .property( "status", codecForEither( @@ -505,8 +504,8 @@ export const codecForBankWireTransferStatus = .build("TalerWireGatewayApi.BankWireTransferStatus"); export const codecForBankWireTransferListStatus = - (): Codec<TalerWireGatewayApi.BankWireTransferListStatus> => - buildCodecForObject<TalerWireGatewayApi.BankWireTransferListStatus>() + (): Codec<BankWireTransferListStatus> => + buildCodecForObject<BankWireTransferListStatus>() .property("row_id", codecForNumber()) .property( "status", diff --git a/packages/taler-wallet-core/src/balance.ts b/packages/taler-wallet-core/src/balance.ts @@ -646,7 +646,7 @@ export async function getBalancesInsideTransaction( case PeerPullDebitRecordStatus.PendingDeposit: case PeerPullDebitRecordStatus.AbortingRefresh: case PeerPullDebitRecordStatus.SuspendedAbortingRefresh: - case PeerPullDebitRecordStatus.SuspendedDeposit: + case PeerPullDebitRecordStatus.SuspendedDeposit: { const currency = Amounts.currencyOf(rec.amount); const amount = rec.coinSel?.totalCost ?? rec.amount; await balanceStore.addPendingOutgoing( @@ -655,6 +655,7 @@ export async function getBalancesInsideTransaction( amount, ); break; + } } } @@ -662,7 +663,7 @@ export async function getBalancesInsideTransaction( for (const rec of purchases) { switch (rec.purchaseStatus) { case PurchaseStatus.SuspendedPaying: - case PurchaseStatus.PendingPaying: + case PurchaseStatus.PendingPaying: { if (!rec.payInfo || !rec.payInfo.payCoinSelection?.coinPubs) { break; } @@ -682,6 +683,7 @@ export async function getBalancesInsideTransaction( sel.coinContributions[i], ); } + } } } diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts @@ -74,7 +74,7 @@ interface WorkItem { /** * Time when the work was submitted to a (non-busy) worker thread. */ - startTime: BigInt; + startTime: bigint; state: WorkItemState; } diff --git a/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts b/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts @@ -76,7 +76,6 @@ export function handleWorkerMessage(msg: any): void { const handleRequest = async (): Promise<void> => { const responseMsg = await processRequestWithImpl(msg, nativeCryptoR); try { - // eslint-disable-next-line @typescript-eslint/no-var-requires const _r = "require"; const worker_threads: typeof import("worker_threads") = module[_r]("worker_threads"); @@ -130,7 +129,6 @@ class NodeThreadCryptoWorker implements CryptoWorker { private nodeWorker: import("worker_threads").Worker; constructor() { - // eslint-disable-next-line @typescript-eslint/no-var-requires const _r = "require"; const worker_threads = module[_r]("worker_threads"); diff --git a/packages/taler-wallet-core/src/host-impl.node.ts b/packages/taler-wallet-core/src/host-impl.node.ts @@ -22,7 +22,6 @@ /** * Imports. */ -// eslint-disable-next-line no-duplicate-imports import { BridgeIDBFactory, createSqliteBackend, @@ -208,7 +207,6 @@ export async function createNativeWalletHost2( try { // Try if we have worker threads available, fails in older node versions. const _r = "require"; - // eslint-disable-next-line no-unused-vars const worker_threads = module[_r]("worker_threads"); // require("worker_threads"); workerFactory = new NodeThreadCryptoWorkerFactory(); diff --git a/packages/taler-wallet-core/src/host-impl.qtart.ts b/packages/taler-wallet-core/src/host-impl.qtart.ts @@ -27,7 +27,6 @@ import type { Sqlite3Interface, Sqlite3Statement, } from "@gnu-taler/idb-bridge"; -// eslint-disable-next-line no-duplicate-imports import { BridgeIDBFactory, createSqliteBackend, @@ -46,7 +45,7 @@ import { DefaultNodeWalletArgs, getSqlite3FilenameFromStoragePath, } from "./host-common.js"; -import { exportDb } from "./index.js"; +import { exportDb } from "./db-indexeddb.js"; import { Wallet } from "./wallet.js"; import { WalletDbHandle } from "./dbtx-handle.js"; import { IdbWalletDbHandle } from "./dbtx-handle-impl.js"; diff --git a/packages/taler-wallet-core/src/mailbox.ts b/packages/taler-wallet-core/src/mailbox.ts @@ -301,7 +301,7 @@ export async function refreshMailbox( hMailbox: mailboxConf.hAddress, }); switch (res.case) { - case "ok": + case "ok": { const hpkeSk: Uint8Array = decodeCrock(mailboxConf.privateEncryptionKey); if (res.body) { const messages = res.body.messages; @@ -368,6 +368,7 @@ export async function refreshMailbox( return { messages: [], }; // No new messages; + } default: throw TalerError.fromDetail( TalerErrorCode.WALLET_MAILBOX_UNAVAILABLE, diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts @@ -1548,7 +1548,7 @@ async function createOrReusePurchase( await startPayReplay(wex, tx, oldProposal.proposalId, sessionId); }); break; - case PurchaseStatus.DoneRepurchaseDetected: + case PurchaseStatus.DoneRepurchaseDetected: { // Trigger replay on *old* payment const repId = oldProposal.repurchaseProposalId; if (repId != null) { @@ -1557,6 +1557,7 @@ async function createOrReusePurchase( }); } break; + } } } if (oldProposal.shared || oldProposal.createdFromShared) { @@ -2419,7 +2420,7 @@ async function calculateDefaultChoice( defaultChoiceIndex: 0, automaticExecution: false, }; - case MerchantContractVersion.V1: + case MerchantContractVersion.V1: { if (contractTerms.choices.length === 0) throw TalerError.fromDetail( TalerErrorCode.WALLET_CONTRACT_TERMS_MALFORMED, @@ -2487,6 +2488,7 @@ async function calculateDefaultChoice( } } break; + } default: assertUnreachable(contractTerms); } diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts @@ -912,7 +912,7 @@ async function processPendingMerge( case "ok": logger.trace(`merge response: ${j2s(mergeResp.body)}`); break; - case HttpStatusCode.UnavailableForLegalReasons: + case HttpStatusCode.UnavailableForLegalReasons: { const kycLegiNeededResp = mergeResp.body; logger.info(`kyc legitimization needed response: ${j2s(mergeResp.body)}`); return transitionPeerPushCreditKycRequired( @@ -920,6 +920,7 @@ async function processPendingMerge( peerInc, kycLegiNeededResp, ); + } case HttpStatusCode.Conflict: // FIXME: Check signature. await ctx.wex.runWalletDbTx(async (tx) => { diff --git a/packages/taler-wallet-core/src/query.ts b/packages/taler-wallet-core/src/query.ts @@ -497,7 +497,7 @@ export interface StoreWithIndexes< * Type marker symbol, to check that the descriptor * has been created through the right function. */ - mark: Symbol; + mark: symbol; } const storeWithIndexesSymbol = Symbol("StoreWithIndexesMark"); diff --git a/packages/taler-wallet-core/src/taldir.ts b/packages/taler-wallet-core/src/taldir.ts @@ -65,7 +65,7 @@ export async function lookupAlias( // Refresh message size const resConf = await taldirClient.getConfig(); switch (resConf.case) { - case "ok": + case "ok": { let supported_types = resConf.body.alias_types; let typeFound = false; for (var t of supported_types) { @@ -79,6 +79,7 @@ export async function lookupAlias( return {}; } break; + } default: throw TalerError.fromDetail( TalerErrorCode.WALLET_ALIAS_REGISTRATION_FAILED, diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx @@ -46,7 +46,6 @@ import settingsIcon from "./svg/settings_black_24dp.inline.svg"; * @author sebasjm */ -// eslint-disable-next-line @typescript-eslint/ban-types type PageLocation<DynamicPart extends object> = { pattern: string; (params: DynamicPart): string; @@ -64,7 +63,6 @@ function replaceAll( return result; } -// eslint-disable-next-line @typescript-eslint/ban-types function pageDefinition<T extends object>(pattern: string): PageLocation<T> { const patternParams = pattern.match(/(:[\w?]*)/g); if (!patternParams) diff --git a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx @@ -358,7 +358,7 @@ function ShowObservabilityEvent({ events, onClick }: MoreInfoPRops): VNode { not.type !== NotificationType.RequestObservabilityEvent && not.type !== NotificationType.TaskObservabilityEvent ) - return <Fragment />; + return <Fragment key={idx} />; const title = (function () { switch (not.event.type) { diff --git a/packages/taler-wallet-webextension/src/context/alert.ts b/packages/taler-wallet-webextension/src/context/alert.ts @@ -76,12 +76,8 @@ const initial: Type = { safely: () => { throw Error("alert context not initialized"); }, - pushAlert: () => { - null; - }, - removeAlert: () => { - null; - }, + pushAlert: () => {}, + removeAlert: () => {}, }; const Context = createContext<Type>(initial); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -178,7 +178,6 @@ export function useComponentStateFromURI({ const api = useBackendContext(); const { i18n } = useTranslationContext(); - // eslint-disable-next-line @typescript-eslint/no-unused-vars // const [updatedExchangeByUser, setUpdatedExchangeByUser] = useState<string>(); /** * Ask the wallet about the withdraw URI diff --git a/packages/taler-wallet-webextension/src/mui/Alert.tsx b/packages/taler-wallet-webextension/src/mui/Alert.tsx @@ -16,7 +16,6 @@ import { TranslatedString } from "@gnu-taler/taler-util"; import { ComponentChildren, h, VNode } from "preact"; import styles from "./Alert.module.css"; -// eslint-disable-next-line import/extensions import CloseIcon from "../svg/close_24px.inline.svg"; import ErrorOutlineIcon from "../svg/error_outline_outlined_24px.inline.svg"; import InfoOutlinedIcon from "../svg/info_outlined_24px.inline.svg"; diff --git a/packages/taler-wallet-webextension/src/mui/Button.tsx b/packages/taler-wallet-webextension/src/mui/Button.tsx @@ -14,14 +14,12 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { ComponentChildren, h, VNode, JSX } from "preact"; -// eslint-disable-next-line import/extensions import { theme, Colors, rippleEnabled, rippleEnabledOutlined, } from "./style.js"; -// eslint-disable-next-line import/extensions import { alpha } from "./colors/manipulation.js"; import { useState } from "preact/hooks"; import styles from "./Button.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/Grid.tsx b/packages/taler-wallet-webextension/src/mui/Grid.tsx @@ -15,7 +15,6 @@ */ import { h, JSX, VNode, ComponentChildren, createContext } from "preact"; import { useContext } from "preact/hooks"; -// eslint-disable-next-line import/extensions import { theme } from "./style.js"; import styles from "./Grid.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/Menu.tsx b/packages/taler-wallet-webextension/src/mui/Menu.tsx @@ -17,7 +17,6 @@ import { h, VNode, ComponentChildren } from "preact"; import { buttonBaseStyle } from "./Button.js"; import { alpha } from "./colors/manipulation.js"; import { Paper } from "./Paper.js"; -// eslint-disable-next-line import/extensions import { Colors, ripple, theme } from "./style.js"; import styles from "./Menu.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/Paper.tsx b/packages/taler-wallet-webextension/src/mui/Paper.tsx @@ -14,9 +14,7 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { h, JSX, VNode, ComponentChildren } from "preact"; -// eslint-disable-next-line import/extensions import { alpha } from "./colors/manipulation.js"; -// eslint-disable-next-line import/extensions import { theme } from "./style.js"; import styles from "./Paper.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/TextField.tsx b/packages/taler-wallet-webextension/src/mui/TextField.tsx @@ -22,7 +22,6 @@ import { InputStandard } from "./input/InputStandard.js"; import { SelectFilled } from "./input/SelectFilled.js"; import { SelectOutlined } from "./input/SelectOutlined.js"; import { SelectStandard } from "./input/SelectStandard.js"; -// eslint-disable-next-line import/extensions import { Colors } from "./style.js"; export interface Props { diff --git a/packages/taler-wallet-webextension/src/mui/Typography.tsx b/packages/taler-wallet-webextension/src/mui/Typography.tsx @@ -15,7 +15,6 @@ */ import { ComponentChildren, h, VNode } from "preact"; import { useTranslationContext } from "@gnu-taler/web-util/browser"; -// eslint-disable-next-line import/extensions import { theme } from "./style.js"; import styles from "./Typography.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/input/FormControl.tsx b/packages/taler-wallet-webextension/src/mui/input/FormControl.tsx @@ -15,7 +15,6 @@ */ import { ComponentChildren, createContext, h, VNode } from "preact"; import { useContext, useMemo, useState } from "preact/hooks"; -// eslint-disable-next-line import/extensions import { Colors } from "../style.js"; import styles from "./FormControl.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/input/FormHelperText.tsx b/packages/taler-wallet-webextension/src/mui/input/FormHelperText.tsx @@ -14,7 +14,6 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { ComponentChildren, h, VNode } from "preact"; -// eslint-disable-next-line import/extensions import { theme } from "../style.js"; import { useFormControl } from "./FormControl.js"; import styles from "./FormHelperText.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/input/InputBase.tsx b/packages/taler-wallet-webextension/src/mui/input/InputBase.tsx @@ -15,7 +15,6 @@ */ import { Fragment, h, JSX, VNode } from "preact"; import { useCallback, useLayoutEffect, useRef, useState } from "preact/hooks"; -// eslint-disable-next-line import/extensions import { theme } from "../style.js"; import { FormControlContext, useFormControl } from "./FormControl.js"; import styles from "./InputBase.module.css"; diff --git a/packages/taler-wallet-webextension/src/mui/input/InputFilled.tsx b/packages/taler-wallet-webextension/src/mui/input/InputFilled.tsx @@ -14,7 +14,6 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { h, VNode, JSX } from "preact"; -// eslint-disable-next-line import/extensions import { Colors, theme } from "../style.js"; import { useFormControl } from "./FormControl.js"; import { InputBase, InputBaseComponent, InputBaseRoot } from "./InputBase.js"; diff --git a/packages/taler-wallet-webextension/src/mui/input/InputStandard.tsx b/packages/taler-wallet-webextension/src/mui/input/InputStandard.tsx @@ -14,7 +14,6 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import { h, VNode } from "preact"; -// eslint-disable-next-line import/extensions import { Colors, theme } from "../style.js"; import { useFormControl } from "./FormControl.js"; import { InputBase, InputBaseComponent, InputBaseRoot } from "./InputBase.js"; diff --git a/packages/taler-wallet-webextension/src/mui/style.tsx b/packages/taler-wallet-webextension/src/mui/style.tsx @@ -13,7 +13,6 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ import { darken, lighten } from "polished"; import styles from "./style.module.css"; import "./theme.css"; @@ -26,9 +25,7 @@ import { orange, purple, red, - // eslint-disable-next-line import/extensions } from "./colors/constants.js"; -// eslint-disable-next-line import/extensions import { getContrastRatio } from "./colors/manipulation.js"; export type Colors = diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -161,7 +161,6 @@ export function BalanceView(state: State.Balances): VNode { const currencyWithNonZeroAmount = state.balances .filter((b) => !Amounts.isZero(b.available)) .map((b) => { - b.flags; return b.scopeInfo; }); diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts @@ -168,11 +168,7 @@ export function createWalletApiMock(): { operation, payload, response, - callback: cb - ? cb - : () => { - null; - }, + callback: cb ? cb : () => {}, }); return handler; }, diff --git a/packages/taler-wallet-webextension/src/wallet/Contacts.tsx b/packages/taler-wallet-webextension/src/wallet/Contacts.tsx @@ -249,7 +249,7 @@ export function ContactsView({ style={{ marginTop: 20 }} > {contacts.map((c, _) => ( - <Grid item xs={1}> + <Grid key={_} item xs={1}> <ContactLayout contact={c} transaction={transaction} diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -73,7 +73,7 @@ type SplitedCoinInfo = { const listenAllEvents = Array.from<NotificationType>({ length: 1 }); -function ExchangeActions({}: {}): VNode { +function ExchangeActions(_props: {}): VNode { const [time, reload] = useState<number>(); const { i18n } = useTranslationContext(); const api = useBackendContext(); diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -294,14 +294,15 @@ export function HistoryView({ } return ( - <Fragment> - {groupByScope[key].map((ex) => { + <Fragment key={si}> + {groupByScope[key].map((ex, idx) => { const st = stringifyScopeInfoShort(ex.scopeInfo); if (ex.scopeInfo.type === ScopeType.Global) { - return <Fragment />; + return <Fragment key={idx} />; } return ( <optgroup + key={idx} label={new URL(ex.scopeInfo.url).hostname} > <option value={st} key={st}> diff --git a/packages/taler-wallet-webextension/src/wallet/Mailbox.tsx b/packages/taler-wallet-webextension/src/wallet/Mailbox.tsx @@ -390,7 +390,7 @@ export function MessagesView({ )} <Grid item container columns={1} spacing={1} style={{ marginTop: 20 }}> {messages.map((m, _) => ( - <Grid item xs={1}> + <Grid key={_} item xs={1}> <MailboxMessageLayout message={m} onDeleteMessage={onDeleteMessage} diff --git a/packages/taler-wallet-webextension/src/wallet/SupportedBanksForAccount.tsx b/packages/taler-wallet-webextension/src/wallet/SupportedBanksForAccount.tsx @@ -52,8 +52,12 @@ export function SupportedBanksForAccount({ account }: Props): VNode { return ( <div> - {state.response.choices.map((ch) => { - return <a href={ch.uri}>{ch.label}</a>; + {state.response.choices.map((ch, idx) => { + return ( + <a key={idx} href={ch.uri}> + {ch.label} + </a> + ); })} </div> ); diff --git a/packages/web-util/build.mjs b/packages/web-util/build.mjs @@ -24,7 +24,6 @@ import { execSync } from "node:child_process"; const root = path.dirname(nodeUrl.fileURLToPath(import.meta.url)); process.chdir(root); -// eslint-disable-next-line no-undef const BASE_DIR = process.cwd(); let GIT_ROOT = BASE_DIR; @@ -200,9 +199,7 @@ const buildConfigBrowser = { buildConfigTesting, ].forEach((config) => { esbuild.build(config).catch((e) => { - // eslint-disable-next-line no-undef console.log(e); - // eslint-disable-next-line no-undef process.exit(1); }); }); diff --git a/packages/web-util/src/components/ErrorLoading.tsx b/packages/web-util/src/components/ErrorLoading.tsx @@ -22,11 +22,9 @@ import { TranslatedString, } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; -import { - translateTalerError, - useCommonPreferences, - useTranslationContext, -} from "../index.browser.js"; +import { useCommonPreferences } from "../context/common-preferences.js"; +import { useTranslationContext } from "../context/translation.js"; +import { translateTalerError } from "../hooks/useNotifications.js"; import { Attention } from "./Attention.js"; export function ErrorLoading({ @@ -41,8 +39,8 @@ export function ErrorLoading({ const [{ showDebugInfo }] = useCommonPreferences(); return ( <Attention type="danger" copy title={title}> - {(description ?? []).map((d) => ( - <p>{d}</p> + {(description ?? []).map((d, idx) => ( + <p key={idx}>{d}</p> ))} <pre class="whitespace-break-spaces text-black" diff --git a/packages/web-util/src/components/ErrorLoadingMerchant.tsx b/packages/web-util/src/components/ErrorLoadingMerchant.tsx @@ -16,11 +16,9 @@ import { TalerError, TranslatedString } from "@gnu-taler/taler-util"; import { Fragment, VNode, h } from "preact"; -import { - translateTalerError, - useCommonPreferences, - useTranslationContext, -} from "../index.browser.js"; +import { useCommonPreferences } from "../context/common-preferences.js"; +import { useTranslationContext } from "../context/translation.js"; +import { translateTalerError } from "../hooks/useNotifications.js"; import { Attention } from "./Attention.js"; function DebugInfo({ error }: { error: any }): VNode { @@ -44,8 +42,8 @@ export function ErrorLoading({ const description = translateTalerError(error, i18n); return ( <Attention type="danger" title={title}> - {(description ?? []).map((d) => ( - <p>{d}</p> + {(description ?? []).map((d, idx) => ( + <p key={idx}>{d}</p> ))} <DebugInfo error={error.errorDetail} /> </Attention> diff --git a/packages/web-util/src/components/Header.tsx b/packages/web-util/src/components/Header.tsx @@ -1,11 +1,8 @@ import { ComponentChildren, Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import logo from "../assets/taler-logo-white.png"; -import { - LangSelector, - // useNotifications, - useTranslationContext, -} from "../index.browser.js"; +import { useTranslationContext } from "../context/translation.js"; +import { LangSelector } from "./LangSelector.js"; interface Props { title: string; @@ -45,11 +42,12 @@ export function Header({ </div> <div class="flex-1 ml-6 "> <div class="flex flex-1 space-x-4"> - {sites.map((site) => { + {sites.map((site, idx) => { if (site.length !== 2) return; const [name, url] = site; return ( <a + key={idx} href={url} name={`site header ${name}`} class="hidden sm:block text-white hover:bg-indigo-500 hover:bg-opacity-75 rounded-md py-2 px-3 text-sm font-medium" @@ -277,7 +275,7 @@ export function Header({ <ul role="list" class="space-y-1"> {sites.map(([name, url]) => { return ( - <li> + <li key={url}> <a href={url} name={`site ${name}`} diff --git a/packages/web-util/src/components/LangSelector.tsx b/packages/web-util/src/components/LangSelector.tsx @@ -23,7 +23,7 @@ import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; // import { strings as messages } from "../i18n/strings.js"; import langIcon from "../assets/lang.svg"; -import { useTranslationContext } from "../index.browser.js"; +import { useTranslationContext } from "../context/translation.js"; type LangsNames = { [P: string]: string; @@ -167,8 +167,9 @@ export function LangSelector({ )} {Object.keys(supportedLang) .filter((l) => l !== lang) - .map((lang) => ( + .map((lang, idx) => ( <li + key={idx} class="text-gray-900 hover:bg-primary hover:bg-gray-300 cursor-pointer relative select-none py-2 pl-3 pr-9" role="option" onClick={() => { diff --git a/packages/web-util/src/components/NotificationBanner.tsx b/packages/web-util/src/components/NotificationBanner.tsx @@ -1,11 +1,9 @@ import { Fragment, h, VNode } from "preact"; import { useRef, useState } from "preact/compat"; -import { - CopyButton, - useCommonPreferences, - useNotificationContext, - useTranslationContext, -} from "../index.browser.js"; +import { useCommonPreferences } from "../context/common-preferences.js"; +import { useNotificationContext } from "../context/notification.js"; +import { useTranslationContext } from "../context/translation.js"; +import { CopyButton } from "./CopyButton.js"; import { Attention } from "./Attention.js"; import { composeRef, saveRef } from "./utils.js"; import { Duration } from "@gnu-taler/taler-util"; @@ -34,7 +32,7 @@ export function ToastBanner(): VNode { if (!ns || !ns.length) return <Fragment />; const notification = ns[0]; switch (notification.message.type) { - case "error": + case "error": { const desc = notification.message.description; return ( <Attention @@ -49,8 +47,12 @@ export function ToastBanner(): VNode { {desc && desc.length && (moreInfo ? ( - desc.map((d) => { - return <div class="mt-2 text-sm text-red-700">{d}</div>; + desc.map((d, idx) => { + return ( + <div key={idx} class="mt-2 text-sm text-red-700"> + {d} + </div> + ); }) ) : ( <div class="mt-2 text-sm text-red-700">{desc[0]}</div> @@ -80,6 +82,7 @@ export function ToastBanner(): VNode { </pre> </Attention> ); + } case "info": return ( <Attention @@ -145,8 +148,8 @@ export function ToastBannerBulma(): VNode { {msg.description && msg.description.length && ( <div class="message-body"> {moreInfo ? ( - msg.description.map((d) => { - return <div>{d}</div>; + msg.description.map((d, idx) => { + return <div key={idx}>{d}</div>; }) ) : ( <div>{msg.description[0]}</div> diff --git a/packages/web-util/src/context/navigation.ts b/packages/web-util/src/context/navigation.ts @@ -42,7 +42,6 @@ const Context = createContext<Type>(undefined); export const useNavigationContext = (): Type => useContext(Context); -// eslint-disable-next-line @typescript-eslint/no-explicit-any export function useCurrentLocation<T extends ObjectOf<RouteDefinition<any>>>( pagesMap: T, ): Location<T> | LocationNotFound<T> { diff --git a/packages/web-util/src/forms/forms-types.ts b/packages/web-util/src/forms/forms-types.ts @@ -410,7 +410,6 @@ const codecForUiFormFieldArray = (): Codec<UIFormFieldArray> => .property("type", codecForConstString("array")) .property("labelFieldId", codecForUiFieldId()) .property("tooltip", codecOptional(codecForString())) - // eslint-disable-next-line @typescript-eslint/no-use-before-define .property("fields", codecForList(codecForUiFormField())) .build("UIFormFieldArray"); @@ -482,7 +481,6 @@ const codecForUiFormFieldFile = (): Codec<UIFormFieldFile> => const codecForUiFormFieldGroup = (): Codec<UIFormElementGroup> => codecForUIFormFieldBaseDescriptionTemplate<UIFormElementGroup>() .property("type", codecForConstString("group")) - // eslint-disable-next-line @typescript-eslint/no-use-before-define .property("fields", codecForList(codecForUiFormField())) .build("UiFormFieldGroup"); diff --git a/packages/web-util/src/forms/forms-ui.tsx b/packages/web-util/src/forms/forms-ui.tsx @@ -7,7 +7,7 @@ import { } from "../hooks/useForm.js"; // import { getConverterById, useTranslationContext } from "../index.browser.js"; import { useState } from "preact/hooks"; -import { useTranslationContext } from "../index.browser.js"; +import { useTranslationContext } from "../context/translation.js"; import { FieldComponentFunction, UIFormConfiguration, @@ -113,7 +113,7 @@ export function FormUI<T>({ switch (design.type) { case "double-column": { const ui = design.sections.map((section, i) => { - if (!section) return <Fragment />; + if (!section) return <Fragment key={i} />; return ( <DoubleColumnFormSectionUI sectionKey={`${i}`} @@ -387,6 +387,7 @@ export function ErrorsSummary<T>({ // use preact REF return ( <span + key={fieldName} href="#" onClick={(e) => { e.preventDefault(); diff --git a/packages/web-util/src/hooks/useAsyncAsHook.ts b/packages/web-util/src/hooks/useAsyncAsHook.ts @@ -57,7 +57,6 @@ export function useAsyncAsHook<T>( const args = useMemo( () => ({ fn, - // eslint-disable-next-line react-hooks/exhaustive-deps }), deps || [], ); diff --git a/packages/web-util/src/live-reload.ts b/packages/web-util/src/live-reload.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-undef */ const protocol = window.location.protocol === "http:" ? "ws:" : "wss:"; const POLL_URL = `./build-time.txt`; diff --git a/packages/web-util/src/tests/hook.ts b/packages/web-util/src/tests/hook.ts @@ -226,9 +226,7 @@ function mountHook<T extends object>( }; } -export const nullFunction = (): void => { - null; -}; +export const nullFunction = (): void => {}; export const nullAsyncFunction = (): Promise<void> => { return Promise.resolve(); }; @@ -255,7 +253,6 @@ interface HookTestResultError { * * @returns testing result, should also be checked to be "ok" */ -// eslint-disable-next-line @typescript-eslint/ban-types export async function hookBehaveLikeThis<T extends object, PropsType>( hookFunction: (p: PropsType) => RecursiveState<T>, props: PropsType, diff --git a/packages/web-util/src/tests/mock.ts b/packages/web-util/src/tests/mock.ts @@ -51,10 +51,8 @@ type ExpectationValues = { query: Query<any, any>; auth?: string; params?: { - // eslint-disable-next-line @typescript-eslint/ban-types request?: object; qparam?: Record<string, string>; - // eslint-disable-next-line @typescript-eslint/ban-types response?: object; }; }; @@ -86,9 +84,7 @@ export abstract class MockEnvironment { } public addRequestExpectation< - // eslint-disable-next-line @typescript-eslint/ban-types RequestType extends object, - // eslint-disable-next-line @typescript-eslint/ban-types ResponseType extends object, >( query: Query<RequestType, ResponseType>, @@ -107,9 +103,7 @@ export abstract class MockEnvironment { } public saveRequestAndGetMockedResponse< - // eslint-disable-next-line @typescript-eslint/ban-types RequestType extends object, - // eslint-disable-next-line @typescript-eslint/ban-types ResponseType extends object, >( query: Query<RequestType, ResponseType>, @@ -425,9 +419,7 @@ function deepEquals( let keyIterator: string; while (keySize--) { - // eslint-disable-next-line @typescript-eslint/ban-types const _a = a as Record<string, object>; - // eslint-disable-next-line @typescript-eslint/ban-types const _b = b as Record<string, object>; keyIterator = aKeys[keySize]; @@ -444,7 +436,6 @@ function deepEquals( return true; } -// eslint-disable-next-line @typescript-eslint/ban-types function allKeysFromObject(obj: object): Array<string> { const keys = []; for (const key in obj) {