{"_id":"unfig","_rev":"29-6c866fb1aeaf5a4d01f2bbd0769c08de","time":{"0.0.8":"2014-07-11T18:34:45.070Z","created":"2019-02-28T18:11:18.852Z","0.0.2-alpha.0":"2019-02-28T18:11:19.223Z","modified":"2022-05-22T18:10:19.265Z","0.0.3-alpha.0":"2019-04-25T21:09:37.923Z","0.0.4-alpha.0":"2019-07-06T14:47:07.830Z","0.0.5-alpha.0":"2019-07-22T21:21:41.192Z","0.0.9":"2019-07-24T12:41:19.405Z"},"name":"unfig","dist-tags":{"latest":"0.0.9"},"versions":{"0.0.2-alpha.0":{"name":"unfig","license":"MIT","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"version":"0.0.2-alpha.0","main":"lib/index.js","bin":{"unfig":"./lib/cli.js"},"scripts":{"unfig":"node ./lib/cli.js"},"dependencies":{"@unfig/find-monorepo":"^0.0.2-alpha.0","@unfig/find-pkg":"^0.0.2-alpha.0","@unfig/find-up":"^0.0.2-alpha.0","chalk":"^2.4.1","execa":"1.0.0","find-pkg":"^2.0.0","fs-extra":"^7.0.1","inquirer":"^6.2.1","inquirer-prompt-suggest":"^0.1.0","lint-staged":"^8.1.0","maxstache":"^1.0.7","npm-which":"3.0.1","validate-npm-package-name":"^3.0.0","yargs":"13.2.1","yargs-parser":"^13.0.0"},"devDependencies":{"@unfig/testutils":"^0.0.2-alpha.0","@unfig/toolkit-bare-node":"^0.0.2-alpha.0","@unfig/type-toolkit":"^0.0.2-alpha.0"},"engines":{"node":">=8.3"},"description":"**`unfig`** is a **_framework_** for creating toolkits.","_id":"unfig@0.0.2-alpha.0","_nodeVersion":"11.8.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-UpmH+f5jSfUfUgI471qbbWwyXegID9CM79kFKVTNtwgYcLBJlVO5I/t5cj8Zbb2gGFtRyq0WkwBOL8uu/x9bsQ==","shasum":"52d075f46523a278cccc409220d97752685189c3","tarball":"https://registry.npmjs.org/unfig/-/unfig-0.0.2-alpha.0.tgz","fileCount":36,"unpackedSize":50495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJceCRHCRA9TVsSAnZWagAA910P/RTAi5gWrHimW1zhJGiy\nv00Ts5zbyCw4/HG3/zoJOkCtnkSZwULAJqIIIK+ytuLN7SnxWvRmICVHQBqI\nWljoU7F97bk7BWDczxNGGzzJWjCj69bzfM+ZKVsTAIepjILu60Ve7OzNeH5t\nf9+fxMoS64rj+GzWCcDgKpxpTt73BXa2sImor3c6SDHKchA73DJdECb7i/CL\nyrxLF8//dSwogI72YfxeSeFgUyL2wud3cTsao6fIlOE2iaxVmPoZ9cpcFKnP\n3v69LmdO+GFm5vqZ44QPQbl5n9u2dSqz2UqlQ0U8//OKDJLLPit2+DN6bt5Z\nRMCrjmVG45nmjJeLCnnJ2vfRAYvxQrv9qkJSP4bOFyVBPqqu8HePct4EcbmJ\n9kllh0N9hUKO/nqk9NvL/0kDb9my43dAIpm5elcMhL9t0Su3qnZ9Nce8o+X8\nApOlnml56nr/O/+XhnURgSKM046HfmDGqeLu8qiQP+uGAaks4zYLZUPN/zbp\nfZ7G6GAQ4pzKTA700Wn/gmPrqbiUNxHZj8RFmIqwAS2cCgwlxNLkVABJKhyw\nxXvGmPP+B3WsN1O01SNkfpDZOaa6wSoAw2fxembNaMHvzYE8QhAcKllefwx7\njumEnoTqKae6+bJD/wIIUHe2DB7D3iIoU4WpOIP0ROedNLgGvxaNfX7EoFdS\nF7H8\r\n=CAT3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSQBGpgWYV3Ppa3E9hXFFCHwulUZ7xhCQPdOKjgfKuowIhAL/Z//rSZ1ET2mMniUUYqmuRBxEvBRNvRDdXd2V1swsZ"}]},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"_npmUser":{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/unfig_0.0.2-alpha.0_1551377478853_0.9298789307301916"},"_hasShrinkwrap":false},"0.0.3-alpha.0":{"name":"unfig","license":"MIT","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"version":"0.0.3-alpha.0","main":"lib/index.js","bin":{"unfig":"./lib/cli.js"},"scripts":{"unfig":"node ./lib/cli.js"},"dependencies":{"@unfig/find-monorepo":"^0.0.3-alpha.0","@unfig/find-pkg":"^0.0.3-alpha.0","@unfig/find-up":"^0.0.3-alpha.0","chalk":"^2.4.1","execa":"1.0.0","find-pkg":"^2.0.0","fs-extra":"^7.0.1","inquirer":"^6.2.1","inquirer-prompt-suggest":"^0.1.0","lint-staged":"^8.1.0","maxstache":"^1.0.7","npm-which":"3.0.1","validate-npm-package-name":"^3.0.0","yargs":"13.2.1","yargs-parser":"^13.0.0"},"devDependencies":{"@unfig/testutils":"^0.0.3-alpha.0","@unfig/toolkit-bare-node":"^0.0.3-alpha.0","@unfig/type-toolkit":"^0.0.3-alpha.0"},"engines":{"node":">=8.3"},"gitHead":"02a35cdcec62a6e7b956397950ffced9707aa458","description":"**`unfig`** is a **_framework_** for toolkits.","_id":"unfig@0.0.3-alpha.0","_nodeVersion":"11.8.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-JwxFQWlHl76kAPfIQWxaSDzp99VF2R6W0heN8ivy0x0g5UlIlVDweWxwcncab+JlGfv4L/GSr7C4p3fEtEbjQQ==","shasum":"a9d3a7d33f935deaec2a2279bedfdd33ecf11480","tarball":"https://registry.npmjs.org/unfig/-/unfig-0.0.3-alpha.0.tgz","fileCount":35,"unpackedSize":57985,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcwiISCRA9TVsSAnZWagAA4FUP/RnX7n9AfP5g2ZPzsj/D\nG/jWfRzsbf99pTwZQXCD5D2PmA/+8AW0drMawhN+KR6Q5WdAmqIZLg7vNwZ7\na3SS5rzk1Bj5o4gnk3WDSjuVakFYkH7XH3c63HReNVF8xtBJeHmurIbOKBs4\nDyp7EeX1eQ2zIV6p1iBY62ODgHQfEyyqL6sspgyGL5gZSY8F+kSfyefoL3T6\nUAH9JvSQ1oTnrjU0En/YGvk23/WP7Da4oHwkByMZB5A+oq2OrufRNbepROHX\nwm3+2G65yg2HhumsHIF3E6n9F7RaYPy2ECMbkiPdTkx6cbYv0HlF9zUkXakv\nI0a9ZEXGq34W0j/67EG81MJ1S46rxnvaDfovfmf/3oo4P8NOqH9CACr748zW\nh42L/iMcoGDw74Myme3gvKScoYfMGiboTZWIwZ31dy5MIrwUF6lBbgw42nnF\n4GmYKNRc/tlzabseMOMbJ6DpWqUrTAKejWuTfzG22y4YU2UIzxukDTFJmcOX\nUJ6z6/XUgRG9cshaXUKvWSENjsHTBH9Vbd2YzbGLE+LNWXYAU+71rvj4Y2lk\n/f+9X6SXiKxuDPqwPFDg33LEtMk1SVtXvvcTiX8Qqw1xVHWaB+TlRT6Dmpwj\nY/c3QH+zpxFmKcG/PR8k0ikZCHxyLS5C6evwOgkgxJdMMBlQHaoO/xpqzqtE\nb7DS\r\n=b+dc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrXEGOyiedovh6WIFIVC9xV8jwB7ZOEoSeVtLnE3kKmQIgOxCV4gdlj10XAPMAXCAgYp6Hl2hCgAz8B3yXLejjB4U="}]},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"_npmUser":{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/unfig_0.0.3-alpha.0_1556226577809_0.71361881571092"},"_hasShrinkwrap":false},"0.0.4-alpha.0":{"name":"unfig","license":"MIT","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"version":"0.0.4-alpha.0","main":"lib/index.js","bin":{"unfig":"./lib/cli.js"},"scripts":{"unfig":"node ./lib/cli.js"},"dependencies":{"@unfig/find-monorepo":"^0.0.4-alpha.0","@unfig/find-pkg":"^0.0.4-alpha.0","@unfig/find-up":"^0.0.4-alpha.0","chalk":"^2.4.1","execa":"1.0.0","find-pkg":"^2.0.0","fs-extra":"^7.0.1","inquirer":"^6.2.1","inquirer-prompt-suggest":"^0.1.0","lint-staged":"^8.1.0","maxstache":"^1.0.7","npm-which":"3.0.1","validate-npm-package-name":"^3.0.0","yargs":"13.2.1","yargs-parser":"^13.0.0"},"devDependencies":{"@unfig/testutils":"^0.0.4-alpha.0","@unfig/toolkit-bare-node":"^0.0.5-alpha.0","@unfig/type-toolkit":"^0.0.3-alpha.0"},"engines":{"node":">=8.3"},"description":"**`unfig`** is a **_framework_** for toolkits.","_id":"unfig@0.0.4-alpha.0","_nodeVersion":"11.8.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-6D0kEgRIVH+1Py+/ZO/q72oQFdGtioEhht6DhZTcXNqTrjFOeoeP8nRkfjqlXM+49E7LZfz4lvqjC/ajA6AjSA==","shasum":"b4079c74b3ee661d598ebce54a6c9b128519aca3","tarball":"https://registry.npmjs.org/unfig/-/unfig-0.0.4-alpha.0.tgz","fileCount":35,"unpackedSize":57928,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdILRsCRA9TVsSAnZWagAARgwP/iwbgOZDZAc9/QAKAoxV\nR4L0823i5K94j/F50GqadhpzFeeuhOUGwfVzI2amKVhwSicIIxdgWn4GrXeE\nRJjb7+VpHEPp906wuymQpaUsASm1NB2/KsDuQPOUrHHnDTP4roOl7v24O95X\nPJFzOaMUGGgWVy31J+dxp+yy7eSey84wZMZSvvzIXwDs4MfSjGubO3jmIQBJ\n4G4K9P2kS1ZQN06WA/M3+4yf1BwZH/mFbOfKvM78UFyn4nuorVj9HyflgI8H\nO3mbWcz4yzoq3Tv78X0V0RwMp4YJXjNEiUNge81PkJbr7Yv1rdqKuXanLuMT\nmyHe4AtANM+9UOU6pBX1zrGeUdje2eXEkYUmQvvU2eM+3SZEU9NCIS5ufCz2\n4dk4Acgl6lji6ICF2Ecj9dHwi9AFStfHElJIUtHtEcLFrY0bbCiWCnwBfoW1\nLzLl/yYsuikn92lNennPZxNho43JyDLz/MSgukm8PBs0Hd8kVxhwta4hz9te\nN7lxKzX7P3SE6ejF6TF9y2mfOuHjMKnaZLwEO++lFmnjtlrGbYanzjPOZnHx\ncn5JNG54bp3Q4qqAwO81wL9OpzKjJ0WtvqDIUDy2xxXVvmc+aXlPLdWs7Fmb\n52Q4Hu4mowKELGMU5rdRu0HOZvekh1gUSi1NgKeTDqcLaoFpuf4eC3ArNUS8\nqhHV\r\n=dy1/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSEA9hMdCXrhSGAlJ/wOEZ7GFdRxMj0bYN18b4w30zuwIhAO7qhi+oqrtNferp8Gk7z2RkLrblzjSZX5J4/Xid85hI"}]},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"_npmUser":{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/unfig_0.0.4-alpha.0_1562424427723_0.6701842920973702"},"_hasShrinkwrap":false},"0.0.5-alpha.0":{"name":"unfig","license":"MIT","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"version":"0.0.5-alpha.0","main":"lib/index.js","bin":{"unfig":"./lib/cli.js"},"scripts":{"unfig":"node ./lib/cli.js"},"dependencies":{"@unfig/find-monorepo":"^0.0.5-alpha.0","@unfig/find-pkg":"^0.0.5-alpha.0","@unfig/find-up":"^0.0.5-alpha.0","chalk":"^2.4.1","execa":"1.0.0","find-pkg":"^2.0.0","fs-extra":"^7.0.1","inquirer":"^6.2.1","inquirer-prompt-suggest":"^0.1.0","lint-staged":"^8.1.0","maxstache":"^1.0.7","npm-which":"3.0.1","validate-npm-package-name":"^3.0.0","yargs":"13.2.1","yargs-parser":"^13.0.0"},"devDependencies":{"@unfig/testutils":"^0.0.4-alpha.0","@unfig/toolkit-bare-node":"^0.0.6-alpha.0","@unfig/type-toolkit":"^0.0.3-alpha.0"},"engines":{"node":">=8.3"},"description":"**`unfig`** is a **_framework_** for toolkits.","_id":"unfig@0.0.5-alpha.0","_nodeVersion":"11.8.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-v7581DyTm/dgvv9U53ss0StxbIHX7L9vfOPo8iMaNXHDeZ3umAxfOPezZugl7O4LbQJo5cRiGg/VgWVL/bhKww==","shasum":"5bac631390f808f0596d615cc2d500d2b96ea080","tarball":"https://registry.npmjs.org/unfig/-/unfig-0.0.5-alpha.0.tgz","fileCount":35,"unpackedSize":59740,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdNijlCRA9TVsSAnZWagAASnIP/3vAQXrPwka0I6TyvWXs\nFmWmXJOYWAgBUEuRad/dKoXkm1jbnRNQfPVS2ZTxeIj5o3IB0pjFeUtE6czo\n8T0PgquQfhDxQJjD4aIsvPU0gNu7npiiK1z8Y5512HDnUzPxsW22nJ84KRTe\nUX2e6yoLURUn//MPCzNKK45q3eILCTxoDo2ty2ibeJsJx7IFeuox2+owDOS7\nwTrczYMd9ENFKPR6NBLEWdW/OaQGnXbuDOz3LljuBZrDD+Sl+kN0GfAy4gH+\nDlN0rjJBv9zGiH0LEe2cRotO7Rjf+/TtspNvE2Q9mvHLWmaOFy/JctocsjYS\nRtevbUPM/soMFYB8m/rtg3kqT87AFaKdKhLxOgTjFMBR6UhijdQHElxVkoaW\nKwRowF2xMSYA0CNBIh6rqnu9qdK47DgBopL/tO2QFKon7pHgq1YvvN72Z5iZ\nLvJ1wDClsd3FY201n83kdNNCO3PQi6wpDH+C5INFOr7aYgucqCJkkQ9W4lc9\naHbsMjGQ8F/DmAE0GgaA4efTvwhkBGiCI2krSa42Qx9vZn4Ey2f2hGZhhdX2\nydqV0SK+wnNmKibWt8SUqZ+z+FUCScKmlEPTcSRmbJkKTTK0nu2BpieLgq6X\nn/LxJmBLI5MNZTEMMquUancTLXYInL/fUYuukuEwwWVD5hIADCm4gxhK3snb\nMdqP\r\n=U0tq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBS8KWXHbYC4awlMwSeb5N/AtGJ71yF89HdpC1ySFWD7AiEAmrFN951cG8slDCe7XoB6dpEroCNah0mWQJOM3tI8ZnU="}]},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"_npmUser":{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/unfig_0.0.5-alpha.0_1563830501014_0.46838735699861456"},"_hasShrinkwrap":false},"0.0.9":{"name":"unfig","license":"MIT","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"version":"0.0.9","main":"lib/index.js","bin":{"unfig":"./lib/cli.js"},"scripts":{"unfig":"node ./lib/cli.js"},"dependencies":{"@unfig/find-monorepo":"0.0.9","@unfig/find-pkg":"0.0.9","@unfig/find-up":"0.0.9","chalk":"^2.4.1","execa":"1.0.0","find-pkg":"^2.0.0","fs-extra":"^7.0.1","inquirer":"^6.2.1","inquirer-prompt-suggest":"^0.1.0","lint-staged":"^8.1.0","maxstache":"^1.0.7","npm-which":"3.0.1","validate-npm-package-name":"^3.0.0","yargs":"13.2.1","yargs-parser":"^13.0.0"},"devDependencies":{"@unfig/testutils":"0.0.9","@unfig/toolkit-bare-node":"0.0.9","@unfig/type-toolkit":"0.0.9"},"engines":{"node":">=8.3"},"description":"**`unfig`** is a **_framework_** for toolkits.","_id":"unfig@0.0.9","_nodeVersion":"11.8.0","_npmVersion":"6.8.0","_npmUser":{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"},"dist":{"integrity":"sha512-BztfzHg8H/kQ4x11RqwlVhC5wA020c0Z23xagzpV85dxElkC/27m3hNaJuPzaGvCHKna0XfRKLDkdEhdsiN5GQ==","shasum":"87132c3b4791d47ae934eccd6e6f65ddeb0a1f8b","tarball":"https://registry.npmjs.org/unfig/-/unfig-0.0.9.tgz","fileCount":35,"unpackedSize":59678,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdOFHvCRA9TVsSAnZWagAA3gkP/Rwm7zOJ8idbLSI8Mtcm\nU5o7rQ1gXynYb0rBQvSJZTesFnC0UfRCgbCsIMTT93otpPJl0gSxkPe5wr4T\nfv3+PTGu+63SYRtLnVSv8zqee5n85tn6cehdfX1ArZerpmbbKCGfd505OM53\nXYGH+o9/4cxYJUbp1v0sjXCzT4bAyu+lnmts12MsDqllnf9hV/j6vGFARHHt\nATYKbX0u7PPn9PAZq4qgAolBLFBRziF+IWSPhoYQGO9uhc4AdTlMYsXj63y0\nboea4S0kbPxiEFyUoYYctiEG/LEXYUg1Ynj/EgC+7ZIICEDW61bEOnEdZ483\n9edbaGHmGN5p5Q4pqfXsCs0b5HOMpDxiStSKW0NlCi1HrooH8l9UfVNiTBFv\nyIvJc+/bO5dy5+WNLAsf867R4sF4+dDbRTLdMlz13axvgAWWyw8D9d/IgOLA\n5atpOBlH1UDhCAUHrxgK0m3K8CbQM1R/m9kPuL/Lh65QNcoUlkHRoS0W/On8\n/Zib6ipo556NgOiwFG8ohUBk3R409vGKqdKcs7PGPh8OIDwtQN/SmDqRCFyg\nyKNzYIGNoCZbWyqNP8fysW5BA06Fu2v88dZe+oGFVYQ1VqeWQIX5LOEWKnid\nWkgghI0O3vWrWHN9MkjXcjscOYauTg25dpKkqm4oSiqaojDXVnxlM9KJ+tFc\nt+WO\r\n=FqeU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD4ZRqwmk6txskJz9JtUk6m4VPufzpZw5mBuPAUPr/uKgIgbSc+7e5ZwST9JfFBJcM+mdETCdXxO4oa8UCzNrOeelU="}]},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/unfig_0.0.9_1563972079228_0.7370727726683133"},"_hasShrinkwrap":false}},"maintainers":[{"name":"bradfordlemley","email":"bradfordlemley@gmail.com"}],"description":"**`unfig`** is a **_framework_** for toolkits.","author":{"name":"Bradford Lemley","email":"bradfordlemley@gmail.com"},"license":"MIT","readme":"# unfig\n\n**`unfig`** is a **_framework_** for toolkits.\n\n* **`unfig`** naturally supports **modularity**, **extendability**, **customizability**, and **configurability**.\n\n* **`unfig`** makes **no presumptions** about the functionality that toolkits provide.\n\nThe **`unfig`** philosophy is that toolkits should enable developers to quickly set up projects and support **_everything_** needed to develop and maintain **_quality_** projects, much more functionality than is typically included in [current-generation toolkits](#Current-generation_Toolkits).\n\n* The challenge is that, despite many similarties, every project can be different and developers don't want to be locked in to a toolkit.\n* `unfig` addresses this challenge by building **modularity**, **extendability**, **customizability**, and **configurability** into the framework.\n\nThe **`unfig`** theory is that a **framework** that naturally supports these features can enable a proliferation of **_quality_** **_full-featured_** **toolkits**.\n* Projects can adopt toolkits without concern of lock-in because escape hatches are built in.\n* Toolkits can evolve quickly to enable projects of the future because new toolkits can easily be built, pulling in functionality from existing toolkits.\n\n## Overview\n \nThe **`unfig`** framework is simple.  All functionality comes from **`toolkits`**.\n\n**`unfig` toolkits** provide:\n* **`commands`**, which can be invoked by the user, like `build`.\n* **`configurations`**, which are tool configurations, like `.babelrc.js`.\n* **`dependencies`**, which are tools used by the toolkit, like `babel`.\n\nThe **`unfig`** framework enables toolkits to utilize other toolkits -- to configure them, inherit their functionality, and/or customize their **`commands`**, **`configurations`**, and **`dependencies`**.\n\nA key part of the **`unfig`** framework is that **`configurations` exist as _standard configuration files on disk_ in projects**.\n\nThis allows the `configurations` to integrate seemlessly with tools in the ecosystem.  Generally, standard tools don't need to be integrated into `unfig`, they \"just work\".\n\nSee more details about [configurations](#configurations) and [dependencies](#dependencies) below.\n\n## Usage\n\nEnd users can utilzie a **toolkit** in their project by invoking one of the commands below.\n\n**`npx unfig create [dir] [--toolkit=<toolkit>]`**\nCreate a new project using the specified toolkit. (User will be queried for dir and toolkit if not provided.)\n\n**`npx unfig init [--toolkit=<toolkit>]`**\nUse specified toolkit in an existing project. (User will be queried for toolkit if not provided.)\n\n**`commands`** provided by the **toolkit** are shown in **`unfig help`**.\n\n## Toolkits\n\nAn **`unfig` toolkit** is a javascript function that takes a configuration object and returns an object with **`commands`** and **`configurations`** and **`toolDependencies`**.\n\n```js\n// shape of an unfig toolkit module\nmodule.exports = config => ({\n  commands: {},\n  configurations: {},\n  toolDependencies: {},\n})\n```\n\n### Toolkit Type Definition\nThe complete flow type definition for a toolkit can be found [here](https://github.com/bradfordlemley/unfig/blob/33e549d111a8508cec176afd5c853b52df44fff8/packages/type-toolkit/index.js.flow#L66).\n\n### Real Toolkit Examples\nSeveral real toolkits are included in the `unfig` monorepo.\n\nThe monorepo contains a simple toolkits for each tool, e.g. `babel`, `eslint`, `jest`. These are generally very simple toolkits providing a single `command` and a single `configuration`.\n\n`react-comp` is a `toolkit` which supports a react component.\n\n`bare-node` is a `toolkit` which supports node scripts and is used by toolkits themselves.\n\n`monorepo` is a `toolkit` which can be installed at the top-level of a monorepo.\n\n### Demonstration Example\n\nThis contrived example shows two **toolkits**:\n\n**`toolkit-1`**\n- provides `cmd-1` and `config-1.js`\n\n**`toolkit-2`**\n- uses `toolkit-1` and `toolkit-3` (not shown).\n- modifies `config-1.js` (from `toolkit-1`).\n- provides `cmd-2` (which calls `cmd-1` from `toolkit-1`).\n- provides `config-2.js`.\n\n```js\n// toolkit-1\nmodule.exports = cfg => {\n  const { val } = cfg || { key: 'defaultVal' }; // default cfg\n  return {\n    commands: {\n      'cmd-1': {\n        description: 'Run cmd-1',\n        handler: ({ args }) => console.log(`Running cmd-1 with args: ${args}`),\n      },\n    },\n    configurations: {\n      'config-1.js': () => ({ key: val }), // <-- uses cfg here\n    },\n  };\n};\n```\n\n```js\n// toolkit-2\nmodule.exports = cfg => {\n  return {\n    toolkits: [\n      require('toolkit-1')(cfg), // use and configure toolkit-1\n      cfg.useToolkit3 && require('toolkit-3')(cfg), // conditionally use toolkit-3 (not shown)\n    ],\n    commands: {\n      'cmd-2': {\n        description: 'Run cmd-2',\n        handler: ({ args, toolkits }) => {\n          console.log('running cmd-2');\n          return toolkits.execCmd('cmd-1'); // call cmd-1 from toolkit-1\n        },\n      },\n    },\n    configurations: {\n      'config-1.js': ({ toolkits }) => ({\n        ...toolkits.getConfig('config-1.js'),\n        key2: 'val2', // add key2 to config1.js object from toolkit-1\n      }),\n      'config-2.js': () => ({ key: 'val' }),\n    },\n  };\n};\n```\n\n#### Using Example\nA project could use `toolkit-2` by running `npx unfig init --toolkit toolkit-2`.\n\nThe project would then contain `config-1.js` and `config-2.js`. See [configurations](#configurations) section for more info.\n\nThe user could invoke `cmd-1` by running `npx unfig cmd-1`.\n\nThe user could invoke `cmd-2` by running `npx unfig cmd-2`.\n\n## `Configurations`\n\n### Why are `configurations` special?\n\n- `configurations` exist as **standard configuration files on disk** in projects.\n  - `configurations` **automatically work with many tools in the ecosystem**.\n- `configurations` exist as **objects** within toolkits.\n  - `configurations` **can be modified by chains of toolkits**.\n\n### How do `configurations` work?\n\n1. `unfig init` creates `configuration` proxy files _on disk_.\n\nFor example, after `unfig init` a project might look like this:\n\n```sh\nmy-prj/\n  .babelrc.js\n  .eslintrc.js\n  jest.config.js\n```\n\n2. The `configuration` proxy files call into **`unfig`** to retrieve the actual configuration from toolkits.\n\nEach of these configuration files contains proxy code:\n\n```js\n// .babelrc.js, .eslintrc.js, jest.config.js, etc.\nmodule.exports = require('unfig').getConfig(__filename);\n```\n\n### How can `configurations` be modified?\n\n**`unfig`** **does not** provide tools or helpers to modify configs.\n\nIf your toolkit modifies `.babelrc.js` from another toolkit, you need to know details about how babel config works, and about the `.babelrc.js` config provided by the other toolkit.\n\nThere is no guarantee that your modifications will work for other versions of the toolkit.\n\nBasically, you are [monkey-patching](https://en.wikipedia.org/wiki/Monkey_patch) the `configuration`. Have a good name for this?\n\n### How can actual `configurations` be viewed?\n\n`node -p \"require('./.babelrc.js')\"`\n\nor\n\n`node -p \"JSON.stringify(require('./.babelrc.js'), null, 2)\"`\n\n## `Dependencies`\n`dependencies` specified by a toolkit end up installed as devDependencies in a project.\n\nThey serve two purposes:\n\n1.  They allow toolkits or end users to change/modify tool versions without requiring a new version of a toolkit.\n2.  They allow modules to be resolved when referenced from the project.\n\nFor example, this allows `babel` to work directly in the project, the same way it works when invoked from a toolkit.  `babel` version, and any plugins used by `.babelrc.js` configuration, can be modified by toolkits, or by the end user, and will be used whether `babel` is invoked directly from the project, or from a toolkit.\n\nNote: `unfig init` installs `dependencies` as `devDependencies`.  This modifies `devDependencies` in the project's package.json.\n\n# Current-generation Toolkits\n\n[create-react-app](https://github.com/facebook/create-react-app): AMAZING! And, yet, severely limiting. Your project will hit a brick wall if you need some functionality it doesn't provide. `Ejecting` leaves you unable to upgrade, `forking` is possible, but has significant complications, and `contributing` is a great option for some cases, but generally not available for customization.\n\n[material-ui](https://github.com/mui-org/material-ui), [formik](https://github.com/jaredpalmer/formik), [react-router](https://github.com/ReactTraining/react-router), [react-redux](https://github.com/reduxjs/react-redux), [downshift](https://github.com/downshift-js/downshift): All awesome! These are similiar projects (at least in that they all provide react components), yet they all use their own custom build systems and project setups. There isn't an equivalent of create-react-app for react components.\n\n# Todos\n\n- [ ] Support for specifying/installing tools\n  - Allow toolkits to specify a default set of tools@versions; allow the user to easily update versions; allow tools to be conditionally installed (performance).\n- [ ] Support for documenting toolkit config options and interactive configuration during `init`\n- [ ] Support for documenting command options\n- [ ] Support for initializing toolkit during `init`, e.g. scaffolding code.\n- [ ] Support for non-module configurations, e.g. .json configs\n- [ ] Support toolkit branding\n  - Allow unfig name to be hidden, e.g. `npx mytoolkit create`, `npx mytoolkit build`\n","readmeFilename":"README.md"}