diff --git a/package-lock.json b/package-lock.json index 61b8f65..6c556e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1072,6 +1072,13 @@ "integrity": "sha512-9HrZGFVTR5SOu3PZAnAY2hLO36aW1wmA+FDsVkr85BTST32TLCA1H/AEcatVRAsWLyXS3bqUDYCAjq5/QGuSTA==", "requires": { "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "node-dir": { @@ -1170,6 +1177,13 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } } }, "npmlog": { @@ -1667,9 +1681,9 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz", + "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==" }, "set-blocking": { "version": "2.0.0", diff --git a/package.json b/package.json index 1caafc0..9d63068 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "node-fetch": "^2.6.0", "pinski": "github:cloudrac3r/pinski#19495f7a1c62fbfd8c685cf5bb5d678788906032", "rss": "^1.2.2", + "semver": "^7.1.2", "sharp": "^0.24.0" } } diff --git a/src/site/api/api.js b/src/site/api/stats.js similarity index 53% rename from src/site/api/api.js rename to src/site/api/stats.js index e5afba6..625329f 100644 --- a/src/site/api/api.js +++ b/src/site/api/stats.js @@ -1,5 +1,7 @@ -const constants = require("../../lib/constants") +const semver = require("semver") const child_process = require("child_process") +const md = require("mixin-deep") +const constants = require("../../lib/constants") const {history} = require("../../lib/collectors") const {redirect} = require("pinski/plugins") @@ -11,6 +13,8 @@ function reply(statusCode, content) { } } +// Load current commit hash + let commit = "" { const p = child_process.spawn("git", ["rev-parse", "--short", "HEAD"]) @@ -21,6 +25,43 @@ let commit = "" }) } +// Set up inner versioning + +const displayVersions = ["1.0", "1.1", "1.2"] +const versions = new Map(displayVersions.map(v => [v, semver.coerce(v)])) +const features = [ + "PAGE_PROFILE", + "PAGE_POST", + "API_STATS", + "PAGE_HOME", + "API_INSTANCES", + "BLOCK_DETECT_USER_HTML" +] +const innerMap = new Map() +{ + const addVersion = function(shortVersion, block) { + const coerced = semver.coerce(shortVersion) + const previousVersion = semver.maxSatisfying([...innerMap.keys()], coerced.major+".x") + let previous = {} + if (previousVersion) previous = innerMap.get(previousVersion) + md(block, previous) + md(block, {version: shortVersion}) + innerMap.set(coerced.version, block) + } + addVersion("1.0", { + features + }) + addVersion("1.1", { + availableVersions: [...versions.keys()], + history: history.export() + }) + addVersion("1.2", { + settings: { + rssEnabled: constants.settings.rss_enabled + } + }) +} + module.exports = [ { route: "/.well-known/nodeinfo", methods: ["GET"], code: async ({fill}) => { @@ -41,43 +82,13 @@ module.exports = [ }, { route: "/api/stats/2.0", methods: ["GET"], code: async ({url}) => { - const versions = ["1.0", "1.1", "1.2"] - const features = [ - "PAGE_PROFILE", - "PAGE_POST", - "API_STATS", - "PAGE_HOME", - "API_INSTANCES", - "BLOCK_DETECT_USER_HTML" - ] - const inner = ( - new Map([ - ["1.0", { - version: "1.0", - features - }], - ["1.1", { - version: "1.1", - availableVersions: versions, - features, - history: history.export() - }], - ["1.2", { - version: "1.2", - availableVersions: versions, - features, - history: history.export(), - settings: { - rssEnabled: constants.settings.rss_enabled - } - }] - ]) - ).get(url.searchParams.get("bv") || versions[0]) - if (!inner) return reply(400, { + const selected = semver.maxSatisfying([...innerMap.keys()], url.searchParams.get("bv") || "1.0") + if (!selected) return reply(400, { status: "fail", fields: ["q:bv"], - message: "query parameter `bv` selects version, must be either missing or any of " + versions.map(v => "`"+v+"`").join(", ") + "." + message: "query parameter `bv` selects inner version, must be either missing or a semver query matching any of " + displayVersions.map(v => "`"+v+"`").join(", ") + "." }) + const inner = innerMap.get(selected) return reply(200, { version: "2.0", software: {