├── .gitignore ├── .prettierrc ├── test.js ├── example.js ├── LICENSE ├── package.json ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .nyc_output 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | "@jfhbrook/prettier-config-old-school" 2 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var tap = require('tap'); 2 | 3 | var hoarders = require('.'); 4 | 5 | tap.ok(hoarders.express, "express imports lol"); 6 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | var hoarders = require('.'); 2 | 3 | var app = hoarders.express(); 4 | 5 | app.get('/', function (req, res) { 6 | res.send('hello world!'); 7 | }); 8 | 9 | app.listen(3000, function () { 10 | console.log('listening on 3000!'); 11 | }); 12 | 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Tumbolia Public License 2 | 3 | Copyright Josh Holbrook, 2021 4 | 5 | Copying and distribution of this file, with or without modification, are 6 | permitted in any medium without royalty provided the copyright notice and 7 | this notice are preserved. 8 | 9 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 10 | 11 | 0. opan saurce LOL 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Josh Holbrook", 3 | "name": "hoarders", 4 | "description": "node.js's most complete \"utility grab-bag\". dedicated to substack.", 5 | "version": "1.1.2", 6 | "main": "./index.js", 7 | "homepage": "https://github.com/jfhbrook/hoarders", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/jfhbrook/hoarders.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/jfhbrook/hoarders/issues" 14 | }, 15 | "scripts": { 16 | "format": "prettier *.js *.json --write", 17 | "test": "tap test.js" 18 | }, 19 | "keywords": [ 20 | "hoarders", 21 | "utility", 22 | "grab-bag", 23 | "underscore", 24 | "substack", 25 | "lmao", 26 | "canceled", 27 | "banned" 28 | ], 29 | "devDependencies": { 30 | "@jfhbrook/prettier-config-old-school": "^0.1.0", 31 | "prettier": "^2.3.2", 32 | "tap": "^16.0.1" 33 | }, 34 | "tap": { 35 | "check-coverage": false 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var fs = require('fs'); 3 | var spawnSync = require('child_process').spawnSync; 4 | 5 | var log = process.logging ? process.logging : function () {}; 6 | 7 | // core modules 8 | exports.coreModules = [ 9 | 'assert', 10 | 'child_process', 11 | 'cluster', 12 | 'crypto', 13 | 'dgram', 14 | 'dns', 15 | 'domain', 16 | 'events', 17 | 'fs', 18 | 'http', 19 | 'https', 20 | 'net', 21 | 'path', 22 | 'readline', 23 | 'repl', 24 | 'stream', 25 | 'tls', 26 | 'tty', 27 | 'url', 28 | 'util', 29 | 'vm', 30 | 'zlib' 31 | ].reduce(function (acc, coreModule) { 32 | acc[coreModule] = true; 33 | return acc; 34 | }, {}); 35 | 36 | module.exports = new Proxy(exports, { 37 | get: function (target, prop, receiver) { 38 | return getModule(prop); 39 | } 40 | }); 41 | 42 | function getModule(moduleName) { 43 | if (moduleName === 'hoarders') { 44 | return module.exports; 45 | } 46 | var module = null; 47 | try { 48 | module = require(moduleName); 49 | } catch (err) { 50 | assert( 51 | !exports.coreModules[moduleName], 52 | 'a core module should require first try' 53 | ); 54 | log('error on first require(%module): %err', { 55 | err: err, 56 | module: moduleName 57 | }); 58 | log('attempting to npm install %module...', {module: moduleName}); 59 | var npmResult = spawnSync('npm', ['install', moduleName], { 60 | stdio: ['pipe', 'inherit', 'inherit'] 61 | }); 62 | if (npmResult.error) throw npmResult.error; 63 | if (npmResult.status) 64 | throw new Error('npm install returned status: ' + npmResult.status); 65 | module = require(moduleName); 66 | } 67 | return module; 68 | } 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hoarders 2 | 3 | ## node.js's most complete "utility grab-bag" 4 | # back after being **CANCELED** by **isaac** for **nearly a decade** 5 | ### dedicated to substack 6 | 7 | ![](http://i.imgur.com/WPB5l.jpg) 8 | 9 | # usage 10 | 11 | first, install hoarders: 12 | 13 | ```bash 14 | npm install hoarders 15 | ``` 16 | 17 | then, simply use the utilities exported by hoarders of your choice: 18 | 19 | ```js 20 | var hoarders = require('hoarders'); 21 | 22 | var app = hoarders.express(); 23 | 24 | app.get('/', function (req, res) { 25 | res.send('hello world!'); 26 | }); 27 | 28 | app.listen(3000, function () { 29 | console.log('listening on 3000!'); 30 | }); 31 | 32 | ``` 33 | 34 | and voila, a fully featured web server: 35 | 36 | ``` 37 | $ node example.js 38 | 39 | added 49 packages, and audited 100 packages in 2s 40 | 41 | 2 packages are looking for funding 42 | run `npm fund` for details 43 | 44 | found 0 vulnerabilities 45 | listening on 3000! 46 | ``` 47 | 48 | ## history 49 | 50 | in june of 2012, I wrote the first version of hoarders, node.js's most 51 | complete utility grab bag, as an answer to underscore's then-popularity. on a 52 | ux level, the project was a raging success. 53 | 54 | however, hoarders used to directly depend on every module on npm, which in 55 | 2012 was on the order of 20,000 modules. this caused a plethora of haters to 56 | [come out of the woodwork](https://github.com/jfhbrook/hoarders/issues/2), 57 | unable to contend with the raw power of the hoarders collection of utilities, 58 | and quickly began a campaign to CANCEL hoarders. 59 | 60 | after a year or more of fighting these slanderous claims of "not being 'cute'" 61 | and "a layer of unnecessary complexity that permeates the whole npm ecosystem", 62 | the death knell came from the BIGGEST HATER OF ALL, one ISAAC Z SCHLEUTER: 63 | 64 | ``` 65 | 08:21 < isaacs> jfhbrook: so... bad news. 66 | 08:21 < isaacs> jfhbrook: i think we're going to have to kill hoarders. 67 | 08:21 < isaacs> jfhbrook: probably going to put a limit of like 5000 dependencies in a package. 68 | 08:22 < fotoverite> Noooo! IT's taking up too much space in the database? 69 | 08:22 < isaacs> jfhbrook: every time there's a change to teh hoarders doc, it takes like 30 seconds for views to finish recompiling. 70 | 08:22 < isaacs> fotoverite: no, not space, it's taking up too much time in the database. 71 | 08:22 < isaacs> jfhbrook: i have a bunch of views that walk through all the deps in every package, making links and such 72 | 08:22 < fotoverite> Time exists in a database. :P Wow 73 | 08:23 < isaacs> i just starred and unstarred it. 74 | 08:23 < isaacs> just because the doc was touched, couch had to do a ton of work, and it was like.. not trivial. 75 | 08:23 < isaacs> maybe 30 seconds of downtime or so. 76 | 08:23 < defunctzombie> hahaha 77 | 08:23 < ralphtheninja> lol 78 | 08:24 < isaacs> most things still would work fine, but anything that hit a view (search, stars, last updated, etc.) was awol 79 | 08:24 < chrisdickinson> split into multiple packages and then make one package that requires each hoarders subset? 80 | 08:24 < isaacs> chrisdickinson: yeah, i think jfhbrook will still be able to "install every package" just fine 81 | 08:24 < ralphtheninja> star/unstar/star/unstar/star/unstar .. the new ddos attack :) 82 | 08:24 -!- mikolalysenko [~mikolalys@76-232-30-51.lightspeed.cicril.sbcglobal.net] has quit [Ping timeout: 255 seconds] 83 | 08:24 < fotoverite> Maybe the joke has run its course though 84 | 08:24 < isaacs> but it'll have to be like a hoarders-a hoarders-b hoarders-c... 85 | 08:25 < jfhbrook> isaacs: I see 86 | 08:25 < fotoverite> I think the new one is creating the package NO that removes core things from node and put it outside itself. And then allows nothing else to be required. :P 87 | 08:25 < jfhbrook> isaacs: It's not worth it to me to do anything fancy to get around that, so like 88 | 08:25 < isaacs> jfhbrook: i'm going to push the update to limit the number of deps 89 | 08:25 < isaacs> jfhbrook: but... it's your dog. you wanna be the one to put him down? 90 | 08:25 < jfhbrook> isaacs: npm unpublish? 91 | 08:25 < isaacs> (yeah, it's not like hoarders was ever anything but a joke anyway) 92 | 08:26 < isaacs> jfhbrook: with the -f 93 | 08:26 < isaacs> or --gangsta 94 | 08:26 < jfhbrook> a'ight 95 | 08:26 < isaacs> go with --gangsta 96 | 08:26 < isaacs> it's hella tight 97 | 08:26 < fotoverite> Yes go with gangsta 98 | 08:26 < ralphtheninja> :) 99 | 08:26 < ralphtheninja> I can't watch 100 | 08:27 < isaacs> it's ok hoarders... we're gonna go out to a nice farm. and you'll have room to run.... and rabbits to chase..... 101 | 08:27 < jfhbrook> isaacs: doing my best to unpublish, internet here really sucks 102 | 08:27 * isaacs sniff 103 | 08:27 < jfhbrook> isaacs: you can pass a git url to npm yeah? 104 | 08:27 < isaacs> jfhbrook: yeah 105 | 08:27 < jfhbrook> isaacs: npm install git+ssh://and-so-on 106 | 08:28 < isaacs> jfhbrook: i'm unpublishing it 107 | 08:28 < isaacs> jesus, even just getting the doc is insane 108 | 08:29 < jfhbrook> isaacs: ouch 109 | 08:31 < isaacs> ok, i unpublished it 110 | 08:31 < isaacs> $ npm unpublish hoarders --gangsta 111 | 08:31 < isaacs> npm WARN using --force I sure hope you know what you are doing. 112 | 08:31 < isaacs> <3 that warning ^ 113 | 08:31 < isaacs> i'ts so OMINOUS! 114 | 08:34 < isaacs> if (++n > max) 115 | 08:34 < isaacs> assert(false, "too many deps. please be less ridiculous.") 116 | 08:34 < isaacs> lol 117 | 08:34 < isaacs> can't wait for someone to post a bug about that 118 | 08:34 < isaacs> I SHOULD BE ALLOWED TO BE AS RIDICULOUS AS I'D LIKE! WHO ARE YOU TO RESTRICT MY FREEDOM? 119 | 08:34 < LOUDBOT> GOOGLE WAVE INVITES! I'VE GOT PLENTY 120 | ``` 121 | 122 | (minor edits to the logs for clarity, but this conversation really happened.) 123 | 124 | ### but now, after NINE YEARS, I've found a WORK-AROUND. 125 | 126 | now, rather than installing the utilities as direct dependencies, hoarders 127 | installs them lazily, on-the-fly. this change is practically seamless - simply 128 | reach for the utility like you would normally and hoarders will do the rest! 129 | the only requirements are `npm` and an internet connection. 130 | 131 | ## they might try to CENSOR us but they WON'T SILENCE US. :triumph: 132 | 133 | ## license 134 | 135 | this project is published under the well known and venerated tumbolia public 136 | license: 137 | 138 | ``` 139 | Tumbolia Public License 140 | 141 | Copyright Josh Holbrook, 2021 142 | 143 | Copying and distribution of this file, with or without modification, are 144 | permitted in any medium without royalty provided the copyright notice and 145 | this notice are preserved. 146 | 147 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 148 | 149 | 0. opan saurce LOL 150 | ``` 151 | 152 | enjoy. 153 | --------------------------------------------------------------------------------