Track your Node package downloads
Use Node-RED v1.1+ to keep track of how many downloads your NPM packages get per day.
Uses the newer Inject node features to avoid needing an extra Change node. Also uses the $moment
feature of JSONata to select and format the appropriate date range.
This is fed into a request node and from there to a function node that accumulates the daily data into an object:
global-var -> by package-name -> downloads-by-day
A summary of the date ranges and total downloads is also kept.
You can only download a maximum of 12 months when selecting multiple packages but the data goes back to 2015-01-10. I manually downloaded all of the previous years but you can just change the date range in the inject node as it uses MomentJS's very easy to follow format, subtracting days from today.
It doesn't hurt to rerun the query over dates you've already included, the duplicates are ignored.
Make sure you change the date range and package names in the inject node before running.
You may also want to change the global variable settings at the top of the function node.
The flow example given here runs once a week on a Sunday at 00:01 and captures the last 8 days.
[{"id":"e514269e.74fb58","type":"debug","z":"a851b997.a01c18","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":715,"y":1220,"wires":[],"l":false},{"id":"893de9f.e508e18","type":"function","z":"a851b997.a01c18","name":"","func":"const myNpmStats = 'myNpmStats'\nconst fileStore = 'file'\n\nconst out = global.get(myNpmStats, fileStore) || {}\n\nObject.keys(msg.payload).forEach( package => {\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 msg.payload[package].downloads.forEach( entry => {\n \n // Loose 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})\n\nglobal.set(myNpmStats, out, fileStore)\nmsg.payload = out\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":655,"y":1220,"wires":[["e514269e.74fb58"]],"l":false},{"id":"9a41f93d.2035f8","type":"inject","z":"a851b997.a01c18","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":"","x":360,"y":1220,"wires":[["d2b0e949.dc6a38"]]},{"id":"d2b0e949.dc6a38","type":"http request","z":"a851b997.a01c18","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":535,"y":1220,"wires":[["893de9f.e508e18"]],"l":false}]