Unable to load Node Pallete to install nodes because cloud flare is blocking https://catalogue.nodered.org/catalogue.json due to Invalid SSL Error.
Hi - we're aware of this. Waiting for GitHub to update the certs... not seen this behaviour before, but it's out of our hands currently.
The issue is now resolved. The catalogue is available again.
Is that little side effect related - download counters have been drop down near zero on flows site
It's NPM, it happens from time to time.
The TLS issues aren't related to the download stats.
Here's the graph of daily downloads for a popular node as according to the npm stats api:
Steadily around the 2k/day and then a few days of 0. I see this pattern for non-Node-RED related modules as well:
Suggests an issue with the npm stats collection itself.
Thankyou!!!!
For info, if anyone wants a simple flow to grab the npm stats for their own repo's, I have one.
[{"id":"927aebc8.166678","type":"group","z":"9bbe96e.8c46268","name":"Get NPM Stats","style":{"label":true},"nodes":["bef515f0.68f458","f54151ce.8098c","4748641a.b0c31c","ab737833.48b668","c5d5026d9c3ae2db"],"x":34,"y":39,"w":542,"h":122,"info":"https://discourse.nodered.org/t/track-downloads-of-your-npm-packages-using-node-red/33637\n\nhttps://flows.nodered.org/flow/7d12342915ec522056f0d250be9bfcb6\n\nhttps://api.npmjs.org/downloads/range/2019-10-02:2020-09-30/node-red-contrib-uibuilder,node-red-contrib-moment,node-red-contrib-globalgetset,node-red-contrib-fs,node-red-contrib-jktesting,node-red-contrib-static-markdown,alternate-node-red-installer\n\nData goes back to 2015-01-10\n\nOnly get 365d at a time max."},{"id":"bef515f0.68f458","type":"debug","z":"9bbe96e.8c46268","g":"927aebc8.166678","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":515,"y":80,"wires":[],"l":false},{"id":"f54151ce.8098c","type":"function","z":"9bbe96e.8c46268","g":"927aebc8.166678","name":"","func":"const myNpmStats = 'myNpmStats'\nconst fileStore = 'file'\n\nconst out = global.get(myNpmStats, fileStore) || {}\n\nfunction pkg(package, details) {\n\n if (!out[package]) {\n out[package] = {\n 'downloads': {},\n 'package': package,\n 'start': '',\n 'end': '',\n 'days': 0,\n 'totalDownloads': 0,\n }\n }\n\n details.downloads.forEach(entry => {\n\n // Lose any zeros until the first download\n if (out[package].totalDownloads === 0) {\n if (entry.downloads === 0) return\n }\n\n // If this day has already been recorded, skip\n if (entry.day in out[package].downloads) return\n\n out[package].downloads[entry.day] = {\n 'date': entry.day,\n 'downloads': entry.downloads,\n }\n\n out[package].totalDownloads += entry.downloads\n\n if (entry.day < out[package].start || out[package].start === '') out[package].start = entry.day\n if (entry.day > out[package].end) out[package].end = entry.day\n\n //out[package].days++\n\n })\n\n out[package].days = Object.keys(out[package].downloads).length\n out[package].years = Math.round(100 * out[package].days / 365.25) / 100\n out[package].months = Math.round(out[package].years * 12)\n\n try {\n out[package].avgDlPerDay = Math.round(out[package].totalDownloads / out[package].days)\n } catch (e) { }\n try {\n out[package].avgDlPerMonth = Math.round(out[package].totalDownloads / out[package].months)\n } catch (e) { }\n try {\n out[package].avgDlPerYear = Math.round(out[package].totalDownloads / out[package].years)\n } catch (e) { }\n\n} // ---- End of pkg() ---- //\n\nif ( !msg.payload.start ) {\n // Assume payload is an object with 1 entry per package, multiple packages\n Object.keys(msg.payload).forEach( package => {\n pkg(package, msg.payload[package])\n })\n} else {\n // If it isn't, assume it is 1 package only\n node.warn(msg.payload.package)\n pkg(msg.payload.package, msg.payload)\n}\n\nglobal.set(myNpmStats, out, fileStore)\nmsg.payload = out\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":455,"y":80,"wires":[["bef515f0.68f458"]],"l":false},{"id":"4748641a.b0c31c","type":"inject","z":"9bbe96e.8c46268","g":"927aebc8.166678","name":"URL/Date-Range/package-set","props":[{"p":"url","v":"\"https://api.npmjs.org/downloads/range/\" & \t\t$moment().subtract(8, 'days').format(\"YYYY-MM-DD\")\t\t& \":\" &\t\t$moment().subtract(1, 'days').format(\"YYYY-MM-DD\")\t\t& \"/\" &\t\t$join([\t \"node-red-contrib-uibuilder\",\t \"node-red-contrib-moment\",\t \"node-red-contrib-globalgetset\",\t \"node-red-contrib-fs\",\t \"node-red-contrib-jktesting\",\t \"node-red-contrib-static-markdown\",\t \"alternate-node-red-installer\"\t ], \",\")\t","vt":"jsonata"}],"repeat":"","crontab":"01 00 * * 0","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":220,"y":80,"wires":[["ab737833.48b668"]]},{"id":"ab737833.48b668","type":"http request","z":"9bbe96e.8c46268","g":"927aebc8.166678","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":395,"y":80,"wires":[["f54151ce.8098c","4a4b8ed2.8cb7b"]],"l":false},{"id":"c5d5026d9c3ae2db","type":"inject","z":"9bbe96e.8c46268","g":"927aebc8.166678","name":"URL/Date-Range/package-set","props":[{"p":"url","v":"\"https://api.npmjs.org/downloads/range/\" & \t\t$moment().subtract(8, 'days').format(\"YYYY-MM-DD\")\t\t& \":\" &\t\t$moment().subtract(1, 'days').format(\"YYYY-MM-DD\")\t\t& \"/@totallyinformation/node-red-contrib-events\"\t","vt":"jsonata"}],"repeat":"","crontab":"03 00 * * 0","once":false,"onceDelay":0.1,"topic":"","x":210,"y":120,"wires":[["ab737833.48b668"]]}]
You will need to change the package names of course.
Did you forget the flow JSON?
Nope
Didn't want to post that unless someone actually wanted it.
Someone in the future may want it. You may not be available then. No harm in posting it.
Whilst I don't have a flow to share, the underlying URL to use is:
https://api.npmjs.org/versions/node-red/last-week
(replace node-red
with your module of choice).
This returns a JSON blob:
{
"package": "node-red",
"downloads": {
"4.0.5": 4,
"4.0.2": 1,
"1.2.7": 1,
"3.1.14": 3,
"1.3.7": 4,
"4.0.8": 88,
"4.0.3": 1,
"3.1.15": 3,
"3.1.3": 1,
"0.20.8": 1,
"1.3.2": 1,
"0.18.7": 1,
"3.0.2": 6,
"1.0.6": 1,
"1.0.3": 2
}
}