{"_id":"true-di","_rev":"29-f7271e86abd71469553be6865c9267c9","name":"true-di","dist-tags":{"latest":"3.0.0","betta":"2.2.2-betta.0","future":"4.0.2"},"versions":{"0.0.1":{"name":"true-di","version":"0.0.1","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"index.js","scripts":{"test":"jest --coverage && ./.coveralls.sh","build:es":"rm -rf ./es; tsc -p ./tsconfig.esm.json","build:cjs":"rm -rf ./lib; tsc -p ./tsconfig.cjs.json","build":"npm run build:es && npm run build:cjs"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"gitHead":"e657132f4b9e70d1e7bc5c14dd2828cc874132d3","_id":"true-di@0.0.1","_nodeVersion":"12.14.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-EcAr/vX3YJTmRIdziAoYZghU8Kmd59w51k/00f6gMJmMGGkQ7JkWlm1AacTPH44m+yPFonSeB2lJQ5ulGWtPFA==","shasum":"4fcdce22ee9417a0623ea3a866e2d3494f4cd6bc","tarball":"https://registry.npmjs.org/true-di/-/true-di-0.0.1.tgz","fileCount":16,"unpackedSize":20177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9iN7CRA9TVsSAnZWagAA2OwQAJ7xM6lEMV0SSEMhO0CO\n6g4hqSu254yz0QaAfgET++FRm3yGI29WKHDgqQKzbY13srYaOnb2bCjz1B4T\n2LSMj9DUmtbSNRmHgcHCNuuwNYNu3r1tGlDzLMixtevrQ/f8bFj/0Ke74Dhb\n9dbPQIo+Wepv3wBM2Dy/OQAkrTJO6eIUb7D36JVzCbdlkFy1LdV9834cQSpX\nMXfLepRH4tpfQEVPFWKwmF/+IpcXsFOVaRzNJ1KOCrG/x98TaHEXlu94Mzwv\nSR7/yUAk2vAJjCIUZOaQDd/X3M1qFcwi0WgSs7eOXRGVuIa2VnLpHUu8Tcta\nJ9WB5XjPzN0FD5yplq1a5GWw4nF9UdZy3L3F4dbWJpW0o7Xb+dtS5s7Jt6ZN\n2VPvd5BosuoNBFpBudt1ExkXwLPQy52aeYXSt1scVUcDIKkWDOQ0UNmyoY7G\nS8L6MDYYKJoq4Sq1mfwD7G7BROEvA7pEjKstOXpglJ666Yf7xssRWIGVJWtQ\n1ZSjyOZB02LEq5fn+/ba1v1eAfrZAEyDftkpeeXS+jdbdJD5C6MoSSaD69xJ\n2Jx/uFtfgk0DIBJIYUN1laWLsw0ZIza87o1kNKOM9P8oGojf1o/6qlMnaVRF\nHfVvM3Y5gPxgj5oKV41HRLAHXvGJszuNgXa51iZLlOpxeHk8fwd4oWlwRTpa\nsM9k\r\n=rqRu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFrWQRavuqQ3ExoRe/U+ViX/PgpgoAAYDpbf9NXDQ9ebAiEAlPLkiOPz+j340AkVlV4JSdsjOUFgP/Aue1VK+yBV7Q0="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_0.0.1_1593189243314_0.7840870928704926"},"_hasShrinkwrap":false},"1.0.0":{"name":"true-di","version":"1.0.0","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"index.js","scripts":{"test":"jest --coverage && ./.coveralls.sh","build:es":"rm -rf ./es; tsc -p ./tsconfig.esm.json","build:cjs":"rm -rf ./lib; tsc -p ./tsconfig.cjs.json","build":"npm run build:es && npm run build:cjs","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"gitHead":"5b56a4f9cc09fd23664d664ece647ae39c9d4767","_id":"true-di@1.0.0","_nodeVersion":"12.14.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-j8mshP1mPsEHgQ0wOWuyGHgAj3cH4Y7cZe6OtVMZ/taqiEtMKhwArdJRS1/w8ZHuxVXzIZK2POoFxFU3vyXUsw==","shasum":"993fb486f71ac7bbb6a8ab1b903c1414122faad0","tarball":"https://registry.npmjs.org/true-di/-/true-di-1.0.0.tgz","fileCount":64,"unpackedSize":59402,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9iTgCRA9TVsSAnZWagAATtYP+wYgx01Xpcmso/H0SHcz\n9KpO9F18lmkdcoUdAs7DTJiDSyNsRHJdYLfZ5QLK4uaucHmc8b2Jru5S5WVo\nwLMnG0IVggdnJpDoQW+akTCHAazDaWonSQ2vv6huZ0bKYAi7pIIXq2B0bWc2\n4MxNytlYN8k0OsQzdOp5boPivKBk+ocz3cX3kYHyYZZl9ZQBqzi/S7CBKkFe\nLoXQeaPQEbqRlkHqEciRzFFxqbS6IOuaABZ0s8v3cjuE6c0AdW/hh4Pcv+vq\nNHGQY2HAyNcMswjRbEhqg9WQYFk0NSxobZ+S5JAdzn5eakMn8G2h0RhXuWrB\n0Ay/jSi7ELC/mDRdVHiFJ9LshkMNFtKGUbeIlOfvsHRrC/e/moBn2S2KYCv6\nqJ9tArBJUtT3mHMugqDGuamIOQOww/MJDyL7mW+ocy6gDfwAXJPE8btL4jbS\nxEvEPEB+w28gVvo0n5bZM7yTcIj5G6zIdcoS+KFwN8dzaPjdqQd1tlALRnqf\nAGOlQpM1OMx10wGH4OWVjZPOJEqBC4k4KkaP66KzWeqXlUmxqLwllkPL6dav\nFz2OWjePpYl3VhDJiv36xqklqjKoroMatZ1oelm1G4M91TTNEdH00X3AoQUv\nqmZCMfDAn4hsdXeAx102GTg5gz5wMsAj1SzXtskadZOkbD4Q+4wUxUdiG2Eu\nItO4\r\n=ureP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCW7Gy8ah7AHhCQdvODfPydYil5EeqjOyHaJKXlmStJQQIgDZ+x6+v9Gw6zm52hFHst6P0to6HyGDScM+h1I2jSHdg="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_1.0.0_1593189599611_0.10536135019265358"},"_hasShrinkwrap":false},"1.0.1":{"name":"true-di","version":"1.0.1","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"index.js","scripts":{"test":"jest --coverage && ./.coveralls.sh","build:es":"rm -rf ./es; tsc -p ./tsconfig.esm.json","build:cjs":"rm -rf ./lib; tsc -p ./tsconfig.cjs.json","build":"npm run build:es && npm run build:cjs","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"gitHead":"f94da09465f99dbc91b9911579507a3a184b1304","_id":"true-di@1.0.1","_nodeVersion":"12.14.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-8YP5GwV5swHUOsoIBN1rEJ2LQ6LE/j5MV2pHZE8zoJTIyAZWW9u+aoX+Q4aK/pePdGPQLcDmcUUrfZyOa7bgRQ==","shasum":"d41b3477152551c9551da47255315a5661ed059f","tarball":"https://registry.npmjs.org/true-di/-/true-di-1.0.1.tgz","fileCount":65,"unpackedSize":59452,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9ijQCRA9TVsSAnZWagAAlukQAJ9XYa8Pb1NKCIdehRWE\n5vmKQq/Rlkd2DRZ+ao6xizIeu0+/ygSbBh4IfRceIMSG80Szj8alBSnVxqTk\nGXsSZ+JItby21/Bx+ku9xnmSMlb/QL6o4CiEL5cJen8QC8NmHEyRLprmHkUg\nTANpSuFq2wvDhtIflTcUyoKLS6f4hP8ApPii8GCIIAXHFw1sQOUcYW28Eb3Z\nqqlT1QEdBgj0FflYPHgHMI66VHH4QdPc1wzZ+VRDMWqPYCONAPz5yY8aULYB\nZUc2sHQHQg8AKGZPvKRrfmO3gMQUziumw1/jNA6AYmTWOAp+xC2z371zVUCc\n1yQyRFC6tRMrOqcpuSzO1fCLadhnDX67XSIajuuke52/80KEyhMMV5AiIGCs\nAPl8Ay53nc1AvINjOdcXk2rnvZukYe8DJOE7lnddSaYEB+2ZWg/KHxciqma4\nHZ20t+Yq0pPkR+XLRlhgc14/EFXTv+JGg0GTGZlIEoZGVkZz7MZlxx2qPes9\nK38PB772E3Un3pmrfTTFvt82I6S/9qek74nt32+LG7/9A5G8FajPpbcTQNEY\no9DeUHgMP/3sfbckr3St87yG+VYJWWx4BUNc+4O2fbSIq5+kOoEEirJOr8+R\n8z1TvCAUMpQWlNcu+BwuP+AfN0jmcFJidimMweraMfk3Gml25D0vVvDOChtr\nIuti\r\n=7C1y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC6AIndEIcCtwwwpUshrVLcAUwGdrY+e9CWjnz4rGM98wIhAIwiLIaZbEXE/ZkRy5nZouGIOQbRRXPoW5Kp/ywrJUO9"}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_1.0.1_1593190607652_0.17004459169981856"},"_hasShrinkwrap":false},"1.0.2":{"name":"true-di","version":"1.0.2","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"index.js","scripts":{"test":"jest --coverage && ./.coveralls.sh","build:es":"rm -rf ./es; tsc -p ./tsconfig.esm.json","build:cjs":"rm -rf ./lib; tsc -p ./tsconfig.cjs.json","build":"npm run build:es && npm run build:cjs","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"gitHead":"d0df41e72b5a24cc7bc266d809b36f44bb47aa90","_id":"true-di@1.0.2","_nodeVersion":"12.14.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-N7ex9w70QXvySVXWr+zxY8+uprmE6SKe13JuHYKLqW0ukZCHBQipeT2H242/xTQujHWhFxNodJcM8jG6B5CTKA==","shasum":"3e8c7724af99768aa593bcce49b715088eb60ad9","tarball":"https://registry.npmjs.org/true-di/-/true-di-1.0.2.tgz","fileCount":67,"unpackedSize":59688,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9iusCRA9TVsSAnZWagAAyvIQAI4hr6iCzw7fUnPYI4iX\nqeLmHra8EsuJjnS8xmtXJDGoopnEmEPFeAeVJq+TsZToLBGho+GZwHenXlU8\nNEq3fD6GTi1b/VW8Sll/pa6hHOPazs0PGi7xdjLHeSFGLwrLLVUTJcguWEx9\nZlfv9gEsTUD5uig5BMCkCjNZudTukmcEAsEUns4rBs6bTKl7BRNvjLApHOmQ\n8DURChPaqNYfXyg1N9Ij/n62cs5/EI3pOPHmWt7FAwdxFQ/lBmvjSeQtzjw1\nw8thjqlmPyNgJJORgDs2LcmhglttSby1vp3qvqwb6UmxRQqvXEdKLm14EKL0\ncVQu/0FQVqOEEsuoC6kJNhNV6jUgDTWH5psZ0f2S+cE8czm6KrAhcPM1LxwV\nOWeL8bfAGpRN+dOoIY11ivK+AR9iCwMJCKErdYvHW7RnIKwOkQ34TeTbbQAN\nN2dX1EoYAksd9poBIi8sNdTcD14WCD3nMzSnX1HwtKA3TPNcPFN8sJI5rWiL\nska+XqvA1zP2GHaxl5rbRWHVi4F7rzukIfqFxFFZkrGXzegKQh0iZo3tuyFA\n53b6g6crVtoVeQuFfixliBgSex4zNBJn+FYWH17qriKY9z+SEaqU7zuz+GzQ\n/0c3zFX/03zca+SFinJ13XlVBVO5jkXhf43YN+V7wQ+kWcKnr/1hpHKFxr6g\nTsl/\r\n=hskO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD65EujYrBzTNzjxNyqBR9yeAR/ctyzgiQSQyirjo6b8AIgOXkLmcEyLvsfnz5al2gcLEhctem5uLhMhd3FP4hXhG4="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_1.0.2_1593191340383_0.29345406503980276"},"_hasShrinkwrap":false},"2.0.0":{"name":"true-di","version":"2.0.0","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/"]},"readme":"# true-di\n\n`true-di` is a Simple Dependency Injection Container for TypeScript and JavaScript\n\n[![Build Status](https://travis-ci.org/DScheglov/true-di.svg?branch=master)](https://travis-ci.org/DScheglov/true-di) [![Coverage Status](https://coveralls.io/repos/github/DScheglov/true-di/badge.svg?branch=master)](https://coveralls.io/github/DScheglov/true-di?branch=master) [![npm version](https://img.shields.io/npm/v/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![npm downloads](https://img.shields.io/npm/dm/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/DScheglov/true-di/blob/master/LICENSE)\n\n## Installation\n\n```bash\nnpm i --S true-di\n```\n\n```bash\nyarn add true-di\n```\n\n## Documentation\n\n[Read Documentation on Git Book](https://dscheglov.gitbook.io/true-di/)\n\n## Usage Example:\n\n**./src/container.ts**\n\n```typescript\nimport diContainer from 'true-di';\nimport { IContainer } from './interfaces';\nimport Logger from './Logger';\nimport DataSourceService from './DataSourceService';\nimport ECommerceService from './ECommerceService';\n\n\nconst container = diContainer<IContainer>({\n  logger: () =>\n    new Logger(),\n\n  dataSourceService: ({ logger }) => \n    new DataSourceService(logger),\n\n  ecommerceService: ({ logger, dataSourceService }) =>\n    new ECommerceService(logger, dataSourceService),\n});\n\nexport default container;\n```\n\n**./src/controller.ts**\n\n```typescript\nimport Express from 'express';\n\nexport const getOrders = async (req: Express.Request, res: Express.Response) => {\n  const { ecommerceService } = req.container;\n  res.json(\n    await ecommerceService.getOrders()\n  );\n}\n```\n\n**./src/index.ts**\n\n```typescript\nimport express from 'express';\nimport container from './container';\nimport { getOrders } from './controller';\n\nconst app = express();\n\napp.use((req, res, next) => {\n  req.container = container;\n  next();\n});\n\napp.get('/orders', getOrders);\napp.listen(8080);\n```\n\n### [Live Demo on Sandbox](https://codesandbox.io/s/express-di-example-w2gme?expanddevtools=1&fontsize=14&hidenavigation=1&initialpath=%2Forders&module=%2Fsrc%2Fcontainer.ts&moduleview=1&theme=dark)\n\n![Live Demo Preview](./docs/assets/image.png)\n\n## Why `true-di`?\n\n1. It's light and idiomatic.\n1. It works with **JavaScript** and **TypeScript**.\n1. It's well-typed. Items types are always known whenever your code assess them.\n1. It is Isomorphic: works on Back end and on Front end.\n1. It works with Classes and with Closures.\n1. It doesn't require decorators (annotations).\n1. It doesn't depend on `reflect-metadata`.\n1. It allows referring items without strings or other artificial elements.\n1. It uses `getters` under the hood.\n1. It's lazy: container doesn't create an item until your code requests\n1. It automatically resolves dependencies\n1. It immediately falls down on constructor-injection of cyclic dependency\n1. It supports property-, setter- cyclic dependencies\n1. It doesn't know anything about context but it could be easily placed into the context.\n1. Its containers are composable.\n1. It's SOLID-compatible.\n1. It's more SOLID-compatible then other IOC solutions. Your code doesn't need to depend on the container (nor even on its interface).\n1. It's testable.\n1. It supports symbolic names.\n1. It doesn't have any other dependencies (and it will be kept)\n","readmeFilename":"README.md","gitHead":"ae6ba62c27be2c7ce8d62f9febce72c82c0e6e43","_id":"true-di@2.0.0","_nodeVersion":"14.8.0","_npmVersion":"6.14.7","dist":{"integrity":"sha512-yhQbTuLb9nZdN+0+gcp9M+UCvdBzNbyMqNIQ+Kdwi3ojpN9FCekJ7Zxoe9bCxY90a/xDmxjJrC5jdzIyIFRHRg==","shasum":"782b4716daaede01604d20817df4cdaa45cc51ff","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.0.0.tgz","fileCount":71,"unpackedSize":50344,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfOZeKCRA9TVsSAnZWagAAegwP/RBVSYVEp4ujA1tpceSM\ngKkuoFLCwClC42Kh6fqYneHQ19pMf83WUrU6vfXZmd5zwopogCp79p72xEMb\nDAhpkAGXUXp0L/Xp2XERZcEU2dLSfrkpaRz4W1rZPLLHKhuW74jMPeO6/7R2\njYDLhc67i8bFAuu+12tH2PGBusr1XlUkGAychLuVo6kwGkzvde5GVtEs1pvu\ncjYxooqacryeNV7+QmTwPiPnl03970BagiGE9AlbUgopD66Fqg9KmjseowPF\n8iqupZJN5VJP35UCC2hF4U8VnIdGDdit+zP+/lsYZ2UmdHS1ajwE99lDir8a\np6sPjlE+bMREUHkxXnhs3w+/Uumoc0ZtS7tOneuKELR+0z6OQfUNzRdQKodA\nyBb+9yyG3owcs13h07rRQbeYS3Jp0m9kM8aobLryhXFr5RAeyr10LyR0R5tg\n8MSj4MYKf9+IByBayXyZTDspBo5HrtbCRT/pO//hzCV3ItoZdX1zD86d0HCo\nJdMICfES8yZLYKGxi+S4KxofYx5NFFzj6H+BcSnZ/c0oRLolv0Fcmvu9zrb3\n/DKLL7T+SRDiSGLqkwaKe6GUYn0YhtD7Opstuki7FwZG+hDn1Gm7gCAVt7FH\nWnSo2KTQWSbiYIjp7gomALJOfhYRh41V6fadrqAXrogsZO9ZCQUNQ3kBlOj2\nUM+u\r\n=H3l0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEWvfV051uYRGa0B/i2WZ7/xZOvpzefTbXLyrmXlA2wwIgNRgSV8RuDsHe7JiHCGev9M7ZHpG0cnRSibr6PUUALEc="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.0.0_1597609865774_0.4906650315177197"},"_hasShrinkwrap":false},"2.0.1":{"name":"true-di","version":"2.0.1","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"5c4526bc2993deca1f3ddf25caa692b9dfc2b041","_id":"true-di@2.0.1","_nodeVersion":"12.14.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-r0mIlbyuUFTGwECBe13vDZ+ITE2aDuW0kBgOYhAl7BWshNvelyMen1pA/oG0jH9e5tsK3P2h1Y8n4ZaIalqebg==","shasum":"66908896415757a302d577a925749e7893e34fd0","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.0.1.tgz","fileCount":71,"unpackedSize":50319,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRi1mCRA9TVsSAnZWagAAkFkP/2B+3iBh9FbEfHp7K4YF\npj5pR6Xs5FguEYzWEmttkx2kRVfdvg3CAhYZLzQpZ20RqAJM/cUfeB4Fy4Dc\nPJRYcGIq36FSbl9FZEuNg0SqMJ1+TWYVQkJuFtKdOYi7DJ4BhnqvnWUuNWWu\ns3k1/u7tOqZznqRIf3HBvmV9krMez1DMpLsqE9P06QalcCvgOs/kAsvAE/IL\n17xawLHHhlczOyi94+LYWQutqX/nhtY3ho1dQ30TLcD/FYh6ZEx59rAQE//R\nZJXLok6LSAzWX5V8/uf8qsMfvAjLbkS6Osrwue11+mV5GaCf92sVmIx0EY+n\n9eByZ4RALTkrni0SC6RJSQ3+jl+Kot10dCgFXKgCxbKDiOybJmkkaia1f3qu\nFO99pAAAdOMwI/GCTNcZ618ZlbWW402lQTqAbQrWDJTPJs9vDr2mP98jKU/r\nuwgjlnKFtgjWymd5yz4EhhGKSOjWGsovPXQBWkW4dSzKjbufVnx+dFkDXsUN\nhuMJo3p4B8MQs093T0d8b31dWNP1BatbwixRSDCc1v1D3ATIqIDlqg8g2sQi\nRGhGsaGmOYR/ue9DRPVYNQ2Xn/bt6bKSihyoLM5kAqtAGj4orqu4cZ53n60g\nqjfaG+1Z9kk0quklOC0TAk9a6P6hHxhECN0pJOHFr37LA5N/uCHVT5AJumue\nDo8r\r\n=Ei7n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEE/RXozrK8dhbgiC8haeAym2cuLhI14gj0aOGRDoa/wAiEAizK9Cm8LVlHaihRiuTnUOqRVWpK8W2l2moWBsBXDREI="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.0.1_1598434661665_0.012328518203023497"},"_hasShrinkwrap":false},"2.0.2":{"name":"true-di","version":"2.0.2","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"b4f3a87727b7ed520839ad4cfc857b3586953875","_id":"true-di@2.0.2","_nodeVersion":"12.14.1","_npmVersion":"6.14.8","dist":{"integrity":"sha512-J60W3sz1x2IMvl9lRc0RBTzonAN33IgPqecy6g57kMfnCDA357hJiyCIo43ErOhurPkqWAGIkuTj0eidVkA7/A==","shasum":"d463a524702afca35ae2756fc3798b09f4ffa280","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.0.2.tgz","fileCount":71,"unpackedSize":50309,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfVJpeCRA9TVsSAnZWagAAtRoP+QGp77VIUMTUVoAPsmJa\nZw6/pGvnoHRtD7jhpTpzVVyaPgjmp7Mx0ujADJegjzCOJ5NpnFOLi8acPQPq\n+vUIMw/gDWrFX1Yb2TJp0HZ1yDpdpznMegQETEsmSPATRkUJGm8eUMO3568c\nGcd+PTrK1spZNavu2PRuxeyDhoGPJIhxNUGj4aSSDMVT8neArTG7r24b/WDj\n8WFOGyscq2oYwKDVH/P9r6JGTx7zEA1UltdHurSMVY45WCQsxG/V/BFnnIqi\nWn616nZbsSuPQs71b2CeP4svL4SF+GEuqYCuA50yJPTBIrga4BLLFV80sPwS\nk+btPzIfDNUvuA9MLOcrBOXVF5KNt7KfzeD5O3wkRFj7ZL/Z8MRQ7XePdQRk\n3f76s6YzTuiymp+DSlbMnrQrIWKxjlYHDSuh+XVzz0Rq/wOPQDf2JbdDOn0Y\n675VLHdDEVdTOM0tclBSnLWP9Esx8blLKSW9b2TFU8PvKJKXEYQR02OUU0gz\nAxs3S0ZMoVshXh3lBGDMMkhB8Wcg37jhHveHLwBTrAWqcgBtYnWjr84quKit\ntGtc1Bi9b1VF0DBm1CZ47O6UOgM0R5p4LtRVsSeaC/5fjRu3SpmpppYXItAr\nZnlfuZoTp/XOIfCfJqzJZ8SwqNPV5lrLL3IAEM2qC1yf2K/XFaOLCleGohtZ\n3nId\r\n=nYCw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC7w1amBVOCYBmjJnIZ9xE8RIdQzvht0/IEmA5JUQDfCAiEAvDcEyuaKBc2V0wuqrn5nxVKrPL5w4Yas0W4O4q6qVrU="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.0.2_1599380062035_0.2704168674311329"},"_hasShrinkwrap":false},"2.1.0":{"name":"true-di","version":"2.1.0","description":"Simple Dependency Injection solution for TypeScript and Javascript","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"ad5c1c32c0b5a67a012a1b6c504280408bd831f9","_id":"true-di@2.1.0","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-4hYjEW8REwlMvf32jcWVYw0eyAAWBqJtIzoZK4MvzAGQD7vG8vSmrCHhILWzSH8FYb4Nfg4DB7spUWo6NKoKUw==","shasum":"55f596abeb96252086113961fc994db316ca545e","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.0.tgz","fileCount":80,"unpackedSize":55808,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaZ99CRA9TVsSAnZWagAAmPEP/RDPVNfrryg6ZNl3togr\n1yj/pUwXSpfsbcysZWkRx7pDrvHlVvewJquiJIYhekzf/DjSumnhRAYD1yVM\n4odhWXx9jEmGA5eMZx8y5oDWM1pxf/7ZCidNsveaBx5yak0y5Yrd0w004Osh\nLDWdstnJ34v+VCcVs6781VOCnBF7/dH0U0kzOvIqGc07ox4+CcN6V023//Wo\nC7rQpD8yMGUO2Lo9rZ45zjcCvstFe0IrEPVnLvwT2KJSb7CUeZaBvvcDbvHr\nVGRTyE8jbcinZS0UKKPYUMC0Lw34k05CMaGEyx8sUMWmKmI3BhSPhr5KFWm3\nQB3jNiQU8b3EvS9rLiN7K9m0LCfmLl8KOtkFtjPfGYNCpqbsrk/n5p+zS8yG\nlek30JH6h3bdPHK3lOdarN0VNBSTgDO2SCniOdjs5XcS8wnhOgPnvpnI2Znw\nkKETmCmuk3vFEguDnbQRKUeId6a5vYStyVpzA20ZGUwJJk9UbcV0xRWomq1N\nxbvLlIOu0pr/S7Hfq1mzalQBHu+ivG3TOdEbDdJRVTh1wZRQyNG31088R8Y7\nnBdAmVIiWKohZw0r951QvGvumsAubWdze5J9XlWgyiOuhTxA54waxUlfEH/N\nTSpIe8l7TTilHoNbDHba8egLkd9Tu08/vFqx2Vu6hN+xZeH5nKeNfhKZOkT/\nbigR\r\n=H/zo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAv7tsp0sLz8TSuD4YBzRHS6PpKkQEVTVzUPBWcw5MnwIgcbP4xaplW/9R5PFtRQPSKGISiS22qwyVb5pZrCzwv4w="}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.0_1600757629231_0.6179508222116734"},"_hasShrinkwrap":false},"2.1.1":{"name":"true-di","version":"2.1.1","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"b621521a59aa2c41438a6386936d76545b963913","_id":"true-di@2.1.1","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-zaY3jsf4vWNk7TW38GuUuE/oKwNTil0oDrDyuQBkBNi2tkJA7uekzdELaKDn7vcTVSYyMyWjggA5jcItyLEFjg==","shasum":"c1a05b4567320c06935671a5e1034ef725b1cef4","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.1.tgz","fileCount":80,"unpackedSize":55874,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaaIzCRA9TVsSAnZWagAAUKwP/jdK4Zv+Vs457c3wlS2N\n/l7H7OLAsIoGmucPY55b4kgcOMkZPqZmReQJ2bEPekFyLsd2VTnxemB5gBrJ\nEtuJ41IEMsHfA4T+v4Sf+0Gr5sBcqH7Twhp1WJZzjp/NqBZmf+8RxvDE8Lfd\nJE6gHzUJPdiGJD49oEjn3B/BBwXXl1e6i1kszJHAK96nhR5nS+pBzYvyDP+7\nj1rxVkkglOq6tlHSgpkk/ghu2GW2tC/hfO6VH2vfLJDIaLH0hC14V65y2hJb\nSKI4C0PiJB09eKtK5mqNva3Q5PcuDJdeXcfsHgC42CKcAtV8p1P+f2woaicw\nYLUddMmFoi8AU6p556iLnyAY5yYmuJS1kEESal4k+W9czcOVetIr3Wu+8uyy\n/ooL5P/pufSFF9zY0umCCjfSHlZexrH1WLYzCZ/XxrN2duy8cS5gVl/kWxEk\n+SX8NkgLFAy2zaqcFi69cArKBHadx0st+iEV+8r6Tck/XIDwjJN3tG2ghN1u\nUbjeVdcc6sEaadrBZt6nm401X1dkyKJzVFJomGUkhhYl7ray98S/Bk2f1rvo\nT408L427ltu1uYs8hb1nqj6E4XYkmcrHZRuvUpoJ7DCTab9htMrCeoaIVL+k\nNrNdZlcBEFjR9dxS1ewcG4K+tJ+6Jmg8MVuBBHTg7/2Cg4ZSw4ungytDJ2Em\n6lsi\r\n=5bws\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDkZ+8xO+elFSXT/Nc6A5EUcjLIIboXLqPH6whIPkomRAIhANPoz083oLFRJew3zNGHQXhZt7iVkCOrItdcK70hLcuQ"}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.1_1600758322967_0.6230792674271075"},"_hasShrinkwrap":false},"2.1.2":{"name":"true-di","version":"2.1.2","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"160531b6db0e80c8023f7aac8b41a119c0844ba2","_id":"true-di@2.1.2","_nodeVersion":"12.18.3","_npmVersion":"6.14.6","dist":{"integrity":"sha512-RjcAe/o02uxiaZvNIdNJBuu3um+2X51e22XlpIr19vzjj6mleH/tx6XCouZSqrfUb32eXuwjdzMRTUNK7NUsrQ==","shasum":"93c8c8985b0de6a9fa54d0ccfe5197d6f154bd39","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.2.tgz","fileCount":76,"unpackedSize":58784,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfaiZnCRA9TVsSAnZWagAAhckQAIO/C56JyV7FrWj85UWN\nrGJBvRtcFjwu5VdF3e8d4Y+uSRZ93am4X2NYsNozklp0ehTnsrj3QarkWcNT\nufXfNhe4n8HLYATLYCreHOuQRmcFHf9Gw6Spx9w/+sZU4cxExMZAnFD9iIm2\nqkea18c9ZzVgzIvsZC8Q2W/zLf3cm9SEPuABF2txVmgILCEtKEOVWEhf1e24\nYjlxwr8kFjIWmBQrKCdU+MLjMxaA5yCu3A6SyBVUMukSi1GTt8YOGLyN4gnU\nkl3ZHKYJRrqgCJ05iq5d3+EeVTymaK6qIqvI+UJ+ggr/2XKQyOdffQ4KaU0W\nBbhvJAoqqAmn6Rgp43RP8Vw/tYbPQZebzKp0TsE1YXxnOeIlnbBW8K7Cyjok\n6i6PuV+jSOqqF8FI7FZGcvwZzArqzPzA9N8w9hOZVu/OVnN2AhZU2Uz9/fu3\nLydKh1EH62ihZeLn5GJ0n3GultXbZKJhm9wWn+wouvTNqYHKXM70Or9TyUY9\nQ3kXdwTRSKHYFdloFJLxBDP/TM6Agu76LEXSwKI1qJVp+98KC7ogSB2q8bnF\niXIPFoZ5j8eL9IOdUGAfpSLH6CtxPbUg4LtgE373zVoy+Qnx7njlW84QeSJf\nHFl2JsjW5FLjtvQebjqMS92h2vz51o96GKIhh7KUuYdXVwVwUE6S+ubMWdm2\nKa6g\r\n=ojMm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCDjYdksYCSqe+pGK9/nZycWd0punE0G4Reugfga0azRAIhAKFyV+bC+0vpVEcrqmGqQxss0WHLBc6s0fdUdgZxJHql"}]},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.2_1600792166520_0.9388616917427766"},"_hasShrinkwrap":false},"2.2.0-betta.0":{"name":"true-di","version":"2.2.0-betta.0","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"@typescript-eslint/indent":"off","jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"bcd915426afe8e9a05a1e1bb2290aacd251b035b","_id":"true-di@2.2.0-betta.0","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-g5dXL/MiD5RxJVXjlNiWqr47Cr9mtK+EoUaV9f9Ie0dLqZDgxLqnaG+ow9ZEZ/R34uUsS1I+uddekUXM0Ykf+A==","shasum":"b0511d5e2d161c165c4a0e262a53aab6d150785f","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.2.0-betta.0.tgz","fileCount":81,"unpackedSize":94562,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuX02CRA9TVsSAnZWagAAkqcP/1Qh/e1jR20Nx2Cjut5G\nTXG8GOdRz3pBVstHOeDH7rSP3bXvGBCRLegzEqIMdxD0EFdEoLQfsJpqs74p\nqy+SoxICRlT1otzRyxh++yGh1aaAROXfvoMP8cgOH5sceJ8A2a+LkICGwuz+\ntukgpMc8PzMCHztmxe3LSMyhUu7gjX6vjD8ohYxvYNI/VwWQkP6O5jLXRn1v\n5iRR/ObLtyGrXuP7dkmuMfJELGaPiE11jrxDfWf3ldFSWW3teGPQ0yMpFtqF\nKllwpLnixFmNYXzS4xVMK044ochuV8i5yLSQdQvYQAJIQwiKWevFFVchihh2\n9DVTGBv2J4gOXdT4xzerm+Lh4Vod2axYT4heerfltsL5EaVAVMonB0zw4TCC\nRsRRW5KUcOckce60SjAi5K3grJl+o01AS8flC1RkKtzkXCOGxp/2pX6ToCFV\n3I0mFTVUOAXxlY+Z+uGNewat+lS5bRZwoYTqE+0zaSR1LefdumWa2gu7Sf3F\nztnvMikkBHK9fMS8YuO6i9sHXqbTxtTYZp5rY2eU99TZz5TAHJmJxJPbArF3\n5LXA1YKlEEsv46JmA5SP/Dhzz14rb8+JZ+xObZYrBgwG4oeWPzFeSkucZ4aP\nzYtu7bKA2iZxfNqiIVNaht/8TOTnldNvc/tCJq/Dj8DrHfoCBy3Tu7irlCCx\nQi+1\r\n=q/RE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDbpLre4Av5big49WEHX3Au/Cei4S3UW9o652qa2r1kDAiEA7zhggEQmLU3Xpc2OlTE/mTripSBcuChMXE6rPgn+zaA="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.2.0-betta.0_1605991733478_0.39619671467117334"},"_hasShrinkwrap":false},"2.2.1-betta.0":{"name":"true-di","version":"2.2.1-betta.0","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"@typescript-eslint/indent":"off","jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"readme":"# true-di\n\nFramework Agnostic, Zero Dependency, Isomorphic & Minimalistic **Dependency Injection Container** for TypeScript and JavaScript projects\n\n[![Build Status](https://travis-ci.org/DScheglov/true-di.svg?branch=master)](https://travis-ci.org/DScheglov/true-di) [![Coverage Status](https://coveralls.io/repos/github/DScheglov/true-di/badge.svg?branch=master)](https://coveralls.io/github/DScheglov/true-di?branch=master) [![npm version](https://img.shields.io/npm/v/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![npm downloads](https://img.shields.io/npm/dm/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/DScheglov/true-di/blob/master/LICENSE)\n\n## Installation\n\n```bash\nnpm i --save true-di\n```\n\n```bash\nyarn add true-di\n```\n\n## Documentation\n\n[Read Documentation on Git Book](https://dscheglov.gitbook.io/true-di/)\n\n## Usage Example:\n\n- [Live Demo on Sandbox](https://codesandbox.io/s/github/DScheglov/true-di/tree/master/examples/getting-started?fontsize=14&hidenavigation=1&initialpath=%2Forders&module=%2Fsrc%2Fcontainer.ts&theme=dark)\n- [Example Source Code](./examples/getting-started)\n\n\n**./src/container.ts**\n\n```typescript\nimport diContainer from 'true-di';\nimport { ILogger, IDataSourceService, IECommerceService } from './interfaces';\nimport Logger from './Logger';\nimport DataSourceService from './DataSourceService';\nimport ECommerceService from './ECommerceService';\n\ntype IServices = {\n  logger: ILogger,\n  dataSourceService: IDataSourceService,\n  ecommerceService: IECommerceService,\n}\n\nexport default diContainer<IServices>({\n  logger: () =>\n    new Logger(),\n\n  dataSourceService: ({ logger }) =>\n    new DataSourceService(logger),\n\n  ecommerceService: ({ logger, dataSourceService }) =>\n    new ECommerceService(logger, dataSourceService),\n});\n```\n\n**./src/ECommerceService/index.ts**\n\n```typescript\nimport {\n  IECommerceService, IDataSourceService, Order, IInfoLogger\n} from '../interfaces';\n\nclass ECommerceSerive implements IECommerceService {\n  constructor(\n    private readonly _logger: IInfoLogger,\n    private readonly _dataSourceService: IDataSourceService,\n  ) {\n    _logger.info('ECommerceService has been created');\n  }\n\n  async getOrders(): Promise<Order[]> {\n    const { _logger, _dataSourceService } = this;\n    // do something\n  }\n\n  async getOrderById(id: string): Promise<Order | null> {\n    const { _logger, _dataSourceService } = this;\n    // do something\n  }\n}\n\nexport default ECommerceSerive;\n```\n\n**./src/controller.ts**\n\n```typescript\nimport Express from 'express';\nimport { IGetOrderById, IGetOrders } from './interfaces';\nimport { Injected } from './interfaces/IRequestInjected';\nimport { sendJson } from './utils/sendJson';\nimport { expectFound } from './utils/NotFoundError';\n\nexport const getOrders = (\n  { injected: { ecommerceService } }: Injected<{ ecommerceService: IGetOrders }>,\n  res: Express.Response,\n  next: Express.NextFunction,\n) =>\n  ecommerceService\n    .getOrders()\n    .then(sendJson(res), next);\n\nexport const getOrderById = (\n  { params, injected: { ecommerceService } }:\n    { params: { id: string } } & Injected<{ ecommerceService: IGetOrderById }>,\n  res: Express.Response,\n  next: Express.NextFunction,\n) =>\n  ecommerceService\n    .getOrderById(params.id)\n    .then(expectFound(`Order(${params.id})`))\n    .then(sendJson(res), next);\n```\n\n**./src/index.ts**\n\n```typescript\nimport express from 'express';\nimport container from './container';\nimport { getOrderById, getOrders } from './controller';\nimport { handleErrors } from './middlewares';\n\nconst app = express();\n\napp.use((req, _, next) => {\n  req.injected = container;\n  next();\n});\n\napp.get('/orders', getOrders);\napp.get('/orders/:id', getOrderById);\n\napp.use(handleErrors);\n\nif (module.parent == null) {\n  app.listen(8080, () => {\n    console.log('Server is listening on port: 8080');\n    console.log('Follow: http://localhost:8080/orders');\n  });\n}\n\nexport default app;\n```\n\n## Motivation\n\n`true-di` is designed to be used with [Apollo Server](https://github.com/apollographql/apollo-server) considering to make resolvers as thin as possible, to keep all business logic testable and framework agnostic by strictly following **S**.**O**.**L**.**I**.**D** Principles.\n\nDespite the origin motivation being related to Apollo Server the library could be used with any other framework or library that supports injection through the context.\n\nThe [Getting Started Example](./examples/getting-started) shows how to use `true-di` with one of the most popular nodejs libraries: [Express](https://expressjs.com/). Almost all code in the example (~95%) is covered with tests that prove your business logic could be easily decoupled and kept independent even from dependency injection mechanism.\n\nThanking to business logic does not depend on specific injection mechanism you can defer the\nchoice of framework. Such deferring is suggested by Robert Martin:\n\n> The purpose of a good architecture is to defer decisions, delay decisions. The job of an architect is not to make decisions, the job of an architect is to build a structure that allows decisions to be delayed as long as possible.\n\n[&copy; 2014, Robert C. Martin: Clean Architecture and Design, NDC Conference](https://vimeo.com/68215570),\n\nSummarizing, `true-di` is based on:\n - emulattion of a plain object that allows to specify exact type for each item and makes strict static type checking possible\n - explicit dependency injection for business logic (see example: [./src/container.ts](./examples/getting-started/src/container.ts))\n - transperent injection through the context for framework-integrated components (see example: [./src/index.ts](./examples/getting-started/src/index.ts))\n\n\n## Some useful facts about `true-di`?\n\n1. No syntatic decorators (annotations) as well as `reflect-metadata` are needed\n1. `diContainer` uses `getters` under the hood. Container doesn't create an item until your code requests\n1. Constructor-injection of cyclic dependency raises an exception\n1. The property-, setter- dependency injects is also supported (what allows to resolve cyclic dependencies)\n1. `diContainer`-s could be composed\n1. Symbolic names are also supported for items\n\n","readmeFilename":"README.md","gitHead":"5b4f153c67237da0f5922c3a9654e12270c5eaad","_id":"true-di@2.2.1-betta.0","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-rGhxbBjMS7MW89Dv+gSS3AohN8nmjeEIF7fQoDmtu2HoioVsfDtfP0XtM+W2gipNFzYJBkS07/RbRmIEHpikXA==","shasum":"c33c0c0f786662ff8ca4838222ca0966efa249ca","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.2.1-betta.0.tgz","fileCount":81,"unpackedSize":94593,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf4GYGCRA9TVsSAnZWagAAAHMQAIEMxkWgQWybH2/cPr+C\n6UMHsqmyrbG/TZErao3+s1oPQdhR3rUuYLLySzP6+JuumjU3lXASpiZQV/Zf\nUdrY4DlDZLbKtJZzfHAgxrkjfHEvQ7i3FfAEFbjIMohJmEkwC/Uok4KpYnxG\nJ9j7IGfNw/KcJQqJkdUqnZ98rAghJNnifhGFIpkQ/tz4wOBUzUIIQbkB+Mmu\n6aUrckvO2vMHlapV/lTfZzJ9Lccu423TH6CBiuXbdyCjN1bFmzYd0rCpQucS\nfjyLiRvLwzQioZcIZE/v8KliK25BcdnogIji/iBCgJik9Rr7RetckEmfTf0P\nyrxyCfVWh22M9u+xsdoPJrbq9oZk+oGbVQMFvUpky9S+vkdhZR0FJ2U1e3Mm\n6JCa/rYyl7ZhkEN4Wl+wLAW/rtBUUZbowLVPsoRaTODxPFXSu9rpVnIYbT6E\n85Bwl1NXJWYz/5Uy1MGwt5kXw2osjJ9ayj4GOtPycTSK7PR3fYsrUWpuI1Sa\nT29JkBAGoo0gZXWEt9dB4vw6z7hcBQQFx0JmhMaqqRT3IfavjqgGqgxF5NSR\noXBKLp1Z7ZeqBRhvAJO7jiVmSfbxfPccpxaA/cgqWAyMVLfPfLc0lnKWOCfo\nZDo3QIyGL0GeQnJCliJdv8+GQKV/JYEF3Gr5Fk+3uzsz2cMj9VXdm+HrAzgz\nTt+3\r\n=tI8W\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC/vwiVsFoCMoVwXGpnmhNbsOpdxaIoGAC4V7Mm+SehXwIgTEVpYZ63ZpHSEgjnY/MKoFfzGiylGXGTd3RAgiwEbYE="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.2.1-betta.0_1608541702260_0.7910136437873612"},"_hasShrinkwrap":false},"2.1.4":{"name":"true-di","version":"2.1.4","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"11e92e0c4b9696341a220bcd92ba31f79aa4ec67","_id":"true-di@2.1.4","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-+D4/GlX12a9Ys5WmThQxcqv7xt+k6h4+pI+KPudPUxrKvX5Giq0pb7ra//17RVwU9ZtiqFgyIYt4jNKdWOFctg==","shasum":"1ba35bdd560db02e8d831814b621186e0c0509a3","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.4.tgz","fileCount":76,"unpackedSize":58738,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf4GgDCRA9TVsSAnZWagAAl44P/iPTu636cjS0YMrLMZEx\npB4z4lZfaw6SWGYCGNN40HthRmI82AAZHBAIkUr1FIodG+G6KcIUIZvrq/E3\n+vkR6yC9YqgeZLfTry1E0nikp+yYnvy1CGzNpULmOimT+p0vL8a857VIOmEt\nOb61GUxCPyUfVUArbslf1iGrYRnWE6/pBxUY3A33JVlKgMjnVEw4obmPk8Os\n16PeW323RRaR1P6MhaZMt4vlov4EDQx3iLdlTRZvormXm/FPnefmcjp0c+Ba\nhtu8PlM2wHGYXLhSlBAnjFLP2CwwHla+tOL7nl9rmMqi+JEF2Y/Y31Uk9cX2\nYym/y05HVNRt0mM2tT3fiCraeA6I8HWRY4Xt5aoA1gCMbPUg2o+Cb9CUWWrL\nx4pOLcjgKHweRHLxJRU5oHU9SFEndtwzaETGfdgXS8XWxE2hs2CTBhVZG1H1\n7dcRp+4GBSWmnmHSk0D7E6oBllgIb+TvLbadqKf2HoNknOXoxWtGp8jraHmy\nAY3kY8Lw1p//losea7G9xQ8hPsgIo0auB+ZXhpQ9PCw3Kb8ARN+DZSnjpmGv\na3Mws/cB5U+ehLvZo75IFDOS+OmQu+sQXT2DqKBOQrlUeoMOJPmofxQtQZ1E\ngcPqrjNLV9GEwK2nara+sFSleXbMGd7qBTu4+trJD92KLR4qxdMv0HnNhq2o\nrVJF\r\n=5LZm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD6gwCOGhLr9gQYeDf4AZSvjcXmfw8Vj9rGyBrDssVUEwIhAOR1iB5IbJGmN5QqLrStRzIGj9pLwVi5h/H4Iie+lFV5"}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.4_1608542211064_0.480140333395934"},"_hasShrinkwrap":false},"2.1.5":{"name":"true-di","version":"2.1.5","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"c0ef31c78b60263c3b1af483b1fe83561fe44f67","_id":"true-di@2.1.5","_nodeVersion":"14.15.4","_npmVersion":"6.14.11","dist":{"integrity":"sha512-Qpq0WYZxwGBrh120BCmPvkehBO7ipp86l29B87FdAL0y1GGrsKb9Bzr1CLS1AIpBwjY/7BBIdSOuGJZfUk1BVA==","shasum":"b1211ec00be748801c7956eec795a45142635ed7","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.5.tgz","fileCount":76,"unpackedSize":59258,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgAAn0CRA9TVsSAnZWagAAoJwP/2yq7OvUhn+FiWHPMO++\nfMR9sZuK36yvVr89KLQsrjnVVT0n20djgGNURpBjPpw3zFE8lum1cvmLMRNz\n3fFkMlkRncp5K+AXRiqlk0FWi2/M05e/fbakFOe9x8Avq0w43Y2xX+JRcq87\nenEC+Vf+fnPA9EHIkXtoqtrpN62lZlKoceemKnmrgFy42sLGk8f+1pp3GLtp\nl4GKaWrgEuxFKATgr1tAgTjoumtF321b6gSORV1DONaLOaik40wcNOJY9QyA\nPiKxoFgMxtM8Nru8Y5l+jj4n6xAJYxmivz96Z/mD9BPNp/QnUHowmgHOHVLV\nGK0UNKsM9JsW5C/ewu7YqfHrczJFv/T7FLQa/poxna7QOzhHqYGFmFyYNz51\nOWlT53g8AaaVNFy3RMQYx9ahLw9FtwcXAafbUYIL0lXs0ysp0MG+pcEfjJge\nFtfgSgJuHJPUfLsmF3+nukipYJjLd7sc/vKPgSYwAYg77+cVU1rLhcJcc7DY\nMMXLBOI9HOKLutitXu7HK7VnpcYYqBdzVRmh5Zi+zOewsvDsly3LVGMK4bv3\nyDdvs7ILb69Zu73gi3E+uabEKwwuF4jFn/cU3sEcIJa2mjpW4kOpNy3O6i/m\nnpepGdyUYBnbpoWNQxjtpXXKQoq7G5dp5glK3a42htCJsBLAcpQMXoDsanaX\nxFYl\r\n=eDeO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdjnuMRJGQMf7q4izPBxYBSZpudAWgK6Pat+Gvf9CD2AIgGVyL+cXR0XGcsOLg9s34YI4dEaDXcnJ4c377lNqCRHU="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.5_1610615283627_0.7118571380968481"},"_hasShrinkwrap":false},"2.2.2-betta.0":{"name":"true-di","version":"2.2.2-betta.0","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"@typescript-eslint/indent":"off","jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"563e3b70d1af3c95e848ea725afac90caacee4cb","_id":"true-di@2.2.2-betta.0","_nodeVersion":"14.15.4","_npmVersion":"6.14.11","dist":{"integrity":"sha512-WAY/jWKFuwQ9MP8IlASw9M3zX6NUABLuXj+2LiY7ov8AKGyyIBLIdsnaMZvmma1OOJrrwZo6caCQ7AK2vn1jpA==","shasum":"300984d95f8122c1c2add08764c60e562195891a","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.2.2-betta.0.tgz","fileCount":81,"unpackedSize":95113,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgAAwnCRA9TVsSAnZWagAAgisP/0gcPRpOvp6/7PiUhtZ4\nPYvy7vc1Xc4Km1lmaACSpGb66qh1XWqEf36vEHsdyRmB4TFSzM3EmQBKZZYX\nTSyE5RtxKwjSr/EOvzx9kfNcy2OX6OnSbmDsB9gKECJx0jflxcKdwZb9c9TA\nocHfB7S3UcqXgZVH/tJnPCgenCwRWusk2FQG7Kuar5av2gisHUOegpJelRdw\nL/kcpa5ZzWST/B07e9wDy9tVk/EtXtizEkPLyY4mWstdlS4scrMxEfVSAdZW\niAsdd5InkWAGw4nqDl8doPNs9XsR4XzK19gCn4PY9mdiz3LLjrQTeY2A7oOi\nweLdGQnVFbg2lkN8XEwLdhigzCAVZZvsEbVhFlaxvN7KpYn3AEGWM1M2LJkG\nZyqYDeYaEEPsRW+tUjI4kjzPVEWSquWJewr4CBSm93C+TY37texg2Kdhg67Y\nExj3OohwiNkVibcGSFX/Nx1cNLUsSoULLNbEY1o3R2PXDerOYbNSnC3PynZY\nA5oDSS1HJYH1c/80Ngf/HIgJ/ON3EaxHvFKkzFsjrb91FLTDpl9bFc4B58oc\nUhJHwoiUZqBAgKCbDAm/mgEoPtwmou8dwggLqDxV7XhgmR+vySkWySf9IuhH\n8R/5Wn1qHL3KQE4vY7fIo+MSvqGXPpHJB+QD8m0J/V7dfnub/IvfsXiIv61R\nyq5T\r\n=QQvc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFNkdyb5kB8yglXqGZik+NJdJVT4nKqqEUn5nCmTSZk9AiBqIhqXTmP03sjNlMXdFmxza60RFAYETgongkHL6Wo2+w=="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.2.2-betta.0_1610615846645_0.37646506367245336"},"_hasShrinkwrap":false},"2.1.6":{"name":"true-di","version":"2.1.6","description":"Framework Agnostic, Zero Dependency, Isomorphic & Minimalistic Dependency Injection Container for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"4c8331a3cdc11876a99252f86ffc570267dc65ed","_id":"true-di@2.1.6","_nodeVersion":"14.15.4","_npmVersion":"6.14.11","dist":{"integrity":"sha512-l5WyHqaBiVJlf0UeIRBQT386AVQdUHWBX51+0pubCJuSlO/xRUTZX9vpMDnlLm+T9ycmAE3ateIAGvCZw04wtg==","shasum":"52c40c11f8e48a438f3d6697d650c00ff27d2775","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.6.tgz","fileCount":76,"unpackedSize":59208,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgb4B0CRA9TVsSAnZWagAALmkP/0sYBFTsHAUhUdzUbeDF\nMSoAuoi/UeA7RxAMx1i7gKP2r6lYSrK1re2yumJKu6Q7wle8QMfnmx2zUd0L\nd5sLcLTK2/8cVeyXXuo2SFc+Wx5Ab6+ucSZZ7iNQENeP59LS4L0DAsX1IkIs\nPo3yhczuu+TvNy/92wCmw5Xc+VE3zNGxbYP7PmzbnxQtW1SXBeb68xRcriTE\nth6E+jNNUQs9JKQpFaebur4hTlD2Br9hK/5YVTUMdvrxY6omcVqMnEho/Mfk\nvm2YuB3S8IK6xaQ0q+nIiM+cd2hV85WCXB/vXj7vsNcNy+yiW6sPw66qwNF5\niVkvdORSXWknoChBWlWaZaoyX23EHSVHLe1JxTHJ3OMzQbQ59K+ijDyD56wf\nQvaWljLQ/KMIYURlSxNqpjjdwEfjh9jxoQYfV89mdAaR7v6P+NT0I4u0vDlq\npNgVh1LVIh95IvaSlJJRyE0BJVZYziNhc7II6Eps45GZaUsl89J7cZm8t1Ua\nII3+3bdq3Rwruj2Fym/yamfV8quHWTPQmMN7lHryRBmVNEPyei0UuGhaW2oG\nmdNrSl/vqnl2rb0mXhSzvwP+dxlHkKue15sCekXwqXnn6QlleOmm9LfzUMuT\nwxU9k/m7Kir/6HlDPH0prYdvMMSNUt1rArvl6e0+gzrqfgjKnluC55g87Ol7\nqtS6\r\n=AYug\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICA/I85It9oDb8Ruzx1C3DWgmSF7drVzQy/L2LiD4B3yAiAA5M/37Z/BOsbPdKRmVt2mPHrVBKpElQTOZu9UWUC5ug=="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.6_1617920116507_0.6085865138502278"},"_hasShrinkwrap":false},"2.1.7":{"name":"true-di","version":"2.1.7","description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^24.9.1","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^2.34.0","@typescript-eslint/parser":"^2.34.0","coveralls":"^3.1.0","eslint":"^6.7.2","eslint-config-airbnb":"^18.1.0","eslint-plugin-import":"^2.21.2","eslint-plugin-jest":"^23.13.2","jest":"^25.1.0","ts-jest":"^25.0.0","typescript":"^3.7.5"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"]},"gitHead":"3b16e33b3f475fab7bf1c5cf30e92f03e82aa55d","_id":"true-di@2.1.7","_nodeVersion":"14.15.4","_npmVersion":"6.14.11","dist":{"integrity":"sha512-d2/z+R7bmlnBej1pjigca2h+sX903Y5AuCeT+qWcm0jiogwR/uz2rGbD+8dPkkXynuADaWHG0gLMFsiFZcVtZA==","shasum":"ae8373d5b5ee8d0c4df849953664b734530701e9","tarball":"https://registry.npmjs.org/true-di/-/true-di-2.1.7.tgz","fileCount":76,"unpackedSize":59130,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgdDLKCRA9TVsSAnZWagAASlwQAICMtZ0tFHBwzIRC2eA1\nXh7smTABaSp1Lgi7BMAfCWIpsl/+vn4LgrmdVXGyrmMfEoUNmI/pr1K8PIwt\nQbmC/bCbh3ppruq3upYOArkwDvFzPsCmxiFpHjnmI+1HhHZ0NM9CMj4VGwWo\n9QPPV7PqAYmAc6QaR5SH/iqCmaqZ2eK2I5XhmuCf1NVLXZ6BQOrERMLhI0T/\nBk+JLwQcrf9Gfu1i0OJVleQB8E+YBKR0yvtdW2HHamsZBadtt0sJhWh1VMP0\nP9BQ9QbBUUcF3rls3YWbUSmmX8HLKM1k5X1oyk6h9EM3v65o/DWsNw2gzOJ0\nExFvYtVpZM52ojiXK+DC0amwSmyuYD870LhKBniwIsrlXgwF/ese2iGtK6I3\nYfuoh1hjf/DTZT3PIJs0S6PFI5WQPPCfahLWtstU2Vu49cbzz4kcQ+6LaAiB\nUa/fc9AcEt+Xc2Sk/cdH0qqatR+W3957Ra7jFawAkiwLE9cLOu++87P2E7J3\ntRCzGf0GPHoL3hYO0Udl7zfyz0rBKi9iCa+Y/WR6bUXzBzKqSpUv27Lnpt8i\n4juoKsA1LJ4P0tQHwi6v4NBOecUclA6anBM+DPH3X2zLZjFijov3dvHIch0w\n64vKSud7k7ttnyBPrNoyijHkt+G5wTlIIYIWc1XxoEncLaa9rl7yFoxLR1jq\nFVg4\r\n=FzcA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCSNh/xX6BOwba/B2DIcAxLp7reD2ptx3gBXGQVakTgIAIgIwShs8PA/25eVzUCqQwOFIknW7ioGtG34UuNc3zob3I="}]},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_2.1.7_1618227913924_0.17363786988609675"},"_hasShrinkwrap":false},"3.0.0":{"name":"true-di","version":"3.0.0","description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@types/jest":"^28.1.2","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^5.28.0","@typescript-eslint/parser":"^5.28.0","coveralls":"^3.1.1","eslint":"^8.18.0","eslint-config-airbnb":"^19.0.4","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.5.3","jest":"^28.1.1","ts-jest":"^28.0.5","typescript":"^4.7.4"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"jest":{"preset":"ts-jest","testEnvironment":"node","collectCoverage":true,"collectCoverageFrom":["src/**/*.ts"],"testPathIgnorePatterns":["/lib/', '/es/","/examples"],"globals":{"ts-jest":{"tsconfig":"tsconfig.esm.json"}}},"gitHead":"1a3685ef8e02ac94bc362bb7725d5346b200b81c","_id":"true-di@3.0.0","_nodeVersion":"16.17.0","_npmVersion":"8.15.0","dist":{"integrity":"sha512-EulxoIhlYvXKLoKNm4rhtSB5W4ndCrKL/KAVpPBPW7a5USU0vAcdiehzhBVyEzyTkWnzFzskQa7DsTJVSCceJA==","shasum":"75807a20e27d86b88aec32509b1e6dd274f85153","tarball":"https://registry.npmjs.org/true-di/-/true-di-3.0.0.tgz","fileCount":81,"unpackedSize":57951,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBoph+BRBeyFb2FB4xuVT9d+lp3YLURkiMDke8cRSOOmAiA3M/U2urfUzVNbHRSUam1Rlw6gZHbtG8tcdNylVbHNaw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjHL9QACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqoeA/7B0BtrYliK9vgdoWsR+prM5CeoU1HTvURz1cdLOFHXsxTv95l\r\nRG+YKOTRD/ifpld8ien7RahWeC5syyJP7OPB2V1Xz8vl/l0w7SshmD7+t/VM\r\nhaOTQu1w06q+IqErkE5ysTZW2LC7CzW/r8mE0s+U/vDd8MiBfGpDsoYSyLLb\r\nwK97dvwpYjyhi18ef5efo2Z0msPLFDOONuyC56MmU/KWdVmxd+R0a9sij4XC\r\nIrLcxJLa4BM/DAi7IUwyLOVfaViMsPcFt2YADzQfyOGybrnp7AogDj6TmGUp\r\ni/jmmWDc9GZAtZLzOr8CQuWJIZMYilfqDOBzNulI7WceSNhX/8noA4dmS3YI\r\n/AeBkyuGZ20KZF/Qf/i+hVnAea4mkz8uwIegUP3kZoJAy+QJTMXo5lIAFKYE\r\nXEp076kOuz24JhDrq9Zw2lnpWKfVOzocYgedBFHD6SOc21CmnRGMLvxBgOB6\r\n4Qui861rG3Ymxj6IKrFqAEkF/UZrg1xv5qIraZOki3dV89icayLiDtjml/g0\r\nhqCfHP1Ik8kfPmwOAYA96krMEEUWdH1OTEVDTjIhTW9gmxebs117yqFe3QVK\r\nwn87bPSaSeiXK7S6N+aAI3oti0IjyxcX3mjRq5VLLSisThHEiCR84FeVHvI5\r\nmo2b4/z1kTp+lwiadlELX+Y4Valni/gLU7U=\r\n=xGJR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_3.0.0_1662828367816_0.7241702322989441"},"_hasShrinkwrap":false},"4.0.0":{"name":"true-di","version":"4.0.0","description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@type-challenges/utils":"^0.1.1","@types/jest":"^28.1.2","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^5.28.0","@typescript-eslint/parser":"^5.28.0","coveralls":"^3.1.1","eslint":"^8.18.0","eslint-config-airbnb":"^19.0.4","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.5.3","jest":"^28.1.1","ts-jest":"^28.0.5","typescript":"^4.7.4"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"object-curly-newline":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"gitHead":"5130f59a3c55586a3d954ec67ad7a5a930d45a31","readme":"# true-di\n\nZero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects\n\n[![Build Status](https://travis-ci.org/DScheglov/true-di.svg?branch=master)](https://travis-ci.org/DScheglov/true-di) [![Coverage Status](https://coveralls.io/repos/github/DScheglov/true-di/badge.svg?branch=master)](https://coveralls.io/github/DScheglov/true-di?branch=master) [![npm version](https://img.shields.io/npm/v/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![npm downloads](https://img.shields.io/npm/dm/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/DScheglov/true-di/blob/master/LICENSE)\n\n## Installation\n\n```bash\nnpm i --save true-di\n```\n\n```bash\nyarn add true-di\n```\n\n## Usage Example\n\nThe following code is an example solution that is based on the example used in the book [\"Dependency Injection Principles, Practices, and Patterns\"](https://www.manning.com/books/dependency-injection-principles-practices-patterns) by Steven van Deursen and Mark Seemann.\n\nThe problem is to display the list of featured products and discount their prices for the preferred customers.\n\nMore details on the example could be found in the \"Getting Started\" Example Project\n[README](./examples/getting-started/README.md) file.\n\n### ./src/main.ts - composition root\n\n```typescript\nimport Module from 'true-di';\nimport { DiscountService } from './DiscountService';\nimport { Product } from './domain/products';\nimport { ProductRepoMock } from './ProductRepoMock';\nimport { ProductService } from './ProductService';\nimport { UserService } from './UserService';\nimport PRODUCTS_JSON from './products.json';\n\nconst main = Module()\n  .private({\n    productRepo: () =>\n      new ProductRepoMock(PRODUCTS_JSON as Product[]),\n  })\n  .public({\n    userService: (_, { token }: { token: string | null }) =>\n      new UserService(token),\n  })\n  .private({\n    discountService: ({ userService }) =>\n      new DiscountService(userService),\n  })\n  .public({\n    productService: ({ productRepo, discountService }) =>\n      new ProductService(productRepo, discountService),\n  });\n\nexport default main;\n```\n\n### ./src/DiscountService/index.ts\n\n```typescript\nimport { IDiscountService, IUserProvider } from '../interfaces';\n\nexport const PREFERRED_CUSTOMER_DISCOUNT: number = 0.05;\nexport const NO_DISCOUNT: number = 0;\n\nexport class DiscountService implements IDiscountService {\n  constructor(\n    private readonly userService: IUserProvider,\n  ) {}\n\n  async getDiscountRate() {\n    const user = await this.userService.getCurrentUser();\n    return user != null && user.isPreferredCustomer\n      ? PREFERRED_CUSTOMER_DISCOUNT\n      : NO_DISCOUNT;\n  }\n}\n```\n\n### ./src/ProductRepoMock/index.ts\n\n```typescript\nimport { Product } from '../domain/products';\nimport { IProductRepo } from '../interfaces';\nimport { matches } from '../utils/matches';\n\nexport class ProductRepoMock implements IProductRepo {\n  constructor(private readonly products: Product[]) {}\n\n  async getProducts(match?: Partial<Product>): Promise<Product[]> {\n    return match != null ? this.products.filter(matches(match)) : this.products.slice();\n  }\n}\n```\n\n### ./src/UserService/index.ts\n\n```typescript\nimport { parseToken } from '../domain/user-token';\nimport { User } from '../domain/users';\nimport { IUserService } from '../interfaces';\n\nexport class UserService implements IUserService {\n  #user: User | null = null;\n\n  #token: string | null = null;\n\n  constructor(readonly token: string | null) {\n    this.#token = token;\n  }\n\n  async getCurrentUser(): Promise<User | null> {\n    if (this.#user == null && this.#token != null) {\n      this.#user = parseToken(this.#token);\n    }\n\n    return this.#user;\n  }\n}\n```\n\n### ./src/ProductService/index.ts\n\n```typescript\nimport { applyDiscount } from '../domain/products';\nimport {\n  IDiscountRateProvider,\n  IProductService,\n  IProductsProvider,\n} from '../interfaces';\n\nexport class ProductService implements IProductService {\n  constructor(\n    private readonly products: IProductsProvider,\n    private readonly discountService: IDiscountRateProvider,\n  ) {}\n\n  async getFeaturedProducts() {\n    const discountRate = await this.discountService.getDiscountRate();\n    const featuredProducts = await this.products.getProducts({ isFeatured: true });\n\n    return discountRate > 0\n      ? featuredProducts.map(applyDiscount(discountRate))\n      : featuredProducts;\n  }\n}\n```\n\n### ./src/products-controller.ts\n\n```typescript\nimport type { Request, Response } from 'express';\nimport { JSONMoneyReplacer } from './domain/money';\nimport { IFeaturedProductProvider } from './interfaces/IProductService';\n\ntype GetFeaturedProductsDeps = {\n  productService: IFeaturedProductProvider;\n}\n\nexport const getFeaturedProducts =\n  (req: Request, res: Response) =>\n    async ({ productService }: GetFeaturedProductsDeps) => {\n      const featuredProducts = await productService.getFeaturedProducts();\n\n      res\n        .status(200)\n        .type('application/json')\n        .send(JSON.stringify(featuredProducts, JSONMoneyReplacer, 2));\n    };\n\n```\n\n### ./src/index.ts\n\n```typescript\nimport express from 'express';\nimport createContext from 'express-async-context';\nimport main from './main';\nimport { getFeaturedProducts } from './products-controller';\n\nconst app = express();\n\nconst Context = createContext(\n  req => main.create({ token: req.headers.authorization ?? null }),\n);\n\napp.use(Context.provider);\n\napp.get('/featured-products', Context.consumer(getFeaturedProducts));\n\nif (module === require.main) {\n  app.listen(8080, () => {\n    console.log('Server is listening on port: 8080');\n    console.log('Follow: http://localhost:8080/featured-products');\n\n    console.log(`\n    . .env && curl -H \"authorization: \\${USER_TOKEN}\" http://localhost:8080/featured-products\n    `);\n  });\n}\n\nexport default app;\n```\n\n## Some Concepts\n\n### Module\n\nIn the context of `true-di`, a **Module** is a collection of named and typed\nitems that can communicate with each other. These items can be either\n**private**,meaning they are only accessible within the **Module**, or\n**public**, which allows them to be accessed both inside and outside of the\n**Module**.\n\nEssentially, a **Module** can be thought of as an instance of a class, with\nprivate and public fields. However, in `true-di`, none of the items within the\n**Module** are created until they are requested from outside of the module,\nincluding the function provided to the `.expose` method of the **ModuleBuilder**.\n\nThe **Module** could be created by invoking the **Module Factory** function.\n\n### Module Factory\n\nThe **Module Factory** is a function that takes an object called **external dependencies**\nas input and uses it to create a **Module**. Later on, when an item within the\n**Module** is requested, the corresponding **Resolver** will receive the\n**external dependencies** as input to resolve the item.\n\nIn `true-di`, the **Module Factory** is essentially a composition of Resolvers\nthat have been defined for each item within the module. This means that the code\ndefining the Module Factory serves as the Composition Root, where all loosely\ncoupled components such as classes and functions are brought together and\nassembled in a cohesive manner.\n\n### Resolver & Resolution Rule\n\nThe **Resolver** is an item factory, that receives two parameters:\n\n- **internal dependencies** - an object containing all Module items (excluding\nthe creating one)\n- **external dependencies** - an object passed to the **Module Factory**\n\n**Resolver** is an implementation of the **Resolution Rule**, the rule defines how\nto create a specific item using other items of **Module** and **external dependencies**.\n\nUnlike some other dependency injection solutions, `true-di` does not rely on interfaces\nor type names to define how to create an item. Instead, it uses explicit item\nnames and **Resolvers** defined for each name. This approach avoids the need for\nadditional abstractions in cases where a single interface is implemented by\nseveral different components (classes).\n\nAlso it allows to use `true-di` with JS-projects those don't have any interfaces\nor type names nor in build time, nor in runtime.\n\n### Initializers\n\n**Initializer** - is a function associated with a some item of **Module** that receives\ntwo arguments:\n\n- the **item** to be initialized\n- the **internal dependencies** object with all items of the **Module**\n\nAnd initializes the **item**.\n\nThe **Initializer** is an implement of the \"Injection via property\" pattern\nthat is useful to resolve cyclic dependencies.\n\n> **Note**: The Cyclic Dependencies is an anti-pattern and should be avoided whenever\n> it is possible.\n\nThe **Initializers** is an object that maps item names to correspondent item **Initializer**\n\n### Module Builder\n\n### Module Use Cases\n\n### Life Time Scope\n\n## API Reference\n","readmeFilename":"README.md","_id":"true-di@4.0.0","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-obz7ua8C0KUjfKy3Cyo+F//84FmxCHswSA3BkACQdpX7QT9LT+z/+uRuk3v4poEUMkz+jnX0uL5ZY0wK1MLXHA==","shasum":"73dc4422244dba626c37f65133c481553ce53e10","tarball":"https://registry.npmjs.org/true-di/-/true-di-4.0.0.tgz","fileCount":170,"unpackedSize":135466,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCwt+MUpsF78HT+TCKr2gCTq3SDkz4r3+JcMrFa3tQEKgIgKJoH+9uQZac8IBPC+3CaO1tCMLHtxoT8NVDSjV878c4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHtgyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmroeBAAmjEzqt3NOxWCRjggk6XJNh/SACSyluzxjTcRdAAxOAtzmali\r\naGSVPVzrBLBpEys5tfxvuuRfy9MO7xtpttyQ0LCMgwgUrR6JreNa/2PpIYmO\r\nlVspxR1RAXJ91eO+FY7T7rNgEdn/c/p/u+X5w7ReV8vXYagWiMuLT/TaJ02M\r\nFWkBi1hUI+9AFLYz8EEvHuKjzN3OS8X21fO1cPFpCMPXu/tUp6riL5lGzlUs\r\nifTWUWLVtWsHmQbBEolYVStl5ov66stBHHQKQE47k3VuDv+cLlRDFgh9si0g\r\nHl1NKmWq4TseindGtYA0VFkpsryU7wuj8AYTT2EFdWRQNQ9Yx4PSdPiyl/JL\r\n+u34HLEzUic9GEudP265uqydhLrUbfwxxSy9AEoTh7PO9lm1MgyjMdfWbKjD\r\nn4RzBOB6jSmXzxxpugi1wT7mk6pcQ0Ic4ADo/hOXDtBhAkac2j7DEZMNt/cP\r\nQg/5HjwhLQe4g87UMiX9eOr4ZcZbqj88ZhOYT05bzLxCO+Q7mN9rwVyqSqdK\r\n0CKQDrp4zZrjHMlJdwZVGkYJ5Y9HeXNFvJztHMBedqc1FJ4J6ZPVZkobVK6U\r\nTsR7PS41zA7tQU4lxSKhMwQPnWFxEoOykamnGiSUE20RtxkXS9BF5j05kZsn\r\nWHU/4GbbzhaQmMUabxTNNIdAyurT7aQ4xYE=\r\n=G3jT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_4.0.0_1679743025982_0.7163929980857853"},"_hasShrinkwrap":false},"4.0.1":{"name":"true-di","version":"4.0.1","description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@type-challenges/utils":"^0.1.1","@types/jest":"^28.1.2","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^5.28.0","@typescript-eslint/parser":"^5.28.0","coveralls":"^3.1.1","eslint":"^8.18.0","eslint-config-airbnb":"^19.0.4","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.5.3","jest":"^28.1.1","ts-jest":"^28.0.5","typescript":"^4.7.4"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"object-curly-newline":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"gitHead":"24b13c4be2e3dc08549d9f6704aa644edeb54140","readme":"# true-di\n\nZero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects\n\n[![Build Status](https://travis-ci.org/DScheglov/true-di.svg?branch=master)](https://travis-ci.org/DScheglov/true-di) [![Coverage Status](https://coveralls.io/repos/github/DScheglov/true-di/badge.svg?branch=master)](https://coveralls.io/github/DScheglov/true-di?branch=master) [![npm version](https://img.shields.io/npm/v/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![npm downloads](https://img.shields.io/npm/dm/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/DScheglov/true-di/blob/master/LICENSE)\n\n## Installation\n\n```bash\nnpm i --save true-di\n```\n\n```bash\nyarn add true-di\n```\n\n## Usage Example\n\nThe following code is an example solution that is based on the example used in the book [\"Dependency Injection Principles, Practices, and Patterns\"](https://www.manning.com/books/dependency-injection-principles-practices-patterns) by Steven van Deursen and Mark Seemann.\n\nThe problem is to display the list of featured products and discount their prices for the preferred customers.\n\nMore details on the example could be found in the \"Getting Started\" Example Project\n[README](./examples/getting-started/README.md) file.\n\n### ./src/main.ts - composition root\n\n```typescript\nimport Module from 'true-di';\nimport { DiscountService } from './DiscountService';\nimport { Product } from './domain/products';\nimport { ProductRepoMock } from './ProductRepoMock';\nimport { ProductService } from './ProductService';\nimport { UserService } from './UserService';\nimport PRODUCTS_JSON from './products.json';\n\nconst main = Module()\n  .private({\n    productRepo: () =>\n      new ProductRepoMock(PRODUCTS_JSON as Product[]),\n  })\n  .public({\n    userService: (_, { token }: { token: string | null }) =>\n      new UserService(token),\n  })\n  .private({\n    discountService: ({ userService }) =>\n      new DiscountService(userService),\n  })\n  .public({\n    productService: ({ productRepo, discountService }) =>\n      new ProductService(productRepo, discountService),\n  });\n\nexport default main;\n```\n\n### ./src/DiscountService/index.ts\n\n```typescript\nimport { IDiscountService, IUserProvider } from '../interfaces';\n\nexport const PREFERRED_CUSTOMER_DISCOUNT: number = 0.05;\nexport const NO_DISCOUNT: number = 0;\n\nexport class DiscountService implements IDiscountService {\n  constructor(\n    private readonly userService: IUserProvider,\n  ) {}\n\n  async getDiscountRate() {\n    const user = await this.userService.getCurrentUser();\n    return user != null && user.isPreferredCustomer\n      ? PREFERRED_CUSTOMER_DISCOUNT\n      : NO_DISCOUNT;\n  }\n}\n```\n\n### ./src/ProductRepoMock/index.ts\n\n```typescript\nimport { Product } from '../domain/products';\nimport { IProductRepo } from '../interfaces';\nimport { matches } from '../utils/matches';\n\nexport class ProductRepoMock implements IProductRepo {\n  constructor(private readonly products: Product[]) {}\n\n  async getProducts(match?: Partial<Product>): Promise<Product[]> {\n    return match != null ? this.products.filter(matches(match)) : this.products.slice();\n  }\n}\n```\n\n### ./src/UserService/index.ts\n\n```typescript\nimport { parseToken } from '../domain/user-token';\nimport { User } from '../domain/users';\nimport { IUserService } from '../interfaces';\n\nexport class UserService implements IUserService {\n  #user: User | null = null;\n\n  #token: string | null = null;\n\n  constructor(readonly token: string | null) {\n    this.#token = token;\n  }\n\n  async getCurrentUser(): Promise<User | null> {\n    if (this.#user == null && this.#token != null) {\n      this.#user = parseToken(this.#token);\n    }\n\n    return this.#user;\n  }\n}\n```\n\n### ./src/ProductService/index.ts\n\n```typescript\nimport { applyDiscount } from '../domain/products';\nimport {\n  IDiscountRateProvider,\n  IProductService,\n  IProductsProvider,\n} from '../interfaces';\n\nexport class ProductService implements IProductService {\n  constructor(\n    private readonly products: IProductsProvider,\n    private readonly discountService: IDiscountRateProvider,\n  ) {}\n\n  async getFeaturedProducts() {\n    const discountRate = await this.discountService.getDiscountRate();\n    const featuredProducts = await this.products.getProducts({ isFeatured: true });\n\n    return discountRate > 0\n      ? featuredProducts.map(applyDiscount(discountRate))\n      : featuredProducts;\n  }\n}\n```\n\n### ./src/products-controller.ts\n\n```typescript\nimport type { Request, Response } from 'express';\nimport { JSONMoneyReplacer } from './domain/money';\nimport { IFeaturedProductProvider } from './interfaces/IProductService';\n\ntype GetFeaturedProductsDeps = {\n  productService: IFeaturedProductProvider;\n}\n\nexport const getFeaturedProducts =\n  (req: Request, res: Response) =>\n    async ({ productService }: GetFeaturedProductsDeps) => {\n      const featuredProducts = await productService.getFeaturedProducts();\n\n      res\n        .status(200)\n        .type('application/json')\n        .send(JSON.stringify(featuredProducts, JSONMoneyReplacer, 2));\n    };\n\n```\n\n### ./src/index.ts\n\n```typescript\nimport express from 'express';\nimport createContext from 'express-async-context';\nimport main from './main';\nimport { getFeaturedProducts } from './products-controller';\n\nconst app = express();\n\nconst Context = createContext(\n  req => main.create({ token: req.headers.authorization ?? null }),\n);\n\napp.use(Context.provider);\n\napp.get('/featured-products', Context.consumer(getFeaturedProducts));\n\nif (module === require.main) {\n  app.listen(8080, () => {\n    console.log('Server is listening on port: 8080');\n    console.log('Follow: http://localhost:8080/featured-products');\n\n    console.log(`\n    . .env && curl -H \"authorization: \\${USER_TOKEN}\" http://localhost:8080/featured-products\n    `);\n  });\n}\n\nexport default app;\n```\n\n## Some Concepts\n\n### Module\n\nIn the context of `true-di`, a **Module** is a collection of named and typed\nitems that can communicate with each other. These items can be either\n**private**,meaning they are only accessible within the **Module**, or\n**public**, which allows them to be accessed both inside and outside of the\n**Module**.\n\nEssentially, a **Module** can be thought of as an instance of a class, with\nprivate and public fields. However, in `true-di`, none of the items within the\n**Module** are created until they are requested from outside of the module,\nincluding the function provided to the `.expose` method of the **ModuleBuilder**.\n\nThe **Module** could be created by invoking the **Module Factory** function.\n\n### Module Factory\n\nThe **Module Factory** is a function that takes an object called **external dependencies**\nas input and uses it to create a **Module**. Later on, when an item within the\n**Module** is requested, the corresponding **Resolver** will receive the\n**external dependencies** as input to resolve the item.\n\nIn `true-di`, the **Module Factory** is essentially a composition of Resolvers\nthat have been defined for each item within the module. This means that the code\ndefining the Module Factory serves as the Composition Root, where all loosely\ncoupled components such as classes and functions are brought together and\nassembled in a cohesive manner.\n\n### Resolver & Resolution Rule\n\nThe **Resolver** is an item factory, that receives two parameters:\n\n- **internal dependencies** - an object containing all Module items (excluding\nthe creating one)\n- **external dependencies** - an object passed to the **Module Factory**\n\n**Resolver** is an implementation of the **Resolution Rule**, the rule defines how\nto create a specific item using other items of **Module** and **external dependencies**.\n\nUnlike some other dependency injection solutions, `true-di` does not rely on interfaces\nor type names to define how to create an item. Instead, it uses explicit item\nnames and **Resolvers** defined for each name. This approach avoids the need for\nadditional abstractions in cases where a single interface is implemented by\nseveral different components (classes).\n\nAlso it allows to use `true-di` with JS-projects those don't have any interfaces\nor type names nor in build time, nor in runtime.\n\n### Initializers\n\n**Initializer** - is a function associated with a some item of **Module** that receives\ntwo arguments:\n\n- the **item** to be initialized\n- the **internal dependencies** object with all items of the **Module**\n\nAnd initializes the **item**.\n\nThe **Initializer** is an implement of the \"Injection via property\" pattern\nthat is useful to resolve cyclic dependencies.\n\n> **Note**: The Cyclic Dependencies is an anti-pattern and should be avoided whenever\n> it is possible.\n\nThe **Initializers** is an object that maps item names to correspondent item **Initializer**\n\n### Module Builder\n\n### Module Use Cases\n\n### Life Time Scope\n\n## API Reference\n","readmeFilename":"README.md","_id":"true-di@4.0.1","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-F6c0wtV27+FqxM9cb/hxHrDcdHS4lI/15jQXqyYu7IntdmNyo/zhuAvP2kg7EbJHefw6gfyzj2miJxXMrfYn3Q==","shasum":"e7388494df7f74c4ccf534a60c235418bcc6471c","tarball":"https://registry.npmjs.org/true-di/-/true-di-4.0.1.tgz","fileCount":170,"unpackedSize":135472,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEWLWaDwIHOkM4bww5S9EgpV4wws/zKtbYPCrqAUSi0XAiEA2FJGXXfcZDmSHqEkks6vKFDjE4VMEV2Ai0RXAmHTXPM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHuXJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrJNQ/+NcozJ/942nJvOA+ZT7W0MFRi5607UNyNk5bUq5IcRczv1Avb\r\noxpalNZ1RHZFpJ6Lt7pv7cf8LSgtj3uls8C49TvMvPWDdAl5vXiG0PATah25\r\nsLXpwok5W/CEbHlp0ZEfcf8XTtr0jxwvgvTq+pwLZpCHKEGime0aCgMt3+LG\r\ns2DYYax+VOsiXXPMMe9fXm7Gkgqr/3YJlrjVi2q/96Szm0+UX9YjNdxBTHEp\r\n96aouIqg5R3NqETlIUrv8iBSBtlsvR/MTZW3S5QTVkl2GJ68KUUXAHFjk1Ww\r\n/HYZpnvRWDCDAFuwol95+veDR5cqgLnDcTo4L8f5VDheWDpd/vxi/5VtUAJd\r\nCDAvFsjLbbBcnzThZk0UtnBKEupQQ52+UT1o1DkeMy5g5wjVyi7/5w5VTK87\r\njMFG2ncC9o31dt5cFXRdfeHWhZQ7oUhpGngTs6TIHzQh+HYazTqdGoMRGpQw\r\nX74kLCkQQ+zqh+21FVCLppgmDvBu93IouDKeh1+BnCtr1r0guoTdMrXptbzJ\r\nvSTWqD/Y8LgZsLAuAsZQaYMfOy0UeWjHu9aBgqJ0E/0RwatKuv+xQIW6hfNh\r\nrwioUqZhgf8eZ1tofmtXclpzTUGtXM0CBsMZCFedmC1HCPOS3Z4WEqyxuk4N\r\nCgjCE+s46HpFu4vU6CqLfeCSX9pwxMgXdnk=\r\n=k0r8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_4.0.1_1679746505447_0.24246358231109655"},"_hasShrinkwrap":false},"4.0.2":{"name":"true-di","version":"4.0.2","description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","main":"./lib/index.js","module":"./esm/index.js","types":"./lib/index.d.ts","sideEffects":false,"scripts":{"test":"jest","coveralls":"./.coveralls.sh","lint":"eslint ./src/**/*.ts","clear":"rm -rf ./lib; rm -rf ./esm","compile":"tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json","build":"npm run clear; npm run compile"},"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"homepage":"https://github.com/DScheglov/true-di#readme","devDependencies":{"@type-challenges/utils":"^0.1.1","@types/jest":"^28.1.2","@types/node":"^14.0.13","@typescript-eslint/eslint-plugin":"^5.28.0","@typescript-eslint/parser":"^5.28.0","coveralls":"^3.1.1","eslint":"^8.18.0","eslint-config-airbnb":"^19.0.4","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.5.3","jest":"^28.1.1","ts-jest":"^28.0.5","typescript":"^4.7.4"},"eslintConfig":{"extends":["airbnb/base"],"plugins":["@typescript-eslint","jest"],"parser":"@typescript-eslint/parser","rules":{"max-len":["error",{"code":100,"ignoreStrings":true}],"no-param-reassign":"off","implicit-arrow-linebreak":"off","import/no-unresolved":0,"import/prefer-default-export":0,"indent":[2,2,{"flatTernaryExpressions":true}],"no-unused-vars":"off","no-undef":"error","no-tabs":"error","no-nested-ternary":0,"import/extensions":0,"arrow-parens":["error","as-needed"],"operator-linebreak":0,"object-curly-newline":0,"no-underscore-dangle":0,"@typescript-eslint/no-unused-vars":["error"],"jest/no-disabled-tests":"warn","jest/no-focused-tests":"error","jest/no-identical-title":"error","jest/prefer-to-have-length":"warn","jest/valid-expect":"error"},"env":{"jest/globals":true},"ignorePatterns":["examples/**/*","lib/**/*","esm/**/*"]},"gitHead":"bedc56529cab809420cb624ac3007a364c8b57c5","readme":"# true-di\n\nZero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects\n\n[![Build Status](https://travis-ci.org/DScheglov/true-di.svg?branch=master)](https://travis-ci.org/DScheglov/true-di) [![Coverage Status](https://coveralls.io/repos/github/DScheglov/true-di/badge.svg?branch=master)](https://coveralls.io/github/DScheglov/true-di?branch=master) [![npm version](https://img.shields.io/npm/v/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![npm downloads](https://img.shields.io/npm/dm/true-di.svg?style=flat-square)](https://www.npmjs.com/package/true-di) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/DScheglov/true-di/blob/master/LICENSE)\n\n## Installation\n\n```bash\nnpm i --save true-di\n```\n\n```bash\nyarn add true-di\n```\n\n## Usage Example\n\nThe following code is an example solution that is based on the example used in the book [\"Dependency Injection Principles, Practices, and Patterns\"](https://www.manning.com/books/dependency-injection-principles-practices-patterns) by Steven van Deursen and Mark Seemann.\n\nThe problem is to display the list of featured products and discount their prices for the preferred customers.\n\nMore details on the example could be found in the \"Getting Started\" Example Project\n[README](./examples/getting-started/README.md) file.\n\n### ./src/main.ts - composition root\n\n```typescript\nimport Module from 'true-di';\nimport { DiscountService } from './DiscountService';\nimport { Product } from './domain/products';\nimport { ProductRepoMock } from './ProductRepoMock';\nimport { ProductService } from './ProductService';\nimport { UserService } from './UserService';\nimport PRODUCTS_JSON from './products.json';\n\nconst main = Module()\n  .private({\n    productRepo: () =>\n      new ProductRepoMock(PRODUCTS_JSON as Product[]),\n  })\n  .public({\n    userService: (_, { token }: { token: string | null }) =>\n      new UserService(token),\n  })\n  .private({\n    discountService: ({ userService }) =>\n      new DiscountService(userService),\n  })\n  .public({\n    productService: ({ productRepo, discountService }) =>\n      new ProductService(productRepo, discountService),\n  });\n\nexport default main;\n```\n\n### ./src/DiscountService/index.ts\n\n```typescript\nimport { IDiscountService, IUserProvider } from '../interfaces';\n\nexport const PREFERRED_CUSTOMER_DISCOUNT: number = 0.05;\nexport const NO_DISCOUNT: number = 0;\n\nexport class DiscountService implements IDiscountService {\n  constructor(\n    private readonly userService: IUserProvider,\n  ) {}\n\n  async getDiscountRate() {\n    const user = await this.userService.getCurrentUser();\n    return user != null && user.isPreferredCustomer\n      ? PREFERRED_CUSTOMER_DISCOUNT\n      : NO_DISCOUNT;\n  }\n}\n```\n\n### ./src/ProductRepoMock/index.ts\n\n```typescript\nimport { Product } from '../domain/products';\nimport { IProductRepo } from '../interfaces';\nimport { matches } from '../utils/matches';\n\nexport class ProductRepoMock implements IProductRepo {\n  constructor(private readonly products: Product[]) {}\n\n  async getProducts(match?: Partial<Product>): Promise<Product[]> {\n    return match != null ? this.products.filter(matches(match)) : this.products.slice();\n  }\n}\n```\n\n### ./src/UserService/index.ts\n\n```typescript\nimport { parseToken } from '../domain/user-token';\nimport { User } from '../domain/users';\nimport { IUserService } from '../interfaces';\n\nexport class UserService implements IUserService {\n  #user: User | null = null;\n\n  #token: string | null = null;\n\n  constructor(readonly token: string | null) {\n    this.#token = token;\n  }\n\n  async getCurrentUser(): Promise<User | null> {\n    if (this.#user == null && this.#token != null) {\n      this.#user = parseToken(this.#token);\n    }\n\n    return this.#user;\n  }\n}\n```\n\n### ./src/ProductService/index.ts\n\n```typescript\nimport { applyDiscount } from '../domain/products';\nimport {\n  IDiscountRateProvider,\n  IProductService,\n  IProductsProvider,\n} from '../interfaces';\n\nexport class ProductService implements IProductService {\n  constructor(\n    private readonly products: IProductsProvider,\n    private readonly discountService: IDiscountRateProvider,\n  ) {}\n\n  async getFeaturedProducts() {\n    const discountRate = await this.discountService.getDiscountRate();\n    const featuredProducts = await this.products.getProducts({ isFeatured: true });\n\n    return discountRate > 0\n      ? featuredProducts.map(applyDiscount(discountRate))\n      : featuredProducts;\n  }\n}\n```\n\n### ./src/products-controller.ts\n\n```typescript\nimport type { Request, Response } from 'express';\nimport { JSONMoneyReplacer } from './domain/money';\nimport { IFeaturedProductProvider } from './interfaces/IProductService';\n\ntype GetFeaturedProductsDeps = {\n  productService: IFeaturedProductProvider;\n}\n\nexport const getFeaturedProducts =\n  (req: Request, res: Response) =>\n    async ({ productService }: GetFeaturedProductsDeps) => {\n      const featuredProducts = await productService.getFeaturedProducts();\n\n      res\n        .status(200)\n        .type('application/json')\n        .send(JSON.stringify(featuredProducts, JSONMoneyReplacer, 2));\n    };\n\n```\n\n### ./src/index.ts\n\n```typescript\nimport express from 'express';\nimport createContext from 'express-async-context';\nimport main from './main';\nimport { getFeaturedProducts } from './products-controller';\n\nconst app = express();\n\nconst Context = createContext(\n  req => main.create({ token: req.headers.authorization ?? null }),\n);\n\napp.use(Context.provider);\n\napp.get('/featured-products', Context.consumer(getFeaturedProducts));\n\nif (module === require.main) {\n  app.listen(8080, () => {\n    console.log('Server is listening on port: 8080');\n    console.log('Follow: http://localhost:8080/featured-products');\n\n    console.log(`\n    . .env && curl -H \"authorization: \\${USER_TOKEN}\" http://localhost:8080/featured-products\n    `);\n  });\n}\n\nexport default app;\n```\n\n## Some Concepts\n\n### Module\n\nIn the context of `true-di`, a **Module** is a collection of named and typed\nitems that can communicate with each other. These items can be either\n**private**,meaning they are only accessible within the **Module**, or\n**public**, which allows them to be accessed both inside and outside of the\n**Module**.\n\nEssentially, a **Module** can be thought of as an instance of a class, with\nprivate and public fields. However, in `true-di`, none of the items within the\n**Module** are created until they are requested from outside of the module,\nincluding the function provided to the `.expose` method of the **ModuleBuilder**.\n\nThe **Module** could be created by invoking the **Module Factory** function.\n\n### Module Factory\n\nThe **Module Factory** is a function that takes an object called **external dependencies**\nas input and uses it to create a **Module**. Later on, when an item within the\n**Module** is requested, the corresponding **Resolver** will receive the\n**external dependencies** as input to resolve the item.\n\nIn `true-di`, the **Module Factory** is essentially a composition of Resolvers\nthat have been defined for each item within the module. This means that the code\ndefining the Module Factory serves as the Composition Root, where all loosely\ncoupled components such as classes and functions are brought together and\nassembled in a cohesive manner.\n\n### Resolver & Resolution Rule\n\nThe **Resolver** is an item factory, that receives two parameters:\n\n- **internal dependencies** - an object containing all Module items (excluding\nthe creating one)\n- **external dependencies** - an object passed to the **Module Factory**\n\n**Resolver** is an implementation of the **Resolution Rule**, the rule defines how\nto create a specific item using other items of **Module** and **external dependencies**.\n\nUnlike some other dependency injection solutions, `true-di` does not rely on interfaces\nor type names to define how to create an item. Instead, it uses explicit item\nnames and **Resolvers** defined for each name. This approach avoids the need for\nadditional abstractions in cases where a single interface is implemented by\nseveral different components (classes).\n\nAlso it allows to use `true-di` with JS-projects those don't have any interfaces\nor type names nor in build time, nor in runtime.\n\n### Initializers\n\n**Initializer** - is a function associated with a some item of **Module** that receives\ntwo arguments:\n\n- the **item** to be initialized\n- the **internal dependencies** object with all items of the **Module**\n\nAnd initializes the **item**.\n\nThe **Initializer** is an implement of the \"Injection via property\" pattern\nthat is useful to resolve cyclic dependencies.\n\n> **Note**: The Cyclic Dependencies is an anti-pattern and should be avoided whenever\n> it is possible.\n\nThe **Initializers** is an object that maps item names to correspondent item **Initializer**\n\n### Module Builder\n\n### Module Use Cases\n\n### Life Time Scope\n\n## API Reference\n","readmeFilename":"README.md","_id":"true-di@4.0.2","_nodeVersion":"16.19.1","_npmVersion":"8.19.3","dist":{"integrity":"sha512-vvG0Icv8XkM+MvHDU85Wdjby7ER1KZNGueF80mnHmimLOhXvKCy3wrcxce5aRxd5mqDP/tcbBeS34nbFa/RhKQ==","shasum":"cf9d777a52005f8eef5d31542e7c936b676d7342","tarball":"https://registry.npmjs.org/true-di/-/true-di-4.0.2.tgz","fileCount":175,"unpackedSize":139498,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG/7DsSRqfo4UQNuR6ncfNK+BMbpuWUKFbB01A9Gx6X3AiBp5H0UnQyNc3fkF5w3/qIleTmutwXS3Wjw1QHynsabhg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHy20ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpcYhAApPzckqQiESQonzvusNslfKeT3+w35UpiwYwa/4ad1U7NHPfr\r\nxSwTAWj8VxtZOHTz6K2cxI0sOld/4/V/8ptZuobjbAfLPrEVDn0qRrXSNveA\r\n2M/nobBEu9oaIaMTb4fAMCmLDKRa9glZRmwBBFg41Y/cBdK0qeZIugoZwr3n\r\npBQmK5soe0JpC1pScK68IJPgf5pD4QPNBnkj4TiUi/Jlide8/vPL2Y7daynw\r\nsagIwv8uxlfdsWTlJQb2ngPBg4aEL0AlUfIjYHAd1tG4nUJB+33q9ymJFa5Z\r\nGnOV885+QtbewRu7MsCjCwwZ7zBY1/J968TbbvYcutpuYVnegUGWGXDWpWlD\r\nAqDSGKq17tCQdakl/uOS+HjxO3qE7Og5Ah7tNKuVQaHqPELLLEt6iFjC0sX7\r\nDjyc3p152TGPj5a/sODiY6Sn7n2t7ipOdQFqXsIf0AhlxdcgV175uq81qCqz\r\nnig883VYimap0EmX8omMIHvH+3neWBUpuJ1ApEtrOScXSvui1cVC4GKSIMM1\r\njbCmTnmT5GdVwHQ74Njx9KbaS+VGswMZxMR1vV1k2yqiVRIs0aAmVD4Ez2z3\r\ncTHeWpOpHrKiKwAG/Ez9aaH5/SZ04IGDYqVbmQbL1ndPE5Sti974LZpWLAGB\r\nhINQ9CO5Qha0apyDajeExgpRQOCl527h+xM=\r\n=SkXI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"},"directories":{},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/true-di_4.0.2_1679764916308_0.3784079350671252"},"_hasShrinkwrap":false}},"time":{"created":"2020-06-26T16:34:03.314Z","0.0.1":"2020-06-26T16:34:03.548Z","modified":"2023-03-25T17:21:56.605Z","1.0.0":"2020-06-26T16:39:59.704Z","1.0.1":"2020-06-26T16:56:47.798Z","1.0.2":"2020-06-26T17:09:00.570Z","2.0.0":"2020-08-16T20:31:05.886Z","2.0.1":"2020-08-26T09:37:41.815Z","2.0.2":"2020-09-06T08:14:22.155Z","2.1.0":"2020-09-22T06:53:49.366Z","2.1.1":"2020-09-22T07:05:23.150Z","2.1.2":"2020-09-22T16:29:26.656Z","2.2.0-betta.0":"2020-11-21T20:48:53.642Z","2.2.1-betta.0":"2020-12-21T09:08:22.454Z","2.1.3":"2020-12-21T09:08:40.438Z","2.1.4":"2020-12-21T09:16:51.204Z","2.1.5":"2021-01-14T09:08:03.797Z","2.2.2-betta.0":"2021-01-14T09:17:26.779Z","2.1.6":"2021-04-08T22:15:16.633Z","2.1.7":"2021-04-12T11:45:14.086Z","3.0.0":"2022-09-10T16:46:08.035Z","4.0.0":"2023-03-25T11:17:06.198Z","4.0.1":"2023-03-25T12:15:05.684Z","4.0.2":"2023-03-25T17:21:56.501Z"},"maintainers":[{"name":"dmitry.scheglov","email":"dmitry.scheglov@gmail.com"}],"description":"Zero Dependency, Minimalistic **Type-Safe DI Container** for TypeScript and JavaScript projects","homepage":"https://github.com/DScheglov/true-di#readme","keywords":["Dependency","Injection","Inject","Dependency","di","container","service","instance"],"repository":{"type":"git","url":"git+https://github.com/DScheglov/true-di.git"},"author":{"name":"Dmitry Scheglov","email":"dmitry.scheglov@gmail.com"},"bugs":{"url":"https://github.com/DScheglov/true-di/issues"},"license":"MIT","readme":"","readmeFilename":""}