From 1adbd15afdf0f24c3c86844ea748cb663f40326c Mon Sep 17 00:00:00 2001 From: Christian Bundy Date: Tue, 24 Mar 2020 08:11:13 -0700 Subject: [PATCH 1/4] Don't append channel to non-root posts Problem: When publishing a root post, other clients give you the option of adding a `channel` property, which is basically just a hashtag. We show this at the end of the message, but since replies often copy the `channel` property then it gets appended to every reply. Solution: Only append the channel as a hashtag for root posts. --- src/models.js | 15 ++++++++------- src/ssb.js | 11 ++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/models.js b/src/models.js index 95d87df..15b4a16 100644 --- a/src/models.js +++ b/src/models.js @@ -469,10 +469,17 @@ module.exports = ({ cooler, isPublic }) => { } } + const isPost = + lodash.get(msg, "value.content.type") === "post" && + lodash.get(msg, "value.content.text", false) !== false; + const hasRoot = lodash.get(msg, "value.content.root", false) !== false; + const hasFork = lodash.get(msg, "value.content.fork", false) !== false; + const channel = lodash.get(msg, "value.content.channel"); const hasChannel = typeof channel === "string" && channel.length > 2; + const isRoot = hasRoot === false; - if (hasChannel) { + if (hasChannel && isRoot) { msg.value.content.text += `\n\n#${channel}`; } @@ -506,12 +513,6 @@ module.exports = ({ cooler, isPublic }) => { url: avatarUrl, }); - const isPost = - lodash.get(msg, "value.content.type") === "post" && - lodash.get(msg, "value.content.text") != null; - const hasRoot = lodash.get(msg, "value.content.root") != null; - const hasFork = lodash.get(msg, "value.content.fork") != null; - if (isPost && hasRoot === false && hasFork === false) { lodash.set(msg, "value.meta.postType", "post"); } else if (isPost && hasRoot && hasFork === false) { diff --git a/src/ssb.js b/src/ssb.js index eb291f5..5579260 100644 --- a/src/ssb.js +++ b/src/ssb.js @@ -77,7 +77,7 @@ const createConnection = (config) => { lodash.get(ssbConfig, "friends.hops", 0) ); - const add = address => { + const add = (address) => { inProgress[address] = true; return () => { inProgress[address] = false; @@ -88,10 +88,10 @@ const createConnection = (config) => { rawConnect() .then((ssb) => { log("Retrying connection to own server"); - ssb.friends.hops().then(hops => { + ssb.friends.hops().then((hops) => { pull( ssb.conn.stagedPeers(), - pull.drain(x => { + pull.drain((x) => { x.filter(([address, data]) => { const notInProgress = inProgress[address] !== true; @@ -110,10 +110,7 @@ const createConnection = (config) => { hops[data.key] }/${maxHops} hops: ${address}` ); - ssb.conn - .connect(address, data) - .then(done) - .catch(done); + ssb.conn.connect(address, data).then(done).catch(done); }); }) ); From c9fffe2b9c7bfec1e6918e37174f1bc23193c228 Mon Sep 17 00:00:00 2001 From: Christian Bundy Date: Tue, 24 Mar 2020 09:21:59 -0700 Subject: [PATCH 2/4] Add TypeScript definitions for better guardrails Problem: We have TypeScript enabled on the project but have been missing lots of definition files, so there are like 500 errors when you enable `--noImplicitAny`. Solution: Add definitions and fix the bugs that they point out. This reduces the number of errors with `--noImplicitAny` to 285. --- package-lock.json | 236 ++++++++++++++++++++++++++++++++++++++++++ package.json | 13 +++ src/http.js | 18 +++- src/index.js | 29 ++++-- src/ssb.js | 4 +- src/views/i18n.js | 4 +- src/views/index.js | 4 +- src/views/markdown.js | 1 + 8 files changed, 290 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9667e1e..27cc621 100644 --- a/package-lock.json +++ b/package-lock.json @@ -330,16 +330,83 @@ "fastq": "^1.6.0" } }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/connect": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cookies": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz", + "integrity": "sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "@types/debug": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, + "@types/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", + "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.3.tgz", + "integrity": "sha512-sHEsvEzjqN+zLbqP+8OXTipc10yH1QLR+hnr5uw29gi9AhCAAAdri8ClNV7iMdrJrIzXIQtlkPvq8tJGhj3QJQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, "@types/formidable": { "version": "1.0.31", "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz", @@ -360,6 +427,111 @@ "@types/node": "*" } }, + "@types/highlight.js": { + "version": "9.12.3", + "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.3.tgz", + "integrity": "sha512-pGF/zvYOACZ/gLGWdQH8zSwteQS1epp68yRcVLJMgUck/MjEn/FBYmPub9pXT8C1e4a8YZfHo1CKyV8q1vKUnQ==", + "dev": true + }, + "@types/http-assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", + "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==", + "dev": true + }, + "@types/keygrip": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", + "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", + "dev": true + }, + "@types/koa": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.2.tgz", + "integrity": "sha512-2UPelagNNW6bnc1I5kIzluCaheXRA9S+NyOdXEFFj9Az7jc15ek5V03kb8OTbb3tdZ5i2BIJObe86PhHvpMolg==", + "dev": true, + "requires": { + "@types/accepts": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "@types/koa-compose": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", + "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-mount": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/koa-mount/-/koa-mount-4.0.0.tgz", + "integrity": "sha512-56iBULArwY3uKLl28eRFchZ2v0diEoJzJbDaHH/ehgruF/s2/KMHyWsKcIhvDJ3tGdKu9oZNQvxaMg++1IKFdA==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-send": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.2.tgz", + "integrity": "sha512-rfqKIv9bFds39Jxvsp8o3YJLnEQVPVriYA14AuO2OY65IHh/4UX4U/iMs5L0wATpcRmm1bbe0BNk23TRwx3VQQ==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-static": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/koa-static/-/koa-static-4.0.1.tgz", + "integrity": "sha512-SSpct5fEcAeRkBHa3RiwCIRfDHcD1cZRhwRF///ZfvRt8KhoqRrhK6wpDlYPk/vWHVFE9hPGqh68bhzsHkir4w==", + "dev": true, + "requires": { + "@types/koa": "*", + "@types/koa-send": "*" + } + }, + "@types/koa__router": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-8.0.2.tgz", + "integrity": "sha512-3ZWfVAEcErHrZA31fWUC2YyZyAgoG4eKtQPy2XwBzdSpQealxjL7GcEEtGY925qPPs1wurW59qDl0KuRB39rrw==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/linkify-it": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-2.1.0.tgz", + "integrity": "sha512-Q7DYAOi9O/+cLLhdaSvKdaumWyHbm7HAk/bFwwyTuU0arR5yyCeW5GOoqt4tJTpDRxhpx9Q8kQL6vMpuw9hDSw==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.149", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", + "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", + "dev": true + }, + "@types/markdown-it": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-0.0.9.tgz", + "integrity": "sha512-IFSepyZXbF4dgSvsk8EsgaQ/8Msv1I5eTL0BZ0X3iGO9jw6tCVtPG8HchIPm3wrkmGdqZOD42kE0zplVi1gYDA==", + "dev": true, + "requires": { + "@types/linkify-it": "*" + } + }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -372,11 +544,29 @@ "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", "dev": true }, + "@types/mkdirp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.0.tgz", + "integrity": "sha512-ONFY9//bCEr3DWKON3iDv/Q8LXnhaYYaNDeFSN0AtO5o4sLf9F0pstJKKKjQhXE0kJEeHs8eR6SAsROhhc2Csw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node": { "version": "13.5.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz", "integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==" }, + "@types/nodemon": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/nodemon/-/nodemon-1.19.0.tgz", + "integrity": "sha512-nf0PKjNv3wo0pyhlPkHjfpU2oUYMdOIsCXceiFG6kvhYxbTwn2ne9mz2iWvJ/4QtCrJUEPJLNXuyGleyTacdaw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -389,6 +579,37 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/pull-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@types/pull-stream/-/pull-stream-3.6.0.tgz", + "integrity": "sha512-d7cobAytjsYaTluqFTJopLbdZRs1HBkU+N07/zCtsXANZ5s9riDazRkvxkAUfmRzCvXqYAsGgnJHgX2lInIOQg==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "@types/sharp": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz", + "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/unist": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", @@ -415,6 +636,21 @@ "vfile-message": "*" } }, + "@types/yargs": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", diff --git a/package.json b/package.json index 8c8baec..1131ed6 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,19 @@ "yargs": "^15.3.1" }, "devDependencies": { + "@types/debug": "^4.1.5", + "@types/highlight.js": "^9.12.3", + "@types/koa": "^2.11.2", + "@types/koa-mount": "^4.0.0", + "@types/koa-static": "^4.0.1", + "@types/koa__router": "^8.0.2", + "@types/lodash": "^4.14.149", + "@types/markdown-it": "^0.0.9", + "@types/mkdirp": "^1.0.0", + "@types/nodemon": "^1.19.0", + "@types/pull-stream": "^3.6.0", + "@types/sharp": "^0.23.1", + "@types/yargs": "^15.0.4", "changelog-version": "^1.0.1", "common-good": "^2.0.3", "husky": "^4.0.0", diff --git a/src/http.js b/src/http.js index c085404..7984021 100644 --- a/src/http.js +++ b/src/http.js @@ -4,14 +4,15 @@ const path = require("path"); const mount = require("koa-mount"); /** - * @param {{ host: string, port: number, middleware: [] }} input + * @type function + * @param {{ host: string, port: number, middleware }} input + * @return function */ -module.exports = ({ host, port, middleware }) => { +const http = ({ host, port, middleware }) => { const assets = new Koa(); assets.use(koaStatic(path.join(__dirname, "assets"))); const app = new Koa(); - module.exports = app; app.on("error", (err) => { // Output full error objects @@ -59,16 +60,23 @@ module.exports = ({ host, port, middleware }) => { if (ctx.method !== "GET") { const referer = ctx.request.header.referer; - ctx.assert(referer != null, `HTTP ${ctx.method} must include referer`); + ctx.assert( + referer != null, + 400, + `HTTP ${ctx.method} must include referer` + ); const refererUrl = new URL(referer); const isBlobReferer = refererUrl.pathname.startsWith("/blob/"); ctx.assert( isBlobReferer === false, + 400, `HTTP ${ctx.method} from blob URL not allowed` ); } }); middleware.forEach((m) => app.use(m)); - app.listen({ host, port }); + return app.listen({ host, port }); }; + +module.exports = http; diff --git a/src/index.js b/src/index.js index ddd50a3..2b3bea5 100755 --- a/src/index.js +++ b/src/index.js @@ -38,10 +38,10 @@ if (config.debug) { const nodeHttp = require("http"); const debug = require("debug")("oasis"); -const log = (...args) => { +const log = (formatter, ...args) => { const isDebugEnabled = debug.enabled; debug.enabled = true; - debug(...args); + debug(formatter, ...args); debug.enabled = isDebugEnabled; }; @@ -123,7 +123,7 @@ const { nav, ul, li, a } = require("hyperaxe"); const open = require("open"); const pull = require("pull-stream"); const requireStyle = require("require-style"); -const router = require("@koa/router")(); +const koaRouter = require("@koa/router"); const ssbMentions = require("ssb-mentions"); const ssbRef = require("ssb-ref"); const isSvg = require("is-svg"); @@ -132,6 +132,8 @@ const { isFeed, isMsg, isBlob } = require("ssb-ref"); const ssb = require("./ssb"); +const router = new koaRouter(); + // Create "cooler"-style interface from SSB connection. // This handle is passed to the models for their convenience. const cooler = ssb({ offline: config.offline }); @@ -192,7 +194,11 @@ router const isInteger = size % 1 === 0; const overMinSize = size > 2; const underMaxSize = size <= 256; - ctx.assert(isInteger && overMinSize && underMaxSize, "Invalid image size"); + ctx.assert( + isInteger && overMinSize && underMaxSize, + 400, + "Invalid image size" + ); return next(); }) .param("blobId", (blobId, ctx, next) => { @@ -418,6 +424,11 @@ router } // This prevents an auto-download when visiting the URL. + // + // Using @ts-ignore to circumvent a bug: + // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/43357 + // + // @ts-ignore ctx.attachment(blobId, { type: "inline" }); // If we don't do this explicitly the browser downloads the SVG and thinks @@ -664,13 +675,13 @@ router const { feed } = ctx.params; const referer = new URL(ctx.request.header.referer); ctx.body = await friend.follow(feed); - ctx.redirect(referer); + ctx.redirect(referer.href); }) .post("/unfollow/:feed", koaBody(), async (ctx) => { const { feed } = ctx.params; const referer = new URL(ctx.request.header.referer); ctx.body = await friend.unfollow(feed); - ctx.redirect(referer); + ctx.redirect(referer.href); }) .post("/like/:message", koaBody(), async (ctx) => { const { message } = ctx.params; @@ -710,19 +721,19 @@ router return vote.publish({ messageKey, value, recps: recipients }); }; ctx.body = await like({ messageKey, voteValue }); - ctx.redirect(referer); + ctx.redirect(referer.href); }) .post("/theme.css", koaBody(), async (ctx) => { const theme = String(ctx.request.body.theme); ctx.cookies.set("theme", theme); const referer = new URL(ctx.request.header.referer); - ctx.redirect(referer); + ctx.redirect(referer.href); }) .post("/language", koaBody(), async (ctx) => { const language = String(ctx.request.body.language); ctx.cookies.set("language", language); const referer = new URL(ctx.request.header.referer); - ctx.redirect(referer); + ctx.redirect(referer.href); }) .post("/settings/conn/start", koaBody(), async (ctx) => { await meta.connStart(); diff --git a/src/ssb.js b/src/ssb.js index 5579260..7e292d0 100644 --- a/src/ssb.js +++ b/src/ssb.js @@ -23,10 +23,10 @@ ssbConfig.connections.incoming.unix = [ { scope: "device", transform: "noauth" }, ]; -const log = (...args) => { +const log = (formatter, ...args) => { const isDebugEnabled = debug.enabled; debug.enabled = true; - debug(...args); + debug(formatter, ...args); debug.enabled = isDebugEnabled; }; diff --git a/src/views/i18n.js b/src/views/i18n.js index c91aaeb..d29069e 100644 --- a/src/views/i18n.js +++ b/src/views/i18n.js @@ -1,6 +1,6 @@ const { a, em, strong } = require("hyperaxe"); -module.exports = { +const i18n = { en: { // navbar items extended: "Extended", @@ -510,3 +510,5 @@ module.exports = { "Beiträge von Leuten in deinem Netzwerk die dieses Hashtag referenzieren, sortiert nach Aktualität.", }, }; + +module.exports = i18n; diff --git a/src/views/index.js b/src/views/index.js index 9fbd747..9974f46 100644 --- a/src/views/index.js +++ b/src/views/index.js @@ -47,8 +47,8 @@ const markdown = require("./markdown"); const md = new MarkdownIt(); const i18nBase = require("./i18n"); -let i18n = null; -let selectedLanguage = null; +let selectedLanguage = "en"; +let i18n = i18nBase[selectedLanguage]; exports.setLanguage = (language) => { selectedLanguage = language; diff --git a/src/views/markdown.js b/src/views/markdown.js index 4a60a58..756708c 100644 --- a/src/views/markdown.js +++ b/src/views/markdown.js @@ -53,5 +53,6 @@ const toUrl = (mentions) => { module.exports = (input, mentions = []) => md.block(input, { toUrl: toUrl(mentions), + /** @param character {string} */ emoji: (character) => span({ class: "emoji" }, character).outerHTML, }); From fb23d2521774d296931cf4a8d0fae20be6d0bab2 Mon Sep 17 00:00:00 2001 From: Christian Bundy Date: Fri, 27 Mar 2020 08:21:40 -0700 Subject: [PATCH 3/4] Add more type definitions to reduce implicit any Problem: We still have heaps of implicit 'any' types that our linters can't make sense of. Solution: Keep on adding type documentation! Slowly but surely I'm hoping we can reduce the amount of untyped JavaScript in the repo. --- src/cli.js | 4 ++++ src/index.js | 2 +- src/ssb.js | 4 ++++ src/views/index.js | 10 ++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/cli.js b/src/cli.js index 8749e83..5983aa9 100644 --- a/src/cli.js +++ b/src/cli.js @@ -3,6 +3,10 @@ const yargs = require("yargs"); const _ = require("lodash"); +/** + * @param {object} presets + * @param {string} defaultConfigFile + */ module.exports = (presets, defaultConfigFile) => yargs .scriptName("oasis") diff --git a/src/index.js b/src/index.js index d8ca8a3..1cbad73 100755 --- a/src/index.js +++ b/src/index.js @@ -530,7 +530,7 @@ router peers: peersWithNames, theme, themeNames, - version: config.version, + version: config.version.toString(), }); }; ctx.body = await getMeta({ theme }); diff --git a/src/ssb.js b/src/ssb.js index 7e292d0..248bc59 100644 --- a/src/ssb.js +++ b/src/ssb.js @@ -23,6 +23,10 @@ ssbConfig.connections.incoming.unix = [ { scope: "device", transform: "noauth" }, ]; +/** + * @param formatter {string} input + * @param args {any[]} input + */ const log = (formatter, ...args) => { const isDebugEnabled = debug.enabled; debug.enabled = true; diff --git a/src/views/index.js b/src/views/index.js index d48e297..e55a77c 100644 --- a/src/views/index.js +++ b/src/views/index.js @@ -69,6 +69,9 @@ const toAttributes = (obj) => // non-breaking space const nbsp = "\xa0"; +/** + * @param {{href: string, emoji: string, text: string }} input + */ const navLink = ({ href, emoji, text }) => li(a({ href }, span({ class: "emoji" }, emoji), nbsp, text)); @@ -846,6 +849,9 @@ exports.publishView = () => { ); }; +/** + * @param {{status: object, peers: any[], theme: string, themeNames: string[], version: string }} input + */ exports.settingsView = ({ status, peers, theme, themeNames, version }) => { const max = status.sync.since; @@ -969,6 +975,7 @@ exports.settingsView = ({ status, peers, theme, themeNames, version }) => { ); }; +/** @param {{ viewTitle: string, viewDescription: string }} input */ const viewInfoBox = ({ viewTitle = null, viewDescription = null }) => { if (!viewTitle && !viewDescription) { return null; @@ -989,6 +996,8 @@ exports.likesView = async ({ messages, feed, name }) => { return template( viewInfoBox({ viewTitle: span(authorLink, i18n.likedBy), + // TODO: i18n + viewDescription: "List of messages liked by this author.", }), messages.map((msg) => post({ msg })) ); @@ -1144,6 +1153,7 @@ exports.hashtagView = ({ messages, hashtag }) => { ); }; +/** @param {{percent: number}} input */ exports.indexingView = ({ percent }) => { // TODO: i18n const message = `Oasis has only processed ${percent}% of the messages and needs to catch up. This page will refresh every 10 seconds. Thanks for your patience! ❤`; From 555249277ff9edf4228c7e9d26e732f9c488e839 Mon Sep 17 00:00:00 2001 From: Christian Bundy Date: Fri, 27 Mar 2020 09:13:31 -0700 Subject: [PATCH 4/4] Remove @ts-ignore workaround Problem: The workaround is no longer necessary now that the new version of @types/koa has been published. Thanks to @peterblazejewicz, @harryparkdotio, and @orta for the quick upstream fix. Solution: Run `npm update` and remove the `@ts-ignore` comment. --- package-lock.json | 21 ++++++++++++++++++--- package.json | 2 +- src/index.js | 5 ----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7cac1a7..da6b496 100644 --- a/package-lock.json +++ b/package-lock.json @@ -383,6 +383,12 @@ "@types/node": "*" } }, + "@types/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-GMyw/RJoCOSYqCDLgUnAByorkGY=", + "dev": true + }, "@types/cookies": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz", @@ -466,12 +472,13 @@ "dev": true }, "@types/koa": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.2.tgz", - "integrity": "sha512-2UPelagNNW6bnc1I5kIzluCaheXRA9S+NyOdXEFFj9Az7jc15ek5V03kb8OTbb3tdZ5i2BIJObe86PhHvpMolg==", + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.3.tgz", + "integrity": "sha512-ABxVkrNWa4O/Jp24EYI/hRNqEVRlhB9g09p48neQp4m3xL1TJtdWk2NyNQSMCU45ejeELMQZBYyfstyVvO2H3Q==", "dev": true, "requires": { "@types/accepts": "*", + "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", "@types/keygrip": "*", @@ -1246,6 +1253,7 @@ "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -3175,6 +3183,13 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", diff --git a/package.json b/package.json index f6be6e9..4636ed1 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "devDependencies": { "@types/debug": "^4.1.5", "@types/highlight.js": "^9.12.3", - "@types/koa": "^2.11.2", + "@types/koa": "^2.11.3", "@types/koa-mount": "^4.0.0", "@types/koa-static": "^4.0.1", "@types/koa__router": "^8.0.2", diff --git a/src/index.js b/src/index.js index 1cbad73..3dc322e 100755 --- a/src/index.js +++ b/src/index.js @@ -427,11 +427,6 @@ router } // This prevents an auto-download when visiting the URL. - // - // Using @ts-ignore to circumvent a bug: - // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/43357 - // - // @ts-ignore ctx.attachment(blobId, { type: "inline" }); // If we don't do this explicitly the browser downloads the SVG and thinks