{"_id":"beech-api","_rev":"513-b55bfef2b7a3c50ec790be0aef40a194","name":"beech-api","dist-tags":{"latest":"3.9.80"},"versions":{"3.0.41":{"name":"beech-api","version":"3.0.41","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.0.41","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"./packages/cli/core/generator/index.js","beech-app":"./packages/cli/bin/beech.js"},"dist":{"shasum":"878480335caf6c78594f14a87f86e49e566d2436","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.0.41.tgz","fileCount":16,"integrity":"sha512-/zN4vfJ5WVAomdTn8dOjKNlxn6NYEGDNNs44NP1lX6UlJWkw78Ps5kIWixHEQaSheUHmrqwmFzFBMrKMZzyTFA==","signatures":[{"sig":"MEYCIQCooM8ZQ00BTPYvTVkrYmDNZltnyQiWrCt+wz6d7Q65WgIhAKz4Fl9X13tu3NwqcKJUDC1PYKjuJ8tXxuyd6Sai/Ik3","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":32572,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJegaz7CRA9TVsSAnZWagAAGu0P/2pIG+OZ7aAgZ6mKBD0l\nqayspi3RyMYNFX1Kshc0PI4ghPhYwQSJOxpzcXe4LRnQQMXmpEiZi87wMZs6\nrkypCVQXMMUyUoD2fkoGLUJpvRjZEyWQD4z6x2NJdBeCz19J23f00/YxWppX\nXtB3S3TZk27Fv091e1rhPe94KjEkMj/gnjUq09IfWkl9iI32eBqm+Yp9fpRe\nOhFzOZFmZ2waJfQY52cWW4zVG7kJq4WOv7g4537PJC6MQF41HCZhPRyXNbSm\noTyUKMQeoqCtoqAxl/zur8TqzxiwilS8eE14ElY++jY90Kz+PjgkCORcsrq7\ntcRg/UknbQZWsD+ZDadr6FJ+asTSrupqlGzILmkcTTrJtMehsaR3MzitaTnl\n1fLigi34nutAemcy+B+mzEygR6BFwJm/jFKfz6n0wF5moGBsxzX/RvIk2f+d\naie4uneEqV405sSywb1R+rRyj+GLdvee6pitbGiSrKdwDPl5bSpjZ1srl76K\nD0F2PC/5tJEY5Pzmnw0erydPaJgwU60UAn+AiuxuHVV9f0O7zgoe7FokjiCf\nsBh1ZzNuXM+GywLF7StO7hjOPtJvMWtqGziTk8oP7Uz7FLfHsBiT8y04nBfv\naou/3LfD2uBOXG4oOf2yZjbswnY4JHq0Nrlk9I8XXc9KDkEgMX2QopUC6QyD\n0pHg\r\n=rYrj\r\n-----END PGP SIGNATURE-----\r\n"},"authors":"bombkiml","engines":{"node":">=8.9"},"gitHead":"1a2e73d20d02a2bbc1eaea5b04a40f2246e949c5","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.10.1","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"10.16.3","dependencies":{"fs":"0.0.1-security","path":"^0.12.7","mkdirp":"^0.5.1","node-cmd":"^3.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jasmine-node-karma":"^1.6.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.0.41_1585556730927_0.3528971956904694","host":"s3://npm-registry-packages"}},"3.1.6":{"name":"beech-api","version":"3.1.6","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.1.6","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"./packages/cli/core/generator/index.js","beech-app":"./packages/cli/bin/beech.js"},"dist":{"shasum":"81967f41613c496dc657a01f0b5b9ec0a41a5caa","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.1.6.tgz","fileCount":17,"integrity":"sha512-GDWyLAQNKDn0DgPqtGyS9HAXMBrRKRRB/KhyYMd5isCjEv9hzyMTrNPK4Pm+6sDOaCmLN2rNZzJLRShV6u9Rxg==","signatures":[{"sig":"MEQCIFUTNdq4BTdcWDL75mmADUYqfD1e0mp/xoxGZHggHcJwAiBeGfOzR4GXJmlL4D/yGpRiSCYkpv7WXhWQL/A8/5SY1A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":30997,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJegwTZCRA9TVsSAnZWagAAoZ4P/1nZat6YjJK0jGmUo0x9\niwzbOUWINToDTX6Cp9v77o0ndhhE+x0tJyCWO6yo6OXGiP9KtTsMGfx9M9Gp\ncY1l9cU/IABG/cm0cw+hN9zGf1KxG2DmpNxM4+DpYcl6E5rFGlPO/KSeqcOo\nXUTbnGzM3eml6ciPL5oPXKkJypOGNptVdnWT0FWnH2KZyiIzghhzXnc+i4GN\nQ8JcYPWiSZMMW4g3aa/SUpsuzxuKKPSfHKX3NNsvjUefjEovCgiy4ECgOJqf\n7gwNISlGiNEeG35kKH730OLGqj/hLrVwJ1OADm2A2/ZFfGFpKcu5PyrTE9Yw\nZaEXM+IBm6hQ4bDsv8x7c6DyKu8wvqFb/PykLVBf8XFLbNztIeP/rdLyDF2q\nGimIximMd487OKE0Y2Eq2BsSjhpbHwlsIctRODd/sBmSQNZNc5Cdwkh527Us\nyGlVLXRbVDIA9omUfXKYwRkeGkhH3NbW7Eywp6mjPM69vmrBlTEKargWRu8K\nU/BuoauaBNewc9Sp3ZxTWg9IqWryN31PQ/oTis60xngjkgGo5vRCKJObKgbv\nB4ciQxU+aLUDPfRJyV6MGpfREcO55hDSpoQk9SSkb8YYxobPF3s6TdATtBgf\nlaq03cHZJ9TDIExzlKfIUBci8w48P6/bG98YNSPHOLaQDbNu7NDmIieYojyi\nemHl\r\n=vmBR\r\n-----END PGP SIGNATURE-----\r\n"},"authors":"bombkiml","engines":{"node":">=8.9"},"gitHead":"98b823c34e35a630fae6b32be2de98d22069a19b","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.10.1","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"10.16.3","dependencies":{"fs":"0.0.1-security","path":"^0.12.7","mkdirp":"^0.5.1","node-cmd":"^3.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jasmine-node-karma":"^1.6.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.1.6_1585644760186_0.6278186946910882","host":"s3://npm-registry-packages"}},"3.2.11":{"name":"beech-api","version":"3.2.11","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.2.11","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech.js"},"dist":{"shasum":"c9b813fa85a8b16977f927534a285a14ecf27b44","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.2.11.tgz","fileCount":23,"integrity":"sha512-5Qa0ggzT3DASBIHiv6LSIzIyIJUmGRLdarzcRLGTtecIrj7yFjdaO/Ove3zWYn6MDb/fej8cnsu3HijE+SXtxw==","signatures":[{"sig":"MEUCIBGaY64O/yaineT9BFN9Kt+pRiRuPWvkiY9/NngHRjpWAiEAkUuWDrK+smjikssHDJ04fRSmV5zJe0nPwWAsl9mSy48=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":44788,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJem8MDCRA9TVsSAnZWagAAATMP/07QPleqQKGLKDMBLR2I\n6/EInET+03sTnQ+C2d11TqdkQ3N/44WLI1XLEoUWl9vPZKGzwA2DQrfTeaXA\n+GeIDRRHG92GzKQ9n0Rzc8ZO6bU/2SMahRZL5Mumi8CAvVVJcrQx5H3JuXLl\ngptgNWc/gfRNiMaAf2wT/25znrIjY+KDRPCqMX7UsYdtXoOkgOw52tzBKytE\nF7og6IcrV/ZL3yhkMdAAsKxEcrteU3+HfsGcv0NAD5TThZpruex/fvkI/zm6\nZwvir90c6FHLFfbNbBRePztbItUs6ki47gMgJz4hgTeywMnr5zNWrFzNE1Eg\nhfWlSOGai2Cz2+tQ6Q19tK20A/IShM2Jn+lzgFLcX32uQQniw9S9BY7IeNLc\n0t64D5yxE3ME/cWA6t5Xf0vR3PX0040I+fXD+pc42fWQLmuUKykenQt1dmQw\nS9D6Nx6eRZIiikxWiqahHqszWkbq8ox6UGH8jZsVF2ZSrtnQiAvFGopEiYFm\nZEmUm5r1nDhd0H9TyvnSTagbfkA342KjxQaVkCVPTWAY0QizKSouHKX0od3j\n0naYXI4Z2J9+XexcOng5/ObL2EuHL8jN7Uovw86MtGckoLyZ7r7cN7tSbUyz\nneTHsmMZDiMzelEYsd2Dn92AxpWFdoC2L1nRfnI3ThxjMpYpIsAKwqjaoYt8\nPvwi\r\n=QfDG\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=8.9"},"gitHead":"8af375fcdbc98551809b34ac88f6329680b46086","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.4","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"12.16.1","dependencies":{"fs":"0.0.1-security","path":"^0.12.7","mkdirp":"^0.5.1","node-cmd":"^3.0.0","log-update":"^4.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^25.2.7"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.2.11_1587266306754_0.4174692179119506","host":"s3://npm-registry-packages"}},"3.3.1":{"name":"beech-api","version":"3.3.1","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.3.1","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech.js"},"dist":{"shasum":"72aa1e0c63967f6bdc2d8c434c48aae9925a3dee","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.3.1.tgz","fileCount":30,"integrity":"sha512-lDi5Fbd1bEEdn1pV6ZuD59DmupVyInU8fTnGLt66WL0SerxCYYEyAcDJPCx03S8f1jlotn8GRczioa9pPAJI7w==","signatures":[{"sig":"MEUCIHk1+0UekEkQI8FSM7t3CVcQ6imBbKsyMt1MVXvGXHH6AiEA1rezqmYZDRWYPjy0f/GCADtI+qKZkaspy8h1KZP8s7Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62653,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgQE51CRA9TVsSAnZWagAAKV4QAItm7O6yHTxjU4d03/33\nxytdTCrgsc9q7Vbv69qkGuf6xP6PG+oV9In8MFMfZ+H+34Y4FvyQ4WMRB6x4\nrhwjSPiegwdFXjNXT0NyrDit824y/AH0rMeb5VZorHH7UGv/lIsRQuaqcXv0\nHKO+RaVEgdEfurQfVB7gdHvJr9S5k5Z1MO04W4MCM61rfh+y4c2hdwrgr23T\nZHMLi4nG3F8BwKUNYhZBIbcYK9ULnHz64t/A2WykYS3fD9TER5gP6H3Kwmkw\npVw/hoSiZEDnmBarL4mzjXr1IvM5/Wm8Zj65QTI5iYcN7uMZniQ/VfibdokK\nRkFPwZVPn6mam9WYOpG80WKhLmeNUzgTwdYV6sywfIsTQKQ76m5skwjrG+CD\nLFQGZAb0nUFcbdJScpmb+U+vkiF11kNRLilmxYDsPPMzTT5EHhAXnXM1nhm2\nMXPv1m4j44JohRmvQdwVg3PXJqnlgdSXzVeVQzTfF7UDoUtJwAv5pXgFVtkH\nPUhY/a2zwfa7ZW7XgKFHnDjUmK2kGyOfiYT+VpUbrlVXkmX26i1zAIhYoNnZ\nCL9dGZuZHIw91oajARMk7n3m+M2sbfx90zvScilo+oS07ZfdJlO7rV3l6Bb/\nGzHvLRvdQ3GQ2L3E1+WkVl7V3qaSrQjZgAAsL9shJlZRnygFproTzCko/RkV\nSNln\r\n=AJ5H\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=10.13"},"gitHead":"985ea6f59f65e7f9e125255913c8443b7278b263","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.4","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"12.18.2","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","path":"^0.12.7","mkdirp":"^0.5.1","node-cmd":"^3.0.0","passport":"^0.4.1","log-update":"^4.0.0","jsonwebtoken":"^8.5.1","passport-jwt":"^4.0.0","passport-local":"^1.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^25.2.7"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.3.1_1614827124487_0.7809908658022211","host":"s3://npm-registry-packages"}},"3.4.0":{"name":"beech-api","version":"3.4.0","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.4.0","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech.js"},"dist":{"shasum":"fa0b988c7559d739f84704cd6524c2d7c817bb11","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.4.0.tgz","fileCount":31,"integrity":"sha512-gxQSCwhPTNq8xKG0FDjHBfXNT78+Gelbh2EmO1Yqyvcw9mYE9rqhO2fIbDgIC2wYOb3hGFb0fGJiUwpck1YZng==","signatures":[{"sig":"MEUCID8+FtnDawFuB9nEyCs2nkXVdPKR/sPXIMe/u5cRNVifAiEAkT8QG8L/wxg4EnbmeL11/gQA9mpXICgFeTHy3X+MtwQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":80093,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiQqnAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpZ0Q/+Molatzd79RWKiOQx8vZnMwuaMmBBPlBy9m3nXRT9/Erpra71\r\nOi+6PlbUKSc301ZN5Evb83o760f07ZM+AGG75PiuSmSVmzNnhcZW4Fh1KyXt\r\nQBhoUmuFChSsph+ELp5cqAIirVj8QKMTdl3Ou42/i9gwqvamYufiuAbHp68b\r\nuhZkPqBHE01gAxYJxE6pqk9g63qvooJFjQ+mVlx8IdgfX3dqgZW0A2ZDsx5U\r\n53UOhAGEEzyMWmWeMws0OkeBp2qwHV/1K19EXRAX19PDhs6Z4cZyjmZN6GYz\r\nI85Zsn+8dizV/03CfsYkeTSu3SeDV6C6aIIvQSJH9I6Ybapz3HbA7sHmKCe/\r\nrGWZGxdQH/JhsybD5qHHbFvzd2pLV/nCfFME51THl8PX0VG2VIEjTm0tOo9S\r\nNzLBU6ns0/KondX7kM6SvP2vzpxVYoEmS3PwDClU/+xZRJZc2UVo26JbV6uS\r\nv8vuNTauodemsV/IlTtDUuOHuU0xnMiCxQ0kMS5Fmg8m5mjpCU+QkeuZywKZ\r\nEvQHO0rtD2/9OZW2NwdwmEoZjuJ7HRskAFfDAvx77de1609MnsQVOWtKPXyt\r\njHgzZ+tgWl9Nb7fruD5bVp0ae6bilXE72Q5CuhNnrfhDXArxpfbq12yuqQia\r\njjcXBa462/CA0x6trHbqtr0fhlq64dnViSs=\r\n=Yace\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=8.9"},"gitHead":"931cdf3bbfae2c62d5964b7cc5728a32f30b9a1d","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.5","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"12.18.2","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","mysql":"^2.18.1","mkdirp":"^0.5.1","express":"4.16.3","node-cmd":"^3.0.0","passport":"^0.4.1","sequelize":"^5.21.6","log-update":"^4.0.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","express-validator":"2.21.0","passport-facebook":"^3.0.0","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^25.2.7","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.4.0_1648536000296_0.7429126605059662","host":"s3://npm-registry-packages"}},"3.4.12":{"name":"beech-api","version":"3.4.12","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.4.12","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"./packages/cli/core/generator/index.js","beech-app":"./packages/cli/bin/beech.js"},"dist":{"shasum":"8636c37a5db6b6dff70a1cd0b24ea26f7a454e20","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.4.12.tgz","fileCount":31,"integrity":"sha512-xRA5za8cQ6EaxnVlfmWcHzntx+Gybz56T7UB5LRi1saJBzf+HK/10Ke05fC0a8bxmZv2vpkY2XNZ/LypBA5DoA==","signatures":[{"sig":"MEUCIQCuTdDxsyCJjqu/DEvkopMXUKOKYJs7Xkep3uIR17aKnQIgMDkAOj4tn1Cl4alRy7nzEUr/BlJcQ1LDgG3LkhgnVCw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":93499,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiYjiqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqpfA//VWsJGznV3dLDsi4GAIAaHyQRCngzsynP5zjaaFbrb8gcj/Lq\r\n80O6ZgsMF9RflKG52Gq3Je2ctnhbdp/JRVtO7LbyO1JDh8lKSqwtgKaf6kjQ\r\nnfmh+t1dQDpzaJOkrsQTPqPVC4cyP0dt+Fo328EGEMpjK2UNYUE4uDdKGi6n\r\nm0JsZqQbeb5ni6NuHYXu1ZOuwZQfh0Xg5gFGNSNA6YuwAFPerH14JM8NRW78\r\nAjaG+6wRU2lhJtXUXLL+HzWox0lB8xvtS8siwoGtwF5dDvHO4eZM16pACP1a\r\nr7ylQKrFducKLaOy6sVmPQXocbg7anbaAuwmw0yHhiI54LmB9iCXn3Bg8aVt\r\na7Kr2VjYjv7Ayb66Bsj7YnF7jt1gfrpovq5y2NK7lVoSRB9wL5/cVxuvPeHH\r\nkTvU5okotkl6KcaFsG/GC3k2wGupdYdxUBFA9fc2zloqZH/AU8jp2/f5qlYd\r\nkliHIay3Kyak66S/FuvEHFao6kEJjbUQ4RJKCol45xndrBgS++VdBvXIBmn4\r\nmYqYFRt9LJKNn0kR8+aUX/fnMGJB8C8fyfTTj2YGCNJcRddrMEPmM2OZfDw1\r\n21UWb7KcCyrYKvWpEBFuSYyr7xf0nH2OZGJI/qkAVZ5PV7plzbFbknh8DnP3\r\n/USXXoo3T0MhxWbOg9ogEOyeoZE9xnepBoA=\r\n=DOAo\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=10.13"},"gitHead":"85c74b7de4e69228783551cd8878cea259a06be1","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.4.1","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"10.13.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","mkdirp":"^0.5.1","mysql2":"^2.3.3","express":"4.16.3","node-cmd":"^3.0.0","passport":"^0.4.1","sequelize":"^5.21.6","log-update":"^4.0.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","express-validator":"2.21.0","passport-facebook":"^3.0.0","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^25.2.7","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.4.12_1650604202086_0.820277105932427","host":"s3://npm-registry-packages"}},"3.5.7":{"name":"beech-api","version":"3.5.7","keywords":["beech-api","cli","api","nodejs","api-framework"],"license":"MIT","_id":"beech-api@3.5.7","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech.js"},"dist":{"shasum":"80653155dba31475e0f5aa4c0378410831174f14","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.5.7.tgz","fileCount":37,"integrity":"sha512-Te6fTYRwKIKXetC3TV+RdLB3fTsYHh6QvRH4sCmIbgkstbN6v1UpDDKjLn5hLPIN2zx4Ys84XxviDQrGzMR4gQ==","signatures":[{"sig":"MEQCIEKYg5TCK1lzlO9BLoSEfAbYoExN1mjFiVPGZLrdKNCyAiAA7gQiqNa2Y2nxFPbOfx13RhYO2b4gjPTHRgk1caKiJQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":119776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHl2jACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpz0A//RyIhAMaFMa2/LsZEQJ889RQD/smyRwflblAzRuC6Eg4w1BOX\r\nuAAujw6KJCsKR88VzwHRpL3gD6HWoZqHjAK2SWO6NsHEEyMz7QzIk8bLiVOQ\r\nrf8D94ntOYtiRgR5GPtU2zpChtunwKNmo9kYaHEFv7liSHkq2ywzmcKgkUOd\r\nZLLBQev608wol1Ea2j2Ckd22m14ITBGgks2kPeQhezHAQV8ps6JAazHEpKjX\r\ne5pWRyeTa/lvveibPSDGH8wEoPE4qhHezxNGCfYmCy07u0RgHlKKApxbCngI\r\n1O7+VwbyfoiXw9ooOxPQVYeLj7p0cPqTAampDRpDtoHfi7xUX4TW2cvSxh0/\r\nktSIQsUrQ+ez3fPBhE+hieTHqtcwyBHubBplYtw+0OAVTIs7ODXFDjbNyEQj\r\nACfhWDEQONUtSz5ni5gJCgWBqUcJUE9UPyc1FSgm1wzGzYiLU5y/I2Yr0GjG\r\nTupBG2a2xJWvEpbwfO3qnfRt8qkDLLE9s/y4AuCb3fSya+IFBOLk8zim2zC3\r\nVKJqJAEUeBpFuUzfjehPCiros/pEFDBT6vvisHlLOuKatU/p4eNR0KBy0fRX\r\nBm/wVvJBJbxmNpg5dc2i/c2HjLgwA8sUTmltc3a3EO6QHNURugfTX4iYYYuW\r\nhR3kEOLiLs4pFBD15sq15gq2+CANqV5mKmI=\r\n=XCZ2\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=10.13"},"gitHead":"c3e5aab51a18206ed28361aa2a73f6262aa758a9","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.13","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"14.17.3","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.16.3","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","sequelize":"^6.21.3","log-update":"^4.0.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","express-validator":"2.21.0","passport-facebook":"^3.0.0","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.5.7_1679711651757_0.12251430687505027","host":"s3://npm-registry-packages"}},"3.5.12":{"name":"beech-api","version":"3.5.12","keywords":["api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.5.12","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"087aeab5e3c23d0bdee224ba9d44bd549f3bf260","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.5.12.tgz","fileCount":59,"integrity":"sha512-ffAp3q/GHSNLP2FuHqUEQ1/4V4vf42SlHAEjFESyVMgO6SsgPcQWukNxdfwfvteuCtDhoDusvLCwrek7SOWsxA==","signatures":[{"sig":"MEUCIEt+TDyUVYJQpmGSXuofjyVi7A5wg+yCEcs+SHCwgKPnAiEA1SH39Y6JU9U5jJ1ormJaEI5ojPFpCX1RBH6RwZugikU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":163381},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=14.19"},"gitHead":"7ba989f3808c4b9c3f05477d0eb4657e261ed4cb","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.16","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"14.19.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.16.3","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","sequelize":"^6.21.3","log-update":"^4.0.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","express-validator":"2.21.0","passport-facebook":"^3.0.0","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","nodemon":"^3.0.1","node-dev":"^8.0.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.5.12_1694677607346_0.5492684208535206","host":"s3://npm-registry-packages"}},"3.7.0":{"name":"beech-api","version":"3.7.0","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.7.0","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"e20a4cabec8885702455931692e9192dc56171da","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.7.0.tgz","fileCount":51,"integrity":"sha512-0+joUqUDnTQofgJ6j/tMeB1mgKkF8jiOAao182c0ZEoVDr1PuMkMlH4wiop+odCaAm77o1wljhSwvec5SEKEpQ==","signatures":[{"sig":"MEUCIDeKichZOsB65/5vKUVjPRAt1HOhejfD+yjKEJ/dkYy4AiEAynaeSb3oa483ySvrwTy1wFG71pfzNAZIpYwW+HZdZc0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":206012},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=14.19"},"gitHead":"cd199069e8cdbb5b565b0e87d32a6630514ba110","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.16","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"14.19.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","cryptr":"^6.3.0","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.19.2","inquirer":"8.2.4","passport":"^0.6.0","cli-clear":"^1.0.4","sequelize":"^6.21.3","log-update":"^4.0.0","node-emoji":"^1.11.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-validator":"2.21.0","passport-facebook":"^3.0.0","child-process-promise":"^2.2.1","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","nodemon":"^3.1.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.7.0_1714359147594_0.561365698937097","host":"s3://npm-registry-packages"}},"3.7.23":{"name":"beech-api","version":"3.7.23","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.7.23","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"7b50466740bc497a5817d938e530a79dca70c400","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.7.23.tgz","fileCount":50,"integrity":"sha512-iktwipdO0cNpmM91m0QTSMKafWU3X76+KoZ9sefteg56ET6sCUPbBTdPLDWUp6Pts1H1yEnQDJtLge6MTIjy0A==","signatures":[{"sig":"MEUCIEj62Y8JP2n6nDHwwOzG/wRwWKfMlm4LKmvoLNkX9h/1AiEAk87hgsgm0cy4XF+GWM4mThoaBjmtGqgUCU78gn/GxbA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":205629},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=14.19"},"gitHead":"5cae633ddd3a45065b6e2c93d125dcda25eaffc4","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"6.14.16","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"14.19.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","cryptr":"^6.3.0","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.19.2","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","sequelize":"^6.21.3","log-update":"^4.0.0","node-emoji":"^1.11.0","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-validator":"2.21.0","passport-facebook":"^3.0.0","child-process-promise":"^2.2.1","passport-google-oauth":"^2.0.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","nodemon":"^3.1.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.7.23_1714655304769_0.04511249001805551","host":"s3://npm-registry-packages"}},"3.8.0-beta.1-rc":{"name":"beech-api","version":"3.8.0-beta.1-rc","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.8.0-beta.1-rc","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"ad55ae6c16f817ca843c203f929f976bb375d3c0","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.8.0-beta.1-rc.tgz","fileCount":58,"integrity":"sha512-UJ4/K1lz2hJXJ5rLdEhkONOwTvv8qN/nmrdzukkwNk2l9kWwv6yYHc0K1V0CjWYAs68bL5Aotrjj0Ix6W/HDaQ==","signatures":[{"sig":"MEUCIDlemOzEcUagAm7LO1mxdmerLEdrmvZtGGgdp2rA16ktAiEAyzKhh2TK42FfslUZnFTD7wSRWgXtg2KbBDs1UdNiF0k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":264236},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=14.19"},"gitHead":"6c19813efdb885681cb474811823872ba2ed525b","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"10.8.2","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"20.18.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","cryptr":"^6.3.0","helmet":"^8.1.0","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.19.2","tedious":"^18.6.1","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","crypto-js":"^4.2.0","sequelize":"^6.21.3","log-update":"^4.0.0","node-emoji":"^1.11.0","compression":"^1.7.5","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-slow-down":"^2.0.3","express-validator":"2.21.0","passport-facebook":"^3.0.0","express-rate-limit":"^7.4.0","child-process-promise":"^2.2.1","passport-google-oauth":"^2.0.0","express-duplicate-request":"^1.0.3"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","nodemon":"^3.1.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.8.0-beta.1-rc_1759304559120_0.4364228989713632","host":"s3://npm-registry-packages-npm-production"}},"3.8.0":{"name":"beech-api","version":"3.8.0","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.8.0","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"1662c0264cd774b7489a2c6baea4f74c288f8423","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.8.0.tgz","fileCount":58,"integrity":"sha512-sdXYKRXo2zNBf0LQ2iAdeI99yBx1ba+tfWSCU7E5rAikTwGRfdkrNhqToxk7hNhdIi+HfMEqDesEV4S7kSXabA==","signatures":[{"sig":"MEUCICAPacAWGFnocFt2QrL4WeKHARR0mE17O/oxSiuu72QjAiEAnQ81uyJP3OzTDXrwZFBVjeSnIatZ/XCVDsODX3J8zu8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":263592},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=14.19"},"gitHead":"6c19813efdb885681cb474811823872ba2ed525b","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"11.7.0","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"20.18.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","path":"^0.12.7","walk":"^2.3.14","axios":"^0.26.1","mysql":"^2.18.1","cryptr":"^6.3.0","helmet":"^8.1.0","mkdirp":"^2.1.6","mysql2":"^2.3.3","express":"4.19.2","tedious":"^18.6.1","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","crypto-js":"^4.2.0","sequelize":"^6.21.3","log-update":"^4.0.0","node-emoji":"^1.11.0","compression":"^1.7.5","jsonwebtoken":"^8.5.1","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"1.4.3","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-slow-down":"^2.0.3","express-validator":"2.21.0","passport-facebook":"^3.0.0","express-rate-limit":"^7.4.0","child-process-promise":"^2.2.1","passport-google-oauth":"^2.0.0","express-duplicate-request":"^1.0.3"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^28.1.3","nodemon":"^3.1.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.8.0_1766137933881_0.47106075883452747","host":"s3://npm-registry-packages-npm-production"}},"3.9.0-beta.9-rc":{"name":"beech-api","version":"3.9.0-beta.9-rc","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.9.0-beta.9-rc","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"b64d05f6b0189ffe3d976d5ede99942c2452a5df","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.9.0-beta.9-rc.tgz","fileCount":59,"integrity":"sha512-6+KAcwHJd4N/Tsl2GhiSFhDB/Mitr3HLamXF99QuXRwE6p9u0WLJ/3t10glNZDPs6B3n5xxvaWnFEhLVX3CBaQ==","signatures":[{"sig":"MEYCIQCJbCm8P7DVybvznXompZYVnXrZBC56fER72cJN+B4hTwIhANUbsAUmIzRFvMOwp8RQ2mEBrqwrwdmgbfJXplFXvdN3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":325587},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=16.20"},"gitHead":"aee83a03453f45541b531d752bca1e050bec7b67","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"deprecated":false,"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"10.9.4","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"22.22.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","cron":"^4.4.0","path":"^0.12.7","walk":"^2.3.14","axios":"^1.8.4","mysql":"^2.18.1","cryptr":"^6.3.0","helmet":"^8.1.0","mkdirp":"^2.1.6","mysql2":"^3.14.0","express":"^4.20.0","tedious":"^18.6.1","inquirer":"8.2.4","node-cmd":"^3.0.0","passport":"^0.6.0","cli-clear":"^1.0.4","crypto-js":"^4.2.0","sequelize":"^6.21.3","log-update":"^4.0.0","node-emoji":"^1.11.0","compression":"^1.7.5","jsonwebtoken":"^9.0.2","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"^1.4.7","node-notifier":"^10.0.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-slow-down":"^2.0.3","express-validator":"2.21.0","passport-facebook":"^3.0.0","express-rate-limit":"^7.4.0","child-process-promise":"^2.2.1","passport-google-oauth":"^2.0.0","express-duplicate-request":"^1.0.5"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","nodemon":"^3.1.0","sequelize-cli":"^5.5.1"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.9.0-beta.9-rc_1778472536124_0.28585859980341444","host":"s3://npm-registry-packages-npm-production"}},"3.9.75":{"name":"beech-api","version":"3.9.75","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.9.75","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"183cfb82e63df0bc1210570df7a2b73893c49a82","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.9.75.tgz","fileCount":60,"integrity":"sha512-lHTHCMVx+bKoOi5mGZvGnbjSgEWqJLZrebKRVO0GG7CBUXgayGxh9t6Oi5yrktQ6M6tf9f5Ogv+TRtUh9NYYoQ==","signatures":[{"sig":"MEQCICx7NDBcFQfhV3mIMiQ2L1QVUzbR6ZiOPsUwbgrQ6LAdAiB5uLSHnB3imqhJFj6GaNWQu1u9wHSArRPSgT4/DhrTnQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":335618},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=18.18"},"gitHead":"254ba655cb0f4b109ea999f57e130b758c70ce8e","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"overrides":{"lru.min":"1.1.1","cross-spawn":"^7.0.5"},"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"10.9.4","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"22.22.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","cron":"^4.4.0","glob":"^13.0.6","path":"^0.12.7","uuid":"^14.0.0","walk":"^2.3.14","axios":"^1.8.4","mysql":"^2.18.1","cryptr":"^6.3.0","helmet":"^8.1.0","mkdirp":"^2.1.6","multer":"^2.1.1","mysql2":"^3.22.3","recast":"^0.23.11","esbuild":"^0.28.0","express":"^4.20.0","inquirer":"^8.2.7","node-cmd":"^3.0.0","passport":"^0.6.0","ast-types":"^0.14.2","cli-clear":"^1.0.4","crypto-js":"^4.2.0","sequelize":"^6.21.3","log-update":"^4.0.0","compression":"^1.7.5","jsonwebtoken":"^9.0.2","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"^1.4.7","node-notifier":"^10.0.1","sequelize-cli":"^5.5.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-slow-down":"^2.0.3","passport-facebook":"^3.0.0","express-rate-limit":"^7.4.0","child-process-promise":"^2.1.3","javascript-obfuscator":"^5.4.2","passport-google-oauth":"^2.0.0","express-duplicate-request":"^1.0.5"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","nodemon":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.9.75_1779252318303_0.9756286764774671","host":"s3://npm-registry-packages-npm-production"}},"3.9.80":{"name":"beech-api","version":"3.9.80","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"license":"MIT","_id":"beech-api@3.9.80","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"bin":{"beech":"packages/cli/core/generator/index.js","beech-app":"packages/cli/bin/beech-app.js","beech-service":"packages/cli/bin/beech-service.js"},"dist":{"shasum":"49f2b9d35ba3478012cfd3c445bbba82681c9313","tarball":"https://registry.npmjs.org/beech-api/-/beech-api-3.9.80.tgz","fileCount":60,"integrity":"sha512-igK+W0kDI8d96u+DJCtImNmPvSY4XhsU1b5LU7dh3HLnPgCgkpiYegj+4Vj5mJWAWhNDW6Qa5raJr6QgbWsrJA==","signatures":[{"sig":"MEUCIQDFxdxnJjHtETtNPaNk/FEu8kpC40XEYXDHxDsYb0A23wIgd1+F2ZRHBkmFzXXt86AEHtx81rhVUPrbBBQymMZ9vGU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":348063},"jest":{"devFile":"./core/test/utils.js","prdFile":"./node_modules/beech-api/packages/cli/core/test/utils.js"},"authors":"bombkiml","engines":{"node":">=18.18"},"gitHead":"b4e536a7ade41a14f0084a8cca06f44e417c2340","_npmUser":{"name":"bombkiml","email":"nattapat.jquery@gmail.com"},"overrides":{"lru.min":"1.1.1","cross-spawn":"^7.0.5"},"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"_npmVersion":"10.9.4","description":"Command line interface for rapid Beech API development","directories":{},"_nodeVersion":"22.22.0","dependencies":{"fs":"0.0.1-security","md5":"^2.3.0","cors":"^2.8.1","cron":"^4.4.0","glob":"^13.0.6","path":"^0.12.7","uuid":"^14.0.0","walk":"^2.3.14","axios":"^1.8.4","mysql":"^2.18.1","cryptr":"^6.3.0","helmet":"^8.1.0","mkdirp":"^2.1.6","multer":"^2.1.1","mysql2":"^3.22.3","recast":"^0.23.11","esbuild":"^0.28.0","express":"^4.20.0","inquirer":"^8.2.7","node-cmd":"^3.0.0","passport":"^0.6.0","ast-types":"^0.14.2","cli-clear":"^1.0.4","crypto-js":"^4.2.0","sequelize":"^6.21.3","log-update":"^4.0.0","compression":"^1.7.5","jsonwebtoken":"^9.0.2","module-alias":"^2.2.2","passport-jwt":"^4.0.0","app-root-path":"^3.0.0","cookie-parser":"^1.4.7","node-notifier":"^10.0.1","sequelize-cli":"^5.5.1","passport-local":"^1.0.0","passport-oauth":"^1.0.0","express-session":"^1.17.1","method-override":"^3.0.0","express-slow-down":"^2.0.3","passport-facebook":"^3.0.0","express-rate-limit":"^7.4.0","child-process-promise":"^2.1.3","javascript-obfuscator":"^5.4.2","passport-google-oauth":"^2.0.0","express-duplicate-request":"^1.0.5"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","nodemon":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/beech-api_3.9.80_1779381804653_0.14395441576678714","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2020-03-27T04:39:44.187Z","modified":"2026-05-21T16:44:19.551Z","3.0.0":"2020-03-27T04:39:44.344Z","3.0.1":"2020-03-27T08:27:43.647Z","3.0.2":"2020-03-27T08:40:05.822Z","3.0.3":"2020-03-27T09:11:15.252Z","3.0.4":"2020-03-27T09:15:03.070Z","3.0.5":"2020-03-27T09:17:39.845Z","3.0.6":"2020-03-27T09:31:21.968Z","3.0.7":"2020-03-27T16:03:12.019Z","3.0.8":"2020-03-27T16:07:11.730Z","3.0.9":"2020-03-27T17:03:24.722Z","3.0.10":"2020-03-27T17:11:13.162Z","3.0.11":"2020-03-27T17:17:46.485Z","3.0.12":"2020-03-27T17:19:30.450Z","3.0.13":"2020-03-27T17:39:00.848Z","3.0.14":"2020-03-27T17:45:37.843Z","3.0.15":"2020-03-27T17:49:18.512Z","3.0.16":"2020-03-27T18:06:14.930Z","3.0.17":"2020-03-27T18:33:45.339Z","3.0.18":"2020-03-27T18:38:49.187Z","3.0.19":"2020-03-27T18:58:57.427Z","3.0.20":"2020-03-27T19:00:51.496Z","3.0.21":"2020-03-27T19:08:00.360Z","3.0.22":"2020-03-27T19:09:29.099Z","3.0.23":"2020-03-28T05:45:20.440Z","3.0.24":"2020-03-28T06:15:22.587Z","3.0.25":"2020-03-28T07:16:53.763Z","3.0.26":"2020-03-28T07:18:55.568Z","3.0.27":"2020-03-28T07:19:59.171Z","3.0.28":"2020-03-28T08:32:06.376Z","3.0.29":"2020-03-28T08:48:19.641Z","3.0.30":"2020-03-28T08:50:44.983Z","3.0.31":"2020-03-28T08:51:26.274Z","3.0.32":"2020-03-28T08:56:15.435Z","3.0.33":"2020-03-28T08:58:01.769Z","3.0.34":"2020-03-28T09:01:00.377Z","3.0.35":"2020-03-28T09:40:30.401Z","3.0.36":"2020-03-28T09:41:26.826Z","3.0.37":"2020-03-28T09:45:59.710Z","3.0.38":"2020-03-28T10:12:14.872Z","3.0.39":"2020-03-28T10:20:51.361Z","3.0.40":"2020-03-28T10:27:37.092Z","3.0.41":"2020-03-30T08:25:31.101Z","3.1.0":"2020-03-31T05:01:36.372Z","3.1.1":"2020-03-31T06:50:11.672Z","3.1.2":"2020-03-31T07:31:48.623Z","3.1.3":"2020-03-31T08:13:39.667Z","3.1.4":"2020-03-31T08:40:58.732Z","3.1.5":"2020-03-31T08:48:57.940Z","3.1.6":"2020-03-31T08:52:40.303Z","3.2.0":"2020-04-07T08:24:24.755Z","3.2.1":"2020-04-07T09:32:27.875Z","3.2.2":"2020-04-09T09:07:48.871Z","3.2.3":"2020-04-13T17:33:47.030Z","3.2.4":"2020-04-13T18:29:38.842Z","3.2.5":"2020-04-14T04:29:40.023Z","3.2.7":"2020-04-16T17:29:05.221Z","3.2.8":"2020-04-16T18:27:33.303Z","3.2.9":"2020-04-17T09:40:28.480Z","3.2.10":"2020-04-19T02:43:05.032Z","3.2.11":"2020-04-19T03:18:26.913Z","3.3.0":"2020-09-17T04:37:30.980Z","3.3.1":"2021-03-04T03:05:24.813Z","3.4.0":"2022-03-29T06:40:00.426Z","3.4.1":"2022-03-29T06:51:03.378Z","3.4.2":"2022-03-29T07:12:48.302Z","3.4.3":"2022-03-31T07:02:05.126Z","3.4.4":"2022-04-04T04:57:25.694Z","3.4.5":"2022-04-11T04:11:46.520Z","3.4.6":"2022-04-19T08:47:44.525Z","3.4.7":"2022-04-19T09:23:08.535Z","3.4.8":"2022-04-20T02:02:30.363Z","3.4.9":"2022-04-20T02:43:10.392Z","3.4.10":"2022-04-21T02:50:26.245Z","3.4.11":"2022-04-22T04:57:58.119Z","3.4.12":"2022-04-22T05:10:02.766Z","3.5.0":"2023-03-24T11:58:04.152Z","3.5.1":"2023-03-24T12:20:57.347Z","3.5.2":"2023-03-24T12:43:22.909Z","3.5.4":"2023-03-24T12:56:30.063Z","3.5.5":"2023-03-25T02:02:25.270Z","3.5.6":"2023-03-25T02:17:16.977Z","3.5.7":"2023-03-25T02:34:11.956Z","3.5.8":"2023-09-13T06:25:23.153Z","3.5.9":"2023-09-13T06:49:04.132Z","3.5.10":"2023-09-13T07:08:58.300Z","3.5.11":"2023-09-13T09:03:49.176Z","3.5.12":"2023-09-14T07:46:47.631Z","3.6.1":"2024-03-12T07:37:53.280Z","3.6.2":"2024-03-12T08:15:58.928Z","3.6.3":"2024-03-13T03:40:29.604Z","3.6.4":"2024-03-13T07:27:00.411Z","3.6.5":"2024-03-13T08:06:40.884Z","3.6.6":"2024-03-13T08:10:56.372Z","3.6.7":"2024-03-13T08:35:01.269Z","3.6.8":"2024-03-14T03:15:48.584Z","3.6.0":"2024-03-14T04:38:18.620Z","3.6.9":"2024-03-14T07:04:38.793Z","3.6.10":"2024-03-14T08:15:14.839Z","3.6.11":"2024-03-14T08:52:44.877Z","3.6.21":"2024-03-14T09:21:49.285Z","3.6.22":"2024-03-19T11:13:43.285Z","3.6.23":"2024-03-19T13:43:16.702Z","3.6.24":"2024-03-20T08:12:35.995Z","3.6.25":"2024-03-25T07:10:12.055Z","3.7.1":"2024-04-07T11:24:07.013Z","3.7.2":"2024-04-11T03:11:28.543Z","3.7.3":"2024-04-11T04:08:38.447Z","3.7.4":"2024-04-11T05:36:09.654Z","3.7.5":"2024-04-11T06:16:48.903Z","3.7.6":"2024-04-11T06:32:04.501Z","3.7.7":"2024-04-11T06:34:31.413Z","3.7.8":"2024-04-11T06:36:32.167Z","3.7.9":"2024-04-11T09:01:56.478Z","3.7.10":"2024-04-19T08:09:25.940Z","3.7.11":"2024-04-24T02:54:08.814Z","3.7.12":"2024-04-24T03:51:44.255Z","3.7.14":"2024-04-24T04:16:18.765Z","3.7.15":"2024-04-24T07:34:55.341Z","3.7.16":"2024-04-24T10:29:03.294Z","3.7.17":"2024-04-24T10:44:04.784Z","3.7.18":"2024-04-24T12:31:17.161Z","3.7.19":"2024-04-29T02:22:09.462Z","3.7.0":"2024-04-29T02:52:27.776Z","3.7.20":"2024-04-29T03:24:07.607Z","3.8.1":"2024-05-02T12:41:11.424Z","3.7.22":"2024-05-02T12:54:29.422Z","3.7.23":"2024-05-02T13:08:24.992Z","3.8.2":"2024-05-02T13:12:21.142Z","3.8.3":"2024-05-02T13:20:30.793Z","3.8.4":"2024-05-02T15:12:38.842Z","3.8.5":"2024-05-02T16:10:35.305Z","3.8.7":"2024-05-02T16:50:50.092Z","3.8.8":"2024-05-03T06:23:43.377Z","3.8.11":"2024-05-04T14:44:40.330Z","3.8.12":"2024-05-07T03:50:04.603Z","3.8.14":"2024-05-07T04:01:09.760Z","3.8.15":"2024-05-07T04:26:34.373Z","3.8.16":"2024-05-07T04:39:25.486Z","3.8.17":"2024-05-07T06:15:08.167Z","3.8.18":"2024-05-07T06:16:37.970Z","3.8.19":"2024-05-07T06:57:32.960Z","3.8.20":"2024-05-07T07:03:13.074Z","3.8.21":"2024-05-07T07:51:18.997Z","3.8.22":"2024-05-07T07:54:24.076Z","3.8.23":"2024-05-07T08:11:37.223Z","3.8.24":"2024-05-07T08:14:40.699Z","3.8.25":"2024-05-07T08:19:07.812Z","3.8.26":"2024-05-07T08:27:02.995Z","3.8.27":"2024-05-07T08:35:41.689Z","3.8.28":"2024-05-07T08:42:48.261Z","3.8.29":"2024-05-07T08:53:38.862Z","3.8.31":"2024-05-09T02:52:00.541Z","3.8.32":"2024-05-09T06:35:39.511Z","3.8.33":"2024-05-09T07:03:04.100Z","3.8.34":"2024-05-09T07:50:54.706Z","3.8.35":"2024-05-09T08:00:18.619Z","3.8.36":"2024-05-09T08:19:34.204Z","3.8.37":"2024-05-13T04:02:56.444Z","3.8.38":"2024-05-14T08:13:37.658Z","3.8.39":"2024-05-20T08:08:04.577Z","3.8.40":"2024-05-27T04:33:03.179Z","3.8.41":"2024-05-27T04:49:18.702Z","3.8.42":"2024-07-08T03:11:23.090Z","3.8.43":"2024-07-08T04:19:56.272Z","3.8.44":"2024-07-09T16:10:26.717Z","3.8.45":"2024-07-10T02:48:42.640Z","3.8.47":"2024-07-11T08:39:12.325Z","3.8.48":"2024-07-12T07:46:29.709Z","3.8.49":"2024-07-17T02:13:05.523Z","3.8.50":"2024-07-17T03:29:07.949Z","3.8.51":"2024-07-18T07:39:10.109Z","3.8.52":"2024-07-24T08:23:11.376Z","3.8.53":"2024-07-25T13:00:40.699Z","3.8.54":"2024-07-25T14:15:16.380Z","3.8.55":"2024-07-25T15:30:53.184Z","3.8.57":"2024-07-26T08:45:16.785Z","3.8.58":"2024-08-06T08:57:07.419Z","3.8.59":"2024-08-07T05:01:42.779Z","3.8.70":"2024-08-07T05:17:44.477Z","3.8.71":"2024-08-07T06:47:40.191Z","3.8.72":"2024-08-07T07:16:16.822Z","3.8.73":"2024-08-08T07:32:41.762Z","3.8.74":"2024-08-10T16:25:11.944Z","3.8.75":"2024-08-13T06:48:11.482Z","3.8.77":"2024-08-13T08:48:36.011Z","3.8.78":"2024-08-14T09:12:35.415Z","3.8.79":"2024-08-19T08:41:19.749Z","3.8.80":"2024-08-20T07:42:19.700Z","3.8.81":"2024-08-30T02:39:06.597Z","3.8.82":"2024-08-30T03:23:01.381Z","3.8.83":"2024-10-25T08:55:18.280Z","3.8.84":"2024-11-04T08:48:37.624Z","3.8.85":"2024-11-04T08:50:37.468Z","3.8.87":"2024-12-03T06:47:03.641Z","3.9.1":"2024-12-04T08:27:34.441Z","3.9.2":"2024-12-04T08:46:09.926Z","3.8.91":"2024-12-11T03:22:04.255Z","3.8.92":"2024-12-11T03:25:47.922Z","3.8.93":"2024-12-11T03:30:15.635Z","3.8.90":"2024-12-11T03:41:00.683Z","3.9.3":"2024-12-11T04:02:06.256Z","3.8.95":"2024-12-11T04:08:03.472Z","3.9.4":"2024-12-11T04:09:08.629Z","3.9.5":"2025-02-21T05:39:46.550Z","3.9.10":"2025-04-04T05:00:50.014Z","3.9.11":"2025-04-08T08:35:04.141Z","3.9.14":"2025-04-08T10:22:03.204Z","3.9.15":"2025-04-08T10:35:14.722Z","3.9.17":"2025-04-10T08:20:30.984Z","3.9.20-beta":"2025-04-20T16:41:20.756Z","3.9.20-beta2":"2025-04-20T18:23:50.475Z","3.9.20-beta3":"2025-04-21T09:43:56.282Z","3.9.20-beta4":"2025-04-21T09:50:56.883Z","3.9.20-beta5":"2025-04-23T07:40:56.216Z","3.9.20-beta7":"2025-04-28T04:16:24.173Z","3.9.20-beta8":"2025-04-30T16:27:32.908Z","3.8.97":"2025-04-30T17:21:48.816Z","3.9.20-beta9":"2025-04-30T17:49:55.794Z","3.8.98":"2025-05-13T08:49:38.612Z","3.8.99":"2025-05-15T06:33:06.042Z","3.9.20-beta10":"2025-05-15T06:38:28.958Z","3.8.100":"2025-05-16T08:31:05.327Z","3.9.0-beta.1":"2025-05-16T08:48:37.488Z","3.8.0-beta.1-a":"2025-06-24T02:18:11.817Z","3.8.0-beta.1-b":"2025-06-24T03:33:39.977Z","3.9.0-beta.2":"2025-06-24T03:45:24.400Z","3.9.0-beta.3":"2025-06-24T04:16:29.762Z","3.8.0-beta.1-c":"2025-06-24T04:18:43.107Z","3.9.0-beta.4":"2025-06-24T04:25:23.859Z","3.9.0-beta.5":"2025-07-29T02:07:17.610Z","3.9.0-beta.6":"2025-07-29T03:25:28.972Z","3.8.0-beta.1-rc":"2025-10-01T07:42:39.316Z","3.9.0-beta.7-rc":"2025-10-01T07:42:58.368Z","3.9.0-beta.8":"2025-12-19T07:46:19.969Z","3.9.0-beta.9":"2025-12-19T09:28:30.624Z","3.8.0":"2025-12-19T09:52:14.015Z","3.9.0-beta.8-rc":"2025-12-19T09:56:36.562Z","3.9.0-beta.9-rc":"2026-05-11T04:08:56.319Z","3.9.50":"2026-05-11T04:13:19.394Z","3.9.51":"2026-05-11T04:22:19.309Z","3.9.52":"2026-05-11T04:31:41.019Z","3.9.55":"2026-05-11T08:29:27.502Z","3.9.56":"2026-05-11T08:38:46.768Z","3.9.57":"2026-05-11T10:53:29.407Z","3.9.58":"2026-05-12T10:16:14.077Z","3.9.59":"2026-05-12T15:48:45.200Z","3.9.0-beta.10-rc":"2026-05-13T10:05:15.541Z","3.9.0-beta.11-rc":"2026-05-13T14:46:35.498Z","3.9.60":"2026-05-13T15:31:13.057Z","3.9.69":"2026-05-13T15:42:29.268Z","3.9.70":"2026-05-14T08:29:51.497Z","3.9.71":"2026-05-18T10:10:56.437Z","3.9.72":"2026-05-19T06:26:55.226Z","3.9.73":"2026-05-19T07:13:15.448Z","3.9.75":"2026-05-20T04:45:18.461Z","3.9.80":"2026-05-21T16:43:24.860Z"},"bugs":{"url":"https://github.com/bombkiml/beech-api/issues"},"license":"MIT","homepage":"https://github.com/bombkiml/beech-api/blob/master/README.md","keywords":["api","node-api","api-framework","beech-api","cli","nodejs"],"repository":{"url":"git+https://github.com/bombkiml/beech-api.git","type":"git","directory":"packages/cli"},"description":"Command line interface for rapid Beech API development","maintainers":[{"name":"bombkiml","email":"nattapat.jquery@gmail.com"}],"readme":"[![N|Solid](https://i.ibb.co/NKxx9NQ/beech320.jpg)](https://github.com/bombkiml)\n\n# Beech API framework\n#### Auto endpoint v.3.9.0 (LTS)\n\n[![beech-api release](https://img.shields.io/github/v/release/bombkiml/beech-api)](https://github.com/bombkiml/beech-api/releases/)\n[![PyPI license](https://shields.io/pypi/l/ansicolortags.svg)](https://github.com/bombkiml/beech-api/blob/master/README.md)\n\n# What is Beech API ?\n\nThe Beech API is API framework, It's help you with very easy to create API project under [Node.js](https://nodejs.org)\n\n## Let's go\n- <b>[Installation](#installation)</b>\n- <b>[Creating a project](#creating-a-project)</b>\n- <b>[Upgrade to latest version](#upgrade-to-latest-version)</b>\n- <b>[Beech CLI tool available](#beech-cli-tool-available)</b>\n- ✨ <b>Automation Endpoints with CRUD</b>\n  - [Database Connection](#database-connection)\n    - [Model](#models)\n  - [Retrieving data with Query String](#retrieving-data-with-query-string)\n    - Conditions\n    - Grouping\n    - Ordering\n    - Timestamps (Add-on in Store and Update)\n  - [Transactions](#-transactions)\n    - [Disorganized transactions](#way-1---disorganized-transactions-)\n    - [Organized transactions](#way-2---organized-transactions-)\n    - [Transactions set Isolation levels](#way-3---transactions-set-isolation-levels-)\n  - [Endpoints](#endpoints)\n  - [Helpers](#helpers)\n- 🔐 <b>System Management of Authentication</b>\n  - [Authentication Manegement](#authentication-passport-jwt)\n    - [Request Token](#request-token)\n    - [Beech Guard](#beech-guard)\n      - Verify Identity Management\n      - Two Factor (2fa, OTP, etc.)\n    - [Beech User Authentication Managements](#-beech-user-authentication-managements)\n      - Create Auth\n      - Update Auth\n- 🛠️ <b>Safe Endpoints Request</b>\n  - [Rate Limit](#-custom-endpoint-specific-rate-limit)\n  - [Slow Down](#-custom-endpoint-specific-slow-down)\n  - [Block Duplicate Request per Window](#-custom-endpoint-specific-duplicate-request)\n  - [JWT Broken Role](#jwt-broken-role)\n  - [Advance Guard (Timimg)](#-beech-advanced-guard-timing)\n- 🙂 <b>Hight Security under passport-jwt, oauth2</b>\n- 🌐 <b>Supported Official Strategy</b>\n  - [Google](#-google-strategy)\n  - [Facebook](#-facebook-strategy)\n- 🖥️ <b>CORS Origin & Server Configuration</b>\n  - [Config Base public path `./`](#cors-origin--server-configuration)\n  - [Allow origin whitelist](#cors-origin--server-configuration)\n- 📚 <b>Databases Managements</b>\n  - [Migrations](#databases-managements)\n  - [Seeder](#-creating-first-seeder)\n- ☕ <b>Testing</b>\n  - [Jest](#testing)\n- 🏃 <b>Implementration</b>\n  - [Building for Production](#building-for-production)\n  - [Docker](#implementation)\n  - [PM2](#-implement-with-pm2)\n\n# Environment\n\n- [`Node.js`](https://nodejs.org) >= 18.18.0+ (recommended)\n\n# Installation\n\nBeech API needed Node.js version 18.18.0 or above. You can management multiple versions on the same machine with [nvm](https://github.com/creationix/nvm) or [nvm-windows](https://github.com/coreybutler/nvm-windows).\n\n<b>So, Let's go to install</b> `beech-api`\n\n```sh\n# NPM\n$ npm install beech-api --global\n\n# Yarn\n$ yarn global add beech-api\n```\n\nInstallation demo:\n\n[Demo 1](https://i.ibb.co/TBjNgVrF/1-11.gif)\n![Alt Text](https://i.ibb.co/TBjNgVrF/1-11.gif)\n\n[Demo 2](https://i.ibb.co/wrdgyzDP/ezgif-8539024298ec62a9.gif)\n![Alt Text](https://i.ibb.co/wrdgyzDP/ezgif-8539024298ec62a9.gif)\n\nAfter installation, you will have access to the `beech-app` binary in your command line.\nYou can check you have the right version with this command:\n\n```sh\n$ beech-app --version\n```\n\n# Creating a project\n\nCreate a new project run:\n\n```sh\n$ beech-app create hello-world\n```\nRun your project:\n```sh\n$ cd hello-world\n\n$ npm run dev\n# OR\n$ yarn dev\n```\n\n❓ **Note:** The Beech API it's start server at [http://localhost:9000](http://localhost:9000) you can change new a port in `app.config.js` file.\n\n\n# Upgrade to latest version\nThe Beech API upgrade to latest version command avariable :\n\n```sh\n// Project upgrade\n$ beech-app update\n\n// Global upgrade\n$ beech-app update -g, --global\n```\n\n# Beech CLI tool available\nAfter installation, you will have access to the `beech` binary in your command line.\nThe `beech` command has a number of options and you can explore them all by running:\n\n```sh\n$ beech --help\n```\n\nThe `beech` command line available:\n\n```\nUsage:\n  $ beech [options] [arguments] [special]\n\nOptions:\n  ?, -h, --help                       Display this help message.\n  -v, --version                       Display the application version.\n\nCommands:\n  $ beech make <endpoint>             Create a new Endpoints and unit test file.\n                                      Use [special] `-R, --require` to select Model(s).\n\n  $ beech make <model> --model, -M    Create a new Models file.\n                                      Options:\n                                      --no-comment   Ignore property comments in Schema.\n                                      --name <custom_name>  Rename for the Model file.\n\n  $ beech update model <model_name>   Update existing Model with latest DB structure.\n                                      Options:\n                                      --no-comment   Ignore property comments in Schema.\n                                      --name <custom_name>   Rename for the Model file.\n                                      --inject <table_name>  Update schema to latest,\n                                                             from a specific table name.\n\n  $ beech make <helper> --helper      Create a new Helpers file.\n  $ beech passport init               Initialize authentication with passport-jwt.\n  $ beech skd init                    Initialize Job Scheduler file.\n  $ beech key:generate, key:gen       Re-Generate application key (Dangerous!).\n  $ beech hash:<text>                 Hash text for Database connection access.\n```\n❓ **Note:** Every to create new project will be generated new ``app_key`` in ``app.config.js`` file.\n\n❓ **Note:** If you can re-generate. Can use command ``$ beech key:generate`` or ``$ beech key:gen``\n\n# Database connection\n\nYou might connection to Database with `database_config` object in `app.config.js` file. Anything can support to multiple Database connections.\n\nThe connection base on `pool_base` in `global.config.js` file.\n\n- `basic` = Support only Raw Query with Only MySQL.\n- `sequelize` = Support PDO, Raw Query with various Database Engine.\n\nIn case Access to Database must to Hash the `username` and `password` with Beech CLI like this.\n\n```sh\n// Hash database username\n$ beech hash:root\nOutput: m42BVxQ6Q4kLdRX7xS_Hm7WbQiNqShJDvw9SLCgI431oafWBtQJoJDnoCL\n\n// Hash database password\n$ beech hash:password\nOutput: FjgcgJPylkV7EeQJjea_EeifPwaHVO9onD3ATk3YYAyvjtMGu3dcDS0ejA\n\n```\n***For Example :***\n\n📂 app.config.js\n```js\n// Database configuration Only Basic & Sequelize (needed Hash)\n\n...\n\ndatabase_config: [\n  {\n    dialect: \"mysql\",\n    name: \"mysql_my_store_db\",\n    host: \"localhost\",\n    username: \"m42BVxQ6Q4kLdRX7xS_Hm7WbQiNqShJDvw9SLCgI431oafWBtQJoJDnoCL\",\n    password: \"FjgcgJPylkV7EeQJjea_EeifPwaHVO9onD3ATk3YYAyvjtMGu3dcDS0ejA\",\n    database: \"my_store_db\",\n    port: \"3306\",\n\n    // Specify global options, which are used when Define is called.\n    define: {\n      charset: \"utf8\",\n      freezeTableName: true,\n      ...\n    },\n\n    timezone: \"+07:00\", // Example: GMT+2\n    // or use a named timezone supported by Intl.Locale\n    // timezone: 'America/Los_Angeles',\n\n    logging: console.log, // SQL trace logs. Learn more: https://sequelize.org/docs/v6/getting-started/#logging\n\n    is_connect: true, // Boolean, Turn ON/OFF to connect\n  },\n\n  ...\n\n],\n\n...\n```\n❓ **Caution! :**  Every re-new generate `app_key`. Must to new Hash your Access and change to ALL Database connections.\n\n❓ **Development** : You can add ```dev: true``` in ```main_config``` for a better experience.\n\n# Models\n\nThe `models` keep the files of function(s) data managemnets for Retriving, Creating, Updating and Destroying (CRUD). for understanding you might make model name same your table name inside `src/models` folder.\n\n```sh\n$ beech make modelName --model\n```\n\n## # Model (Basic)\n\n  Basic model only support `MySQL` Raw Query format and freedom of your SQL query\n\n  ❓ **Note:**  The Basic pool engine it's not support auto Endpoints.\n\n\n***For example :***\n\n📂 models/Fruit.js\n```js\nmodule.exports = {\n\n  // Example basic function get data\n  getData() {\n\n    return {\n      id: 1,\n      name: \"John Doe\",\n    }\n\n  },\n\n  // Example basic function get data from MySQL table\n  getFruit() {\n\n    // calling Pool connection name by `mysql.default_db`\n    mysql.default_db.query(\"SELECT * FROM fruit\", (err, results) => {\n\n      if (err) { throw err }\n      return results;\n\n    });\n\n  }\n\n};\n```\n\n## # Model (Sequelize)\n\n  Sequelize is a promise-based Node.js ORM tool for Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server, Oracle Database, Amazon Redshift and Snowflake’s Data Cloud. It features solid transaction support, relations, eager and lazy loading, read replication and more. <br/>You can learn more: [Sequelize docs](https://sequelize.org/docs/v6)\n  \n  You can asign more DataTypes, Learn more : [Sequelize Data Types](https://sequelize.org/docs/v6/core-concepts/model-basics/#data-types)\n\n  ❓ **Note:** When you generate a model it's create table structure for automatically for you.\n\n***For example :***\n\n📂 models/Fruit.js\n```js\nconst { Schema } = require(\"beech-api\");\n\n// Define table Schema with `Schema(sql.default_db)` connection name\nconst Fruit = Schema(sql.default_db).define(\"fruit\", {\n  fruit_id: {\n    field: \"id\", // Rename PK field to fruit_id Ref: `id` field in fruit table\n    type: DataTypes.INTEGER,\n    autoIncrement: true,\n    primaryKey: true\n  },\n  friut_uuid: {\n    field: \"uuid\",\n    type: DataTypes.STRING(100),\n    allowNull: true,\n    defaultValue: DataTypes.UUIDV4,\n  },\n  fruitName: DataTypes.STRING,\n  fruitQty: DataTypes.INTEGER,\n  fruitPrice: {\n    type: DataTypes.INTEGER,\n    allowNull: false, // Allow null feilds\n  },\n  sort: DataTypes.STRING,\n  createdAt: {\n    type: DataTypes.DATE,\n    allowNull: false,\n    defaultValue: DataTypes.NOW,\n  },\n  updatedAt: {\n    type: DataTypes.DATE,\n    allowNull: true,\n  },\n}, {\n  // Enables timestamps with createdAt and updatedAt\n  timestamps: true,\n  // Custom field names createdAt and updatedAt\n  createdAt: \"createdAt\",\n  updatedAt: \"updatedAt\",\n});\n\nFruit.options = {\n  // Choose one for Allow magic generate default Endpoint (CRUD), It's like magic creating The endpoints for you (CRUD) ✨\n\n  // Option 1: Allow all methods\n  defaultEndpoint: true,\n\n   // Option 2: Allow with specific per methods\n  defaultEndpoint: {\n    GET: true,\n    POST: {\n      allow: true, // allow Auto-Endpoint\n      jwt: {\n        allow: true, // allow JWT\n        broken_role: [\n          { role: [1, 2] },\n        ],\n      },\n      // Rate Limit for POST\n      rate_limit: {\n        windowMs: 15 * 60 * 1000, // 15 minutes\n        limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).\n        // store: ... , // Redis, Memcached, etc.\n        // See more: https://www.npmjs.com/package/express-rate-limit#Configuration\n      },\n      // Duplicate Request for POST\n      duplicate_request: {\n        expiration: 500, // Can't duplicate request for 5 milliseconds each IP requests per `window` (Disabled for Set expiration to 0 zero.)\n      },\n    },\n    PATCH: false,\n    DELETE: false,\n  },\n\n  limitRows: 100, // Limit rows default 100\n};\n\n// Example Finder by id (ORM), Learn more: https://sequelize.org/docs/v6/core-concepts/model-querying-finders/\nfunction exampleFindOneFruitById(id) {\n  return Fruit.findOne({ where: { id: id } });\n}\n\n// Example Raw Query with Model Instances. This allows you to easily map a query to a predefined model\nfunction exampleGetAllFruitWithModelInstance(id) {\n  return Fruit.query(\"SELECT * FROM fruit\", {\n    model: Fruit, // When JOIN table needed register that table [Fruit, ...]\n    mapToModel: true // pass true here if you have any mapped fields\n  });\n}\n\n// Example Raw Query, Learn more: https://sequelize.org/docs/v6/core-concepts/raw-queries/\nfunction exampleGetAllFruit(id) {\n  return Fruit.query(\"SELECT * FROM fruit\");\n}\n\n...\n\n// Export Schema, Function, ...\nmodule.exports = {\n  Fruit,\n  exampleFindOneFruitById,\n  exampleGetAllFruitWithModelInstance,\n  exampleGetAllFruit,\n  ...\n};\n```\n\n## Retrieving data with Query String\n\nNow you can add Query String with Conditional, Grouping and Ordering (Now Support Readonly for GET method)\n\n### ✨ That's cool! It's like magic Creating The Endpoints for you (CRUD) ✨\n\n<b style=\"font-size:12pt\">For Example, Now!</b>, You can request to `/fruit` with methods GET, POST, PATCH and DELETE like this.\n\n| Efficacy |  Method  |        Endpoint        |    Body      | Mode    |\n|:---------|:---------|:-----------------------|:-------------|:--------|\n|  Create  |  POST    | /fruit                 |     { }      | Single  |\n|  Create  |  POST    | /fruit                 |     [ ]      | Bulk    |\n|  Read    |  GET     | /fruit                 |     No       | Fetch   |\n|  Read    |  GET     | /fruit/:limit/:offset  |     No       | Fetch   |\n|  Read    |  GET     | /fruit?someField=1     |     No       | Fetch   |\n|  Read    |  GET     | /fruit?orderby=sort    |     No       | Fetch   |\n|  Read    |  GET     | /fruit?groupby=id      |     No       | Fetch   |\n|  Update  |  PATCH   | /fruit/:id             |     { }      | Single  |\n|  Delete  |  DELETE  | /fruit/:id             |     No       | Single  |\n\nAdd some Basic Conditions, Grouping and Ordering with `QUERY STRING` under GET methods<br/>\n\nRetrieving `fruit` data with GET : `/fruit?someField=[eq,1]&groupby=[id]&orderby=[id,desc]`\n\n***For Example :***\n\n```java\n// WHERE Conditions\nGET: /fruit?id=1                       // id = 1\nGET: /fruit?isActived=[eq,1]           // isActived = 1\nGET: /fruit?fruitName=[like,Banana%]   // fruitName LIKE 'Banana%' (Not allow with date, time)\nGET: /fruit?cost=[gt,50]&qty=[lt,10]   // cost > 50 AND qty < 10\nGET: /fruit/10/0?qty=[lt,10]           // qty < 10 LIMIT 0,10\n\n// Grouping\nGET: /fruit?groupby=id                 // GROUP BY id\nGET: /fruit?groupby=[id,fruitName]     // GROUP BY id, fruitName\n\n// Ordering\nGET: /fruit?oderby=id                  // ORDER BY id ASC\nGET: /fruit?oderby=[sort,desc]         // ORDER BY sort DESC\n```\n\nFor usage avariable:\n\n```java\n// Basics conditions\n=3                                      // = 3\n=[eq,3]                                 // = 3\n=[ne,20]                                // != 20\n=[is,null]                              // IS NULL\n=[not,null]                             // IS NOT NULL\n=[or,[5,6]]                             // (someField = 5) OR (someField = 6) // Not support NULL value\n\n// Number comparisons conditions\n=[gt,6]                                 // > 6\n=[gte,6]                                // >= 6\n=[lt,10]                                // < 10\n=[lte,10]                               // <= 10\n=[between,[6,10]]                       // BETWEEN 6 AND 10\n=[between,[\"2025-01-01\",\"2025-04-30\"]]  // BETWEEN \"2025-01-01\" AND \"2025-04-30\"\n                                        // When assign Datetime format will only support field datatype is `Date`, `Datetime`, `Time`\n\n// OR You can assign Datetime like this.\n=[between,[\"2025-01-01 12:00:00\",\"2025-04-30 15:00:00\"]] // BETWEEN \"2025-01-01 12:00:00\" AND \"2025-04-30 15:00:00\"\n\n=[notBetween,[11,15]]                   // NOT BETWEEN 11 AND 15\n\n// Other operators conditions\n=[in,[1,2,3]],                          // IN [1, 2, 3]\n=[notIn,[1,2,3]],                       // NOT IN [1, 2, 3]\n=[like,\"%Banana\"]                       // LIKE '%Banana' (Freestyle LIKE)\n\n=[notLike,\"Banana\"]                     // NOT LIKE 'Banana'\n=[startsWith,\"Banana\"]                  // LIKE 'Banana%'\n=[endsWith,\"Banana\"]                    // LIKE '%Banana'\n=[substring,\"Banana\"]                   // LIKE '%Banana%'\n\n// Grouping\ngroupby=id                              // GROUP BY id\ngroupby=[id]                            // ORDER BY id\ngroupby=[id,fruitName]                  // ORDER BY id, fruitName\n\n// Ordering\noderby=id                               // ORDER BY id ASC (Basic usage default Ascending)\noderby=[id,asc]                         // ORDER BY id ASC\noderby=[id,desc]                        // ORDER BY id ASC\noderby=[[id,desc],[sort,asc]]           // ORDER BY id DESC, sort ASC\n```\n\n## # Transactions\n\nSequelize does not use transactions by default. However, for production-ready usage of Sequelize, you should definitely configure Sequelize to use transactions.\n\nBeech use Sequelize supports three ways of using transactions:\n\n- ### Way 1 - Disorganized transactions :\n```js\n// First, we start a transaction from your connection and save it into a variable\nconst t = await Fruit.transaction();\n\ntry {\n\n  // Then, we do some calls passing this transaction as an option:\n  const fruit = await Fruit.create({ fruitName: 'Banana', fruitQty: '5', }, { transaction: t });\n  await fruit.addSibling({ fruitName: 'Litle', fruitQty: '2', }, { transaction: t }); // Error function\n\n  // If the execution reaches this line, no errors were thrown.\n  // We commit the transaction.\n  await t.commit();\n\n} catch (error) {\n\n  // If the execution reaches this line, an error was thrown.\n  // We rollback the transaction.\n  await t.rollback();\n\n}\n```\n\n- ### Way 2 - Organized transactions :\n```js\n// First, we start a transaction from your connection and save it into a variable\nFruit.transaction(async t => {\n  try {\n\n    // Then, we do some calls passing this transaction as an option:\n    const fruit = await Fruit.create({ fruitName: 'Banana', fruitQty: '5', }, { transaction: t });\n    await fruit.addSibling({ fruitName: 'Litle', fruitQty: '2', }, { transaction: t }); // Error function\n\n    // If the execution reaches this line, no errors were thrown.\n    // We commit the transaction.\n    await t.commit();\n\n  } catch (error) {\n\n    // If the execution reaches this line, an error was thrown.\n    // We rollback the transaction.\n    await t.rollback();\n\n  }\n});\n```\n\n- ### Way 3 - Transactions set Isolation levels :\n\nThe possible [isolations levels](https://sequelize.org/docs/v6/other-topics/transactions/#isolation-levels) to use when starting a transaction:\n\n```js\nconst { Transaction } = require('sequelize');\n\n// First, we start a transaction from your connection and save it into a variable\nFruit.transaction(\n  {\n    isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE,\n  },\n  async t => {\n    try {\n\n      // Then, we do some calls passing this transaction as an option:\n      const fruit = await Fruit.create({ fruitName: 'Banana', fruitQty: '5', }, { transaction: t });\n      await fruit.addSibling({ fruitName: 'Litle', fruitQty: '2', }, { transaction: t }); // Error function\n\n      // If the execution reaches this line, no errors were thrown.\n      // We commit the transaction.\n      await t.commit();\n\n    } catch (error) {\n\n      // If the execution reaches this line, an error was thrown.\n      // We rollback the transaction.\n      await t.rollback();\n\n    }\n});\n```\n\n# Endpoints\n\nThe `endpoints` keep the endpoints basic request files currently support `GET`, `POST`, `PUT`, `PATCH` and `DELETE`.\n\nSo, you might create new endpoints with constant `endpoint` object variable in `src/endpoints/` folder and file neme must be end with `-endpoints.js`\n\n```sh\n$ beech make endpointName\n```\nYou might using [special] `-R, --require` for choose Model(s) used for that endpoint.\n\n❓ **Note:** If you generate Endpoint Name same Auto-Endpoint it's Override to main Auto-Endpoint to you, (You always have priority).\n\n***For Example :***\n\n📂 endpoints/fruit-endpoints.js\n```js\n// Require Model schema, Function & Others\nconst { Fruit } = require(\"@/models/Fruit\");\n\nexports.init = () => {\n\n  // GET method\n  endpoint.get(\"/fruit\", Credentials, async (req, res) => {\n    // example call Fruit model for get data\n    res.json({\n      code: 200,\n      status: \"SUCCESS\",\n      results: await Fruit.findAll();\n    });\n  });\n\n\n  // POST method\n  endpoint.post(\"/fruit\", Credentials, (req, res) => {\n    // @response\n    res.json({\n      code: 200,\n      status: \"SUCCESS\",\n      message: \"POST request at /fruit\",\n      result: {\n        id: req.body.id,\n        name: req.body.name,\n      },\n    });\n  });\n\n\n  // PUT method\n  endpoint.put(\"/fruit/:id\", Credentials, (req, res) => {\n    // @response\n    res.json({\n      code: 200,\n      status: \"SUCCESS\",\n      message: \"PUT request at /fruit/\" + req.params.id,\n    });\n  });\n\n\n  // DELETE method\n  endpoint.delete(\"/fruit/:id\", Credentials, (req, res) => {\n    // @response\n    res.json({\n      code: 200,\n      status: \"SUCCESS\",\n      message: \"DELETE request at /fruit/\" + req.params.id,\n    });\n  });\n\n  ...\n\n}\n```\n\n# JWT Broken Role\n\nThe **JWT Broken Role** mechanism provides a flexible way to bypass or override role-based authorization rules when using JWT.\n\n#### It can be applied in three different levels, depending on your use case.\n\n| Priority | Level \t                         | Scope                    | Best For                        |\n|:---------|:--------------------------------|:-------------------------|:--------------------------------|\n| 3rd      | Global (``passport.config.js``) | All endpoints            |\tCommon authorization exceptions |\n| 2nd      | Model-level options             |\tPer model & HTTP method |\tStructured, reusable rules      |\n| 1st      | Endpoint middleware             |\tSingle endpoint\t        | Custom or special cases         |\n\nThis multi-layer approach allows you to design **secure, flexible, and maintainable JWT authorization flows**.\n\n### 1. Global Configuration (passport.config.js) - Priority 3\n\nYou can define global JWT Broken Role rules that apply to all endpoints by configuring them in ``passport.config.js``.\n```js\nmodule.exports = {\n  // Enable JWT authentication\n  jwt_allow: true,\n\n  ...\n\n  // Global JWT broken role configuration\n  jwt_broken_role: [\n    {\n      role: [0, 2, 4],\n      email: \"john.doe@company.com\",\n    }, // Basic role matching\n\n    {\n      role: { $in: [0, 2, 4] },\n      email: { $regex: /@company\\.com$/ },\n    }, // Advanced matching using operators\n  ],\n\n  ...\n};\n```\n\n**Use cases**\n\n- Apply common authorization exceptions across the entire application\n- Support both simple role arrays and advanced operators (``$in``, ``$regex``, etc.)\n\n### 2. Model-Level Configuration (Per HTTP Method) - Priority 2\n\nYou can configure JWT and Broken Role rules per model and per HTTP method using model options.\n\n📂 src/models/Fruit.js\n```js\nFruit.options = {\n  ...\n\n  // Auto-endpoint configuration by HTTP method\n  defaultEndpoint: {\n    GET: true, // Enable auto-generated GET endpoint\n\n    POST: {\n      allow: true,\n      jwt: {\n        allow: true,\n        broken_role: [\n          { role: [5, 6] },\n        ],\n      },\n    },\n\n    PATCH: {\n      allow: true,\n      jwt: {\n        allow: true,\n        broken_role: [\n          { role: [5, 6, 9] },\n          { department: \"IT\" },\n        ],\n      },\n    },\n\n    DELETE: false, // Disable auto-generated DELETE endpoint\n  },\n\n  ...\n};\n```\n\n**Use cases**\n\n- Fine-grained access control per HTTP method\n- Different role requirements for POST, PATCH, etc.\n- Combine role-based and attribute-based conditions\n\n### 3. Endpoint-Level Configuration (Credentials Middleware) - Priority 1\n\nFor maximum flexibility, you can define Broken Role rules directly on a specific endpoint using the Credentials middleware.\n\n📂 endpoints/custom-fruit-endpoints.js\n```js\nconst { Fruit } = require(\"@/models/Fruit\");\n\nendpoint.delete(\n  \"/destroy-fruit-by-id/:id\",\n  Credentials([{ role: [5, 9] }]),\n  async (req, res) => {\n\n    // Only JWT tokens with role level 5 or 9 are allowed\n\n    const deleted = await Fruit.destroy({\n      where: {\n        id: req.params.id,\n      },\n    });\n\n    console.log(\"result:\", deleted);\n\n    // @response\n  }\n);\n```\n\n**Use cases**\n\n- One-off or custom endpoints\n- Highly specific authorization rules\n- Override global or model-level behavior when necessary\n\n## Supported Basic & Operators Usage\n\nThe JWT Broken Role system supports both basic value matching and advanced operators for flexible authorization rules.\n\n| Operator | Meaning            | Description                                                   |\n|:---------|:-------------------|:--------------------------------------------------------------|\n| $eq      | equal              | Matches when the value is equal                               |\n| $ne      | not equal          | Matches when the value is not equal                           |\n| $in      | value IN array     | Matches when the value exists in the specified array          |\n| $not     | value NOT IN array | Matches when the value does not exist in the specified array  |\n| $regex   | regex match        | Matches using a regular expression                            |\n| $fn      | custom function    | Matches using a custom evaluation function                    |\n\n## Evaluation Logic (Very Important !)\n```js\n[\n  { rule1 AND rule1 },\n  { rule2 AND rule2 }\n]\n        ⬇\n        OR\n```\n\n## Basic Usage for Examples :\n\n```js\nCredentials([\n  { role: [9] },         // Only role check\n  { email: 'a@b.com' },  // OR email\n])\n\n// Common Matching Patterns\n{ role: [1, 2, 3] }     // IN\n{ role: 1 }             // Equal\n{ email: 'a@b.com' }    // Equal\n{ department: 'IT' }    // Equal\n{ status: ['active'] }  // Dynamic key\n```\n\n## Operators Usage for Examples :\n\n```js\n// Equal with Role\nCredentials([\n  {\n    role: { $eq: [1, 2, 5] }\n  }\n])\n\n// Not Equal with Role\nCredentials([\n  {\n    role: { $ne: [0, 3] }\n  }\n])\n\n// Regex with Email domain\nCredentials([\n  {\n    email: { $regex: /@company\\.com$/ }\n  }\n])\n\n// IN with Role\nCredentials([\n  {\n    role: { $in: [1, 2, 4] }\n  }\n])\n\n// NOT IN with Role\nCredentials([\n  {\n    role: { $not: [0, 3] }\n  }\n])\n\n// Multiple OR rules\nCredentials([\n  {\n    role: { $in: [1] },\n    email: 'john.doe@company.com'\n  },\n  // OR\n  {\n    role: { $in: [4] },\n    email: { $regex: /@company\\.com$/ }\n  },\n])\n\n// Custom Function\nCredentials([\n  {\n    role: {\n      $fn: (value, user) => value >= 4 && user.department === 'IT'\n    }\n  }\n])\n```\n\n# Helpers\n\nThe `helpers` keep the files of functions for process specific something in the project. So, you might create the `helpers` in path `src/helpers` folder.\n\n```sh\n$ beech make helperName --helper\n```\n\n***For Example :***\n\n📂 helpers/TextEditor.js\n```js\nmodule.exports = {\n\n  textUpperCase(text) {\n    return text.toUpperCase();\n  },\n  \n  textTrim(text) {\n    return text.trim();\n  },\n\n  ...\n\n};\n```\n\n# Authentication (passport-jwt)\n\nPassport is authentication middleware for Node. It is designed to serve a singular purpose: authenticate requests. When writing modules, encapsulation is a virtue, so Passport delegates all other functionality to the application. This separation of concerns keeps code clean and maintainable, and makes Passport extremely easy to integrate into an application.\n\n### Passport-jwt Initialization\n\n```sh\n$ beech passport init\n```\n\nAfter passport initialized the `passport.config.js` it's appeared\n\n📂 passport.config.js\n```js\nmodule.exports = {\n  // Allow for using passport-jwt\n  jwt_allow: true,\n\n  // custom authenticaiton endpoint name, default `/authentication`\n  auth_endpoint: \"\",\n\n  // your jwt secret key\n  secret: \"your_jwt_secret\",\n\n  // token expiry time (seconds), default 86400 sec. it's expired in 24 hr.\n  token_expired: 86400,\n\n  // Allow for using global jwt broken role\n  jwt_broken_role: [\n    // { role: [1, 2, 9] },\n  ],\n\n  model: {\n    // Main sql connection name. You must make sure connection name like inside `app.config.js` file and choose one connection name.\n    name: \"default_db\",\n\n    // table name of users store, default table `users`\n    table: \"\",\n\n    // secret user store field for authenticate, default field `username` and `password`\n    username_field: \"\",\n    password_field: \"\",\n\n    // JWT playload data, You can add it. Example: [\"name\", \"email\", ...]\n    fields: [],\n\n    // Other fields add for authentication.\n    guard: {\n      // Basic guard field, Example: [\"pin\", \"hint\", \"2fa\"]\n      guard_field: [],\n\n      // Advanced guard jwt request (needed some logical from front-end)\n      advanced_guard: {\n        allow: false,\n        entity: \"\", // default entity `timing`\n        secret: \"top_secret\",\n        time_expired: {\n          minutes: 1, // should length [0-60]\n          seconds: 0, // should length [0-60]\n        },\n      },\n    },\n  },\n\n  // Allow for using request with app_key entity (Every request must be using the app_key entity in headers)\n  app_key_allow: false\n\n  ...\n\n};\n```\n### Request Token\n**Authentication structure :** Simple ``users`` table:\n```\n==============================================================\n|  id  |  username | password |     name     |     email     |\n--------------------------------------------------------------\n|  1   |  bombkiml |  secret  | bombkiml NC. | bomb@bomb.com |\n|  2   |  johnson  |  secret  | johnson BA.  | john@bomb.com |\n```\n\nWhen you config passport with ```users``` table already. You will got Auth endpoint in available.\n```js\nPOST:  \"/authentication\"               // Request token\nPOST:  \"/authentication/refresh\"       // Request refresh token\nPOST:  \"/authentication/create\"        // Create new Auth data\nPATCH: \"/authentication/update/:id\"    // Update old Auth data (needed user id)\n```\n\n***XHR Example :***\n\n```js\n// Request with body for gether Token\nPOST: \"/authentication\"\npayload: {\n  username: \"bombkiml\",\n  password: \"secret\"\n}\n\n// Request with header for refresh token\nPOST: \"/authentication/refresh\"\nheaders: Authorization: Bearer <your_token>\n\n// Request with body for Create Auth data\nPOST: \"/authentication/create\"\npayload: {\n  username: \"add_new_username\",\n  password: \"add_new_secret\",\n  name: \"add_new_my_name\",\n  email: \"add_new_email\"\n}\n\n// Request with body for Update Auth data\nPATCH: \"/authentication/update/1\"\nheaders: Authorization: Bearer <your_token>\npayload: {\n  username: \"update_bombkiml\",\n  password: \"update_secret\",\n  name: \"update_my_name\",\n  email: \"my_update_email@bomb.com\"\n}\n```\n\n# Beech Guard\nYou can easy using 2 Factor authenticate with ```guard_field``` inside ```passport.config.js``` file and add your Guard field ex: ```2fa``` field for Authenticate Conditions.\n\n## # Guard (2FA, Other)\n\n📂 passport.config.js\n```js\nmodule.exports = {\n  ...\n\n  guard: {\n    // Other fields add for authenticate, exmaple [\"pin\", \"hint\", \"2fa\"]\n    guard_field: [\"2fa\"], 👈 // your feild guard. (Disabled to remove it.)\n\n    ...\n  },\n\n  ...\n\n}\n```\n\n## # Beech Advanced Guard (Timing)\nAdvance Guard for Protection your Endpoint with Timing. You can allow in object ```advance_guard``` inside ```passport.config.js``` file. So let's go add your Advance Guard Configuration.\n\n📂 passport.config.js\n```js\nmodule.exports = {\n  ...\n\n  guard: {\n    ...\n\n    // Advanced guard to Request (Needed some logical from front-end)\n    advanced_guard: {\n      allow: false, 👈 // advanced guard allow for All Endpoint.\n      entity: \"\", // default entity `timing`\n      secret: \"your_advance_guard_secret\",\n      time_expired: {\n        minutes: 1, // should length [0-60]\n        seconds: 0, // should length [0-60]\n      },\n    },\n  },\n\n  ...\n\n}\n\n```\n\n<b>After configure</b>, You must add some logic in your front-end like this.\n\nBefore add logic, We needed [```beech-auth0```](https://github.com/bombkiml/beech-auth0) and [```moment.js```](https://momentjs.com) for apply in Policy.\n\n```sh\n# NPM\n$ npm install --save beech-auth0 moment\n\n# Yarn\n$ yarn add beech-auth0 moment\n```\nNow! you can add some logic like this.\n\n - Import packages\n\n```js\n// CommonJS\nconst { Auth0 } = require(\"beech-auth0\");\nconst moment = require(\"moment\");\n\n// ES6\nimport { Auth0 } from \"beech-auth0\";\nimport moment from \"moment\";\n```\n\n- Get unix time with momentJS\n\n```js\n// Get UNIX TIME with moment\nlet unix_time = moment().unix();\n```\n\n- Get hashing with Beech Auth0\n\n```js\n// Auth0 Policy.\nAuth0(unix_time, 'your_advance_guard_secret', (error, hashing) => {\n\n  // Your XHR request for All Endpoint.\n  POST: \"/authentication\"\n  headers: { timing: hashing } 👈 // Assign advance guard entity to headers with callback hashing.\n\n});\n\n```\n\n## # Beech User Authentication Managements ###\nYou can easy management `users` data with Beech, Only ```Store, Update``` NO ```Delete```, Anything you can make DELETE endpoint by yourself\n\n```js\nconst { Store, Update } = require(\"beech-api\");\n```\n\n- ***Store*** users data with ``Store()``\n```js\n// prepare data for store users\nvar data = {\n  username: \"bombkiml\",\n  password: \"secret\",\n  name: \"bombkiml nc.\",\n  email: \"bomb@bomb.com\"\n}\n\nStore(data, (err, stored) => {\n  if (err) throw err;\n  \n  // response affected data\n  console.log(stored.insertId, stored.affectedRows);\n\n});\n```\n\n- ***Update*** users data with ``Update()``\n```js\n// prepare data for update users\nvar data = {\n  password: \"new_secret\",\n  name: \"bombkiml NC.\",\n  email: \"bombkiml@bomb.com\"\n}\n\nUpdate(data, id, (err, updated) => {\n  if (err) throw err;\n\n  // response affected data\n  console.log(updated.updateId, updated.affectedRows);\n\n});\n```\n\n# Beech with Official Strategy\n\nLatest supported with ``Google`` and ``Facebook`` Strategy.\n\n\n## # Google Strategy\n\n\nThe Google OAuth 2.0 authentication strategy authenticates users using a Google account and OAuth 2.0 tokens. The strategy requires a verify callback, which accepts these credentials and calls done providing a user, as well as options specifying a client ID, client secret, and callback URL.\n\nBefore your application can make use of Sign In With Google, you must register your app with Google. This can be done in the [APIs & Services](https://console.cloud.google.com/apis) page of the [Google Cloud Platform console.](https://console.cloud.google.com/) Once registered, your app will be issued a client ID and secret which will be used in the strategy configuration.\n\nGo to open file ``passport.config.js`` and go to ``google strategy`` then turn allow Google Strategy is ``allow: true`` something like this.\n\n📂 passport.config.js\n```js\n...\n\nstrategy: {\n\n  google: {\n\n    // Allow for using google strategy\n    allow: true,\n\n    // Authen profile store fields available: `google_id`, `name`, `email`, `photos`, `locate`\n    local_profile_fields: {\n      google_id: \"google_id\", // Google ID field, default field name: `google_id`\n      name: \"your_name_field\",\n      email: \"your_email_field\",\n      photos: \"your_profile_url_field\",\n      locate: \"\" // If you not store set to null or remove it.\n    },\n    // Google development Credentials OAuth 2.0 Client IDs\n    client_id: \"GOOGLE_CLIENT_ID\",\n    client_secret: \"GOOGLE_CLIENT_SECRET\",\n    // Callback endpoint default `/google/callback`\n    callbackURL: \"\",\n    // Failure redirect to your route\n    failureRedirect: \"/login\"\n  }\n}\n\n...\n```\n\nThe above code is a configures and registers the Google Strategy.\n\n- ``allow`` : Turn on/off the Google Strategy config type of ``boolean`` switch by ``true/false``.\n- ``google_id`` : Local Google ID field for store Google ID in my local database default field is ``google_id``.\n- ``local_profile_fields`` : Local Profile fields for store Google user details.\n- ``client_id`` and ``client_secret`` : The options to the Google Strategy constructor must include a ``clientID`` and ``clientSecret``, the values of which are set to the client ID and secret that were obtained when registering your application.\n- ``callbackURL`` : When registering your application. A callbackURL must also be included. Google will redirect users to this location after they have authenticated.\n- ``failureRedirect`` : When registering your application somthing failure it's redirect to that.\n\nPlace a button on the application's login page, prompting the user to sign in with Google.\n\n```html\n<a href=\"/authentication/google\" class=\"button\">Sign in with Google</a>\n```\n\n❓ **Note:** The URL \"``/authentication``\" will be follow by ``auth_endpoint`` when you custom it.\n\n\n## # Facebook Strategy\n\n\nFacebook Login allows users to sign in using their Facebook account. Support for Faceboook Login is provided by the ``passport-facebook`` package.\n\nBefore your application can make use of Facebook Login, you must register your app with Facebook. This can be done in the [App dashboard](https://developers.facebook.com/apps) at [Facebook for Developers.](https://developers.facebook.com/) Once registered, your app will be issued an app ID and secret which will be used in the strategy configuration.\n\nGo to open file ``passport.config.js`` and go to ``facebook strategy`` then turn allow Facebook Strategy is ``allow: true`` something like this.\n\n📂 passport.config.js\n```js\n...\n\nstrategy: {\n\n  facebook: {\n\n    // Allow for using facebook strategy\n    allow: true,\n\n    // Authen profile store fields available: `facebook_id`, `name`, `email`, `photos`, `locate`\n    local_profile_fields: {\n      facebook_id: \"facebook_id\", // Facebook ID field, default field name: `facebook_id`\n      name: \"your_name_field\",\n      email: \"your_email_field\",\n      photos: \"your_profile_url_field\",\n      locate: \"\" // If you not store set to null or remove it.\n    },\n    // Facebook development Credentials OAuth 2.0\n    app_id: \"FACEBOOK_APP_ID\",\n    app_secret: \"FACEBOOK_APP_SECRET\",\n\n    // You can allow Permissions facebook profile fields. Learn more (https://developers.facebook.com/docs/graph-api/reference/v13.0/user#readperms)\n    // **Update 2024, Now! Facebook requests permission for show Email. Learn more (https://developers.facebook.com/docs/permissions)\n    profileFieldsAllow: [ 'id', 'displayName', 'name', 'photos', 'email', 'location' ], // Default allowed\n\n    // Callback endpoint default `/facebook/callback`\n    callbackURL: \"\",\n    // Failure redirect to your route\n    failureRedirect: \"/login\"\n  }\n}\n\n...\n```\n\nThe above code is a configures and registers the Facebook Strategy.\n\n- ``allow`` : Turn on/off the Facebook Strategy config type of ``boolean`` switch by ``true/false``.\n- ``facebook_id`` : Local Facebook ID field for store Facebook ID in my local database default field is ``facebook_id``.\n- ``local_profile_fields`` : Local Profile fields for store Facebook user details.\n- ``app_id`` and ``app_secret`` : The options to the Facebook Strategy must include an app ID and secret. you must register your app with Facebook. This can be done in the [App dashboard](https://developers.facebook.com/apps) at [Facebook for Developers.](https://developers.facebook.com/) Once registered, your app will be issued an ``app ID`` and ``secret`` which will be used in the strategy configuration.\n- ``profileFieldsAllow`` : Permissions with Facebook Login. You must allow Permissions facebook profile fields: see more (https://developers.facebook.com/docs/graph-api/reference/v13.0/user#readperms)\n- ``callbackURL`` : When registering your application. A callbackURL must also be included. Facebook will redirect users to this location after they have authenticated.\n- ``failureRedirect`` : When registering your application somthing failure it's redirect to that.\n\nPlace a button on the application's login page, prompting the user to sign in with Facebook.\n\n```html\n<a href=\"/authentication/facebook\" class=\"button\">Log In With Facebook</a>\n```\n\n❓ **Note:** The URL \"``/authentication``\" will be follow by ``auth_endpoint`` when you custom it.\n\n# CORS Origin & Server Configuration\nThe origin array to the callback can be any value allowed for the origin option of the middleware. Certain CORS requests are considered `complex` and require an initial OPTIONS request (called the `pre-flight request`). You can allowed CORS origin inside file `beech.config.js`\n\n📂 beech.config.js\n```js\nmodule.exports = {\n  defineConfig: {\n    // Base public path when served in development or production.\n    base: process.env.NODE_ENV === \"production\"\n          ? \"/my-api/\" // For Production\n          : \"/\", // For Development\n\n    server: {\n      // Client request allow origin whitelist\n      origin: [\"http://example.com\", \"http://my-webapp:8080\", \"https://cat.io\"],\n      originSensitive: false, // Sensitive with contrasts wording\n\n      // API Request rate limit (Disabled for Remove it.)\n      rateLimit: {\n        windowMs: 15 * 60 * 1000, // 15 minutes\n        limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).\n        // store: ... , // Redis, Memcached, etc.\n        // See more: https://www.npmjs.com/package/express-rate-limit#Configuration\n      },\n\n      // API Duplicate Request (Disabled for Set expiration to 0 zero.)\n      duplicateRequest: {\n        expiration: 500, // Can't duplicate request for 5 milliseconds each IP requests per `window`\n      },\n\n      payload: {\n        // The limit of request body size, json default \"100KB\", urlencoded default \"100KB\". Learn more: https://expressjs.com/en/4x/api.html#express.json\n        json: {\n          limit: \"100KB\", // default: \"100KB\"\n        },\n        urlencoded: {\n          limit: \"100KB\", // default: \"100KB\"\n          extended: true, // default: true (reccomended: true)\n        },\n        file: {\n          uploadAllowMethod: [\"POST\", \"PATCH\", \"PUT\"], // Only apply file upload limit for POST, PATCH, PUT method.\n          allowedTypes: [\"image/jpeg\", \"image/png\", \"application/pdf\"], // Example: Allow only JPEG, PNG, and PDF files. Learn more: https://www.digipres.org/formats/mime-types/\n          limit: 5 * 1024 * 1024, // 5MB (default: Infinity)\n        },\n      },\n\n    },\n  },\n}\n```\n\n❓ **Note:** When you must to allowed all Origin. You can assign `*` or `[]` null value to `origin` variable.\n\n## # Custom Endpoint Specific Rate Limit\nWhen you need assign specific request Endpoint with [express-rate-limit](https://www.npmjs.com/package/express-rate-limit), You can managemnet with Beech object ```rateLimit``` for your custom Rate Limit like this.\n\n```js\nconst { rateLimit } = require(\"beech-api\").Express;\n\n// Specific of your rate limit\nconst specificRateLimit1 = rateLimit({\n  windowMs: 5 * 60 * 1000, // 5 minutes\n  limit: 20,\n  // more...\n});\n\n// Your Endpoints...\nendpoint.get(\"/banana\", specificRateLimit1, (req, res) => {\n  ...\n});\n\n...\n```\n\n## # Custom Endpoint Specific Slow Down\n**DON'T DO IT.** &nbsp; Because it's annoying to users.\n\nWhen you need assign specific request Endpoint with [express-slow-down](https://www.npmjs.com/package/express-slow-down), You can managemnet with Beech object ```slowDown``` for your custom Slow Down like this.\n\n```js\nconst { slowDown } = require(\"beech-api\").Express;\n\n// Specific of your slow down\nconst specificSlowDown1 = slowDown({\n  windowMs: 15 * 60 * 1000,      // 15 minutes\n  delayAfter: 5,                 // Allow 5 requests per 15 minutes.\n  delayMs: (hits) => hits * 100, // Add 100 ms of delay to every request after the 5th one.\n  // more...\n  \n  /**\n   * So:\n   *\n   * - requests 1-5 are not delayed.\n   * - request 6 is delayed by 600ms\n   * - request 7 is delayed by 700ms\n   * - request 8 is delayed by 800ms\n   *\n   * and so on. After 15 minutes, the delay is reset to 0.\n   */\n});\n\n// Your Endpoints...\nendpoint.get(\"/banana\", specificSlowDown1, (req, res) => {\n  ...\n});\n\n...\n```\n\n## # Custom Endpoint Specific Duplicate Request\nThis middleware to Limit each IP duplicated requests per window.\n\nWhen you need assign specific request Endpoint with duplicate request use [express-duplicate-request](https://github.com/bombkiml/express-duplicate-request), You can managemnet with Beech object ```duplicateRequest``` for your custom Duplicate Request like this.\n\n```js\nconst { duplicateRequest } = require(\"beech-api\").Express;\n\n// Specific of your duplicate request\nconst specificDup1 = duplicateRequest({\n  expiration: 500, // Can't duplicate request for 5 milliseconds, Should 0 to disabled\n  // more...\n});\n\n// Your Endpoints...\nendpoint.get(\"/banana\", specificDup1, (req, res) => {\n  ...\n});\n\n...\n```\n\n# Databases managements\n\n## # Migrations & Seeder\n\nJust like you use Git / SVN to manage changes in your source code, you can use migrations to keep track of changes to the database. With migrations you can transfer your existing database into another state and vice versa: Those state transitions are saved in migration files, which describe how to get to the new state and how to revert the changes in order to get back to the old state.\n\nYou will need [Sequelize CLI.](https://github.com/sequelize/cli) The CLI ships support for [migrations](https://sequelize.org/v5/manual/migrations.html) and project.\n\n## # Usage\n\nTo create an empty project you will need to execute `init` command\n\n```sh\n$ npx sequelize-cli init\n```\n\nThis will create following folders inside `databases` folder.\n\n- `config`, contains config file, which tells CLI how to connect with database.\n- `models`, contains all models for your project.\n- `migrations`, contains all migration files.\n- `seeders`, contains all seed files.\n\n## # Configuration\n\nBefore continuing further we will need to tell CLI how to connect to database. To do that let's open default config file `databases/config/database.json` It looks something like this:\n\n```json\n{\n  \"development\": {\n    \"username\": \"root\",\n    \"password\": null,\n    \"database\": \"database_development\",\n    \"host\": \"127.0.0.1\",\n    \"port\": 3306, // IF your another port\n    \"dialect\": \"mysql\"\n  },\n  \"test\": {\n    \"username\": \"root\",\n    \"password\": null,\n    \"database\": \"database_test\",\n    \"host\": \"127.0.0.1\",\n    \"dialect\": \"mysql\"\n  },\n  \"production\": {\n    \"username\": \"root\",\n    \"password\": null,\n    \"database\": \"database_production\",\n    \"host\": \"127.0.0.1\",\n    \"dialect\": \"mysql\"\n  }\n}\n```\n\n❓ **Note:** The database connect default port 3306 if you another port you can add object ``port`` in config.\n\n❓ **Note:** If your database doesn't exists yet, you can just call `npx sequelize-cli db:create` command. With proper access it will create that database for you.\n\n## # Creating first Migrations\n\nCreate `model` use `model:generate` command. This command requires two options.\n\n- `--name`, Name of the model\n- `--attributes`, List of model attributes\n\nLet's create a model name example `User`. See more about of [Datatypes](https://sequelize.org/v5/manual/data-types.html)\n\n```sh\n$ npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string,birhday:date\n```\n\n## # Migrations Up and Down\n\nUntil this step, we haven't inserted anything into the database. We have just created required model and migration files for our first model User.\n\n- **Migrate Up** : you can create that table in database you need to run db:migrate command.\n\n  ```sh\n  $ npx sequelize-cli db:migrate\n  ```\n\n- **Migrate Down** : you can use `db:migrate:undo`, this command will revert most recent migration.\n  ```sh\n  // Step to undo\n  $ npx sequelize-cli db:migrate:undo\n\n  // All to undo\n  $ npx sequelize-cli db:migrate:undo:all\n\n  ```\n\n## # Creating First Seeder\n\nTo manage all data migrations you can use seeders. Seed files are some change in data that can be used to populate database table with sample data or test data.\n\nLet's create a seed file which will add a demo user to our User table.\n\n```sh\n$ npx sequelize-cli seed:generate --name user\n```\n\n## # Seeder Up and Down\n\nIn last step you have create a seed file. It's still not committed to database. To do that we need to run a simple command.\n\n- **Seed Up** : you can execute that seed file and you will have a user inserted into `User` table.\n\n  ```sh\n  $ npx sequelize-cli db:seed:all\n  ```\n\n- **Seed Down** : seeders can be undone if they are using any storage. There are two commands available for that:\n\n  If you wish to undo most recent seed\n\n  ```sh\n  $ npx sequelize-cli db:seed:undo\n  ```\n\n  If you wish to undo a specific seed\n\n  ```\n  $ npx sequelize-cli db:seed:undo --seed <seederName>\n  ```\n\n  If you wish to undo all seeds\n\n  ```sh\n  $ npx sequelize-cli db:seed:undo:all\n  ```\n\n# Testing\n\nTest using [Jest](https://jestjs.io/en/) for testing the project. Jest is a delightful JavaScript Testing Framework with a focus on simplicity. Learn more [Jest docs](https://jestjs.io/docs/en/getting-started.html)\n\nSo, When you make the new endpoints it's automatic create test file end with `.spec.js` in `__test__` folder with constant `baseUrl` variable and `axios` package.\n\n***For Example :***\n\n📂 \\_\\_test\\_\\_/unit/endpoints/fruit-endpoints.spec.js\n```js\nconst endpoint = baseUrl.concat(\"/fruit\");\n\ndescribe(\"Test endpoint : \" + endpoint, () => {\n  it(\"Truthy!\", () => {\n    expect(\"/fruit\").toBeTruthy();\n  });\n\n  it(\"Respond with basic GET status code 200\", (done) => {\n    axios.get(endpoint).then((res) => {\n      expect(200).toEqual(res.data.code);\n      done();\n    });\n  });\n});\n```\n\n# Building for Production\n\nThe Beech API build system is designed to secure your source code without sacrificing performance.\n\nTo start the build process, run the following command from your project root\n\n```sh\n$ npm run build\n# OR\n$ yarn build\n```\n\n❓ **Note:** This command triggers ```beech-service build``` as defined in your package.json.\n\n### # What happens during Build ?\nThe build engine performs the following automated steps:\n\n- **Scanning**: It scans for all .js files in src/ (endpoints, models, helpers) and configuration files.\n\n- **Entry Point Generation**: It retrieves the core engine template (beech.txt) and converts it into a secured server.js in the output folder.\n\n- **Compilation**: Files are minified to reduce size.\n\n- **Obfuscation**:\n\n  - Variables and function names are renamed.\n  - Strings are Base64 encoded.\n  - Performance remains 100% because control-flow logic is preserved.\n\n- **Distribution**: All protected files are placed in the ```./dist``` directory.\n\n### # Deployment Structure ?\nAfter the build is complete, your ./dist folder will look like this:\n\n```sh\ndist/\n├── src/\n│   ├── endpoints/    (Obfuscated)\n│   ├── models/       (Obfuscated)\n│   ├── helpers/      (Obfuscated)\n│   └── etc/          (Obfuscated)\n├── server.js         (Main entry point)\n├── app.config.js     (Obfuscated)\n├── beech.config.js   (Obfuscated)\n├── global.config.js  (Obfuscated)\n└── package.json      (Copied for dependency management)\n```\n\n## # Starting the Production Server ?\nTo run your application in production:\n\n- Upload the contents of the dist folder to your server.\n\n- Install only production dependencies:\n  ```sh\n  npm install --production\n  ```\n\n# Implementation\n\n## # Implement with [Docker](https://www.docker.com)\n\n[Docker](https://www.docker.com) is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.\n\n- ### **Create Dockerfile**\n\nDocker builds images automatically by reading the instructions from a Dockerfile -- a text file that contains all commands, in order, needed to build a given image. A Dockerfile adheres to a specific format and set of instructions which you can find at [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).\n\n📂 Dockerfile\n```js\nFROM node:18-alpine\nENV NODE_ENV=production\nWORKDIR /usr/src/api\nCOPY [\"package.json\", \"package-lock.json*\", \"./\"]\nRUN npm install --production --silent && mv node_modules .\nCOPY . .\nEXPOSE 9000\nCMD [\"node\", \"server.js\"]\n```\n\n- ### **Docker build image**\n\nThe docker build command builds an image from a Dockerfile and a context. The build’s context is the set of files at a specified location ```PATH``` or ```URL```. The PATH is a directory on your local filesystem. The URL is a Git repository location.\n\n```sh\n$ docker build -t <imageName> .\n```\n\n❓ **Note:** You can specify a repository and tag at which to save the new image : ``` $ docker build -t <imageName>:<tags> . ```\n\n- ### **Run docker**\n\n  After create ``image`` you can run docker engine following :\n\n  - ### **Docker Container (Standalone)**\n  ```sh\n  $ docker run -d -p 9000:9000 --name <containerName> <imageName>\n  ```\n\n  - ### **Create Docker Swarm (Cluster)**\n  ```sh\n  # Initiate swarm\n  $ docker swarm init\n  \n  # Run docker service\n  $ docker service create --replicas <instances> --name <containerName> --publish 9000:9000 <imageName>\n  ```\n\n## # Implement with [PM2](https://pm2.keymetrics.io/)\n[PM2](https://pm2.keymetrics.io/) is a daemon process manager that will help you manage and keep your application online. Getting started with PM2 is straightforward, it is offered as a simple and intuitive CLI, installable via [NPM](https://www.npmjs.com/).\n\n```sh\n# Start service as standalone\n$ pm2 start server.js --name <serviceName>\n\n# OR\n\n# Start service as cluster mode\n$ pm2 start server.js --name <serviceName> -i <instances>\n```\n\n# Development\n\nWant to contribute or join for great job!, You can contact to me via\n\n- GitHub: [bombkiml/beech-api - issues](https://github.com/bombkiml/beech-api/issues)\n- E-mail: nattapat.jquery@gmail.com\n- Facebook: [https://www.facebook.com/bombkiml](https://www.facebook.com/bombkiml)\n\n# License\n\nThe Beech API framework is open-sourced software licensed under the [MIT license.](https://opensource.org/licenses/MIT)\n","readmeFilename":"README.md"}