[
  {
    "path": ".dockerignore",
    "content": "node_modules\ndist\nproject-cli\ndocumentation\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\nindent_style = tab\nindent_size = 4\n\n[package.json]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n\tparser: '@typescript-eslint/parser',\n\textends: [\n\t\t'plugin:@typescript-eslint/recommended',\n\t\t'prettier/@typescript-eslint',\n\t\t'plugin:prettier/recommended',\n\t],\n\tparserOptions: {\n\t\tecmaVersion: 2018,\n\t\tsourceType: 'module',\n\t\tproject: './tsconfig.json',\n\t},\n\trules: {\n\t\t// Disabled Rules\n\t\t'@typescript-eslint/camelcase': ['error', { properties: 'never' }],\n\t\t'@typescript-eslint/explicit-function-return-type': 'off',\n\t\t'@typescript-eslint/explicit-member-accessibility': 'off',\n\t\t'@typescript-eslint/interface-name-prefix': 'off',\n\t\t'@typescript-eslint/no-empty-interface': 'off',\n\t\t'@typescript-eslint/no-var-requires': 'off',\n\t\t'@typescript-eslint/no-object-literal-type-assertion': 'off',\n\t\t'@typescript-eslint/no-inferrable-types': 'off',\n\t\t'@typescript-eslint/no-magic-numbers': 'off',\n\t\t'@typescript-eslint/no-namespace': 'off',\n\t\t'@typescript-eslint/no-non-null-assertion': 'off',\n\t\t'@typescript-eslint/no-type-alias': 'off',\n\t\t'@typescript-eslint/no-require-imports': 'off',\n\t\t'@typescript-eslint/no-object-literal-type-assertion': 'off',\n\t\t'@typescript-eslint/prefer-interface': 'off',\n\t\t// Enabled rules\n\t\t'@typescript-eslint/adjacent-overload-signatures': 'error',\n\t\t'@typescript-eslint/array-type': 'error',\n\t\t'@typescript-eslint/await-thenable': 'error',\n\t\t'@typescript-eslint/class-name-casing': 'error',\n\t\t'@typescript-eslint/member-ordering': 'error',\n\t\t'@typescript-eslint/no-explicit-any': 'error',\n\t\t'@typescript-eslint/no-triple-slash-reference': 'error',\n\t\t'@typescript-eslint/no-unnecessary-type-assertion': 'error',\n\t\t'@typescript-eslint/no-unused-vars': 'error',\n\t\t'@typescript-eslint/no-unnecessary-qualifier': 'error',\n\t\t'@typescript-eslint/no-parameter-properties': 'error',\n\t\t'@typescript-eslint/no-misused-new': 'error',\n\t\t'@typescript-eslint/no-for-in-array': 'error',\n\t\t'@typescript-eslint/no-angle-bracket-type-assertion': 'error',\n\t\t'@typescript-eslint/no-var-requires': 'error',\n\t\t'@typescript-eslint/prefer-function-type': 'error',\n\t\t'@typescript-eslint/promise-function-async': 'error',\n\t\t'@typescript-eslint/restrict-plus-operands': 'error',\n\t\t'@typescript-eslint/semi': 'error',\n\t\t'@typescript-eslint/type-annotation-spacing': 'error',\n\t\t'@typescript-eslint/unified-signatures': 'error',\n\t\tcomplexity: ['error', { max: 3 }],\n\t\t'max-depth': ['error', { max: 4 }],\n\t\t'prefer-const': [\n\t\t\t'error',\n\t\t\t{\n\t\t\t\tdestructuring: 'all',\n\t\t\t\tignoreReadBeforeAssign: true,\n\t\t\t},\n\t\t],\n\t},\n};\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# history\n.history\n\n# sqlite\ndb.sqlite\n\n# macos\n.DS_Store\n\n# builds\n/project-cli/dist\ndist/\n/documentation/website/build\n\n# webstorm\n.idea/\n*.iml\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n\t\"semi\": true,\n\t\"trailingComma\": \"all\",\n\t\"singleQuote\": true,\n\t\"printWidth\": 100,\n\t\"tabWidth\": 4,\n\t\"useTabs\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"10\"\ninstall:\n  - npm ci\nscript:\n  - npm run lint\n  - npm run test\nbefore_script:\n  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter\n  - chmod +x ./cc-test-reporter\n  - ./cc-test-reporter before-build\nafter_success:\n  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:10-alpine\n\nRUN mkdir /app\nWORKDIR /app\n\nCOPY package*.json ./\n\nRUN npm ci \n\nCOPY . .\n\nRUN npm run build && npm prune --production\n\nENV NODE_ENV=production\nCMD [\"npm\", \"start\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Pankod\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<img src=\"moleculerjs-cover.png\" alt=\"Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Clients, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects.\" align=\"center\" />\n\n<br/>\n<div align=\"center\" >Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Helpers, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects..\n</div>\n<br/>\n\n<div align=\"center\">\n  <!-- CodeClimate -->\n  <a href=\"https://codeclimate.com/github/pankod/moleculerjs-boilerplate/maintainability\">\n    <img src=\"https://api.codeclimate.com/v1/badges/077c02d5cb9ec7d8a654/maintainability\" />\n  </a>\n  <!-- CodeCoverave -->\n  <a href=\"https://codeclimate.com/github/pankod/moleculerjs-boilerplate/test_coverage\"><img src=\"https://api.codeclimate.com/v1/badges/077c02d5cb9ec7d8a654/test_coverage\" /></a>\n  <!-- Build Status -->\n  <a href=\"https://travis-ci.org/pankod/moleculerjs-boilerplate\">\n    <img src=\"https://travis-ci.org/pankod/moleculerjs-boilerplate.svg?branch=master\" alt=\"Build Status\" />\n  </a>\n  <!-- Dependency Status -->\n  <a href=\"https://david-dm.org/pankod/moleculerjs-boilerplate\">\n    <img src=\"https://david-dm.org/pankod/moleculerjs-boilerplate.svg\" alt=\"Dependency Status\" />\n  </a>\n  <!-- devDependency Status -->\n  <a href=\"https://david-dm.org/pankod/moleculerjs-boilerplate#info=devDependencies\"> \n    <img src=\"https://david-dm.org/pankod/moleculerjs-boilerplate/dev-status.svg\" alt=\"devDependency Status\" />\n  </a>\n</div>\n\n<br/>\n<div align=\"center\">\n  <sub>Created by <a href=\"https://www.pankod.com\">Pankod</a></sub>\n</div>\n\n\n\n## About\n\nA microservice is a single self-contained unit which, together with many others, makes up a large application. By splitting your app into small units every part of it is independently deployable and scalable, can be written by different teams and in different programming languages and can be tested individually.\n\nMoleculer is a fast, modern and powerful microservices framework for Node.js. It helps you to build efficient, reliable & scalable services.\n\nThis boilerplate make it easier to get started with a well-structured Node.js microservices with Typescript.\n\n<br/>\n\n## Features\n\n\nThis boilerplate includes the latest powerfull tools.\n\n* **Moleculer** - Moleculer is a fast, modern and powerful microservices framework for Node.js.\n* **Typescript** - Superset of JavaScript which primarily provides optional static typing, classes and interfaces. path support(allias)\n* **Built-in Project CLI**- Create services, entities, interfaces, and tests with one command by using built-in cli.\n* **Docker** - A tool designed to make it easier to create, deploy, and run applications by using containers.\n* **Eslint** - The pluggable linting utility.\n* **Swagger** - A framework backed by a large ecosystem of tools that helps developers design, build, document, and consume RESTful Web services.\n* **Jest** - Javascript testing framework , created by developers who created react\n* **TypeORM** - TypeORM is specifically an ORM that converts data between JavaScript / TypeScript to a variety of databases.\n* **Service Helpers** - Provides easy communication contract between services.\n<br/>\n\n\n## Setup & Documentation\n\nPlease refer to our [setup guide](https://pankod.github.io/moleculerjs-boilerplate/docs/setup) to create a new app. \n\n\nFor more detailed documentation, check out https://pankod.github.io/moleculerjs-boilerplate/\n\n<br/>\n\n## Built-in CLI\n\n\n<div>\n <img width=\"600\" src=\"./cli.gif\" >\n</div>\n<br/>\n<br/>\n\nmoleculerjs-boilerplate is shipped with a CLI tool to streamline the creation of new microservices. By using the CLI tool, you may easily add entities, services to your project and have all the required interfaces and imports are automatically created for you.\n<br />\n\nTo start the CLI, you may run the following npm command:\n\n```\nnpm run cli\n```\n\n\nAfter answering questions it generates files in miliseconds.\n\n<br/>\n\n \n## License\n\nLicensed under the MIT License, Copyright © 2019-present Pankod\n"
  },
  {
    "path": "docker-compose.env",
    "content": "NAMESPACE=\nLOGGER=true\nLOGLEVEL=info\nSERVICEDIR=dist/services\n\nTRANSPORTER=nats://nats-server:4222\n\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: \"3.0\"\n\nservices:\n\n  api:\n    build: .\n    image: api\n    env_file: docker-compose.env\n    environment:\n      SERVICES: api\n      PORT: 3000\n    ports:\n      - \"3000:3000\"\n\n  attack:\n    build: .\n    image: attack\n    env_file: docker-compose.env\n    environment:\n      SERVICES: attack\n\n  planet:\n    build: .\n    image: planet\n    env_file: docker-compose.env\n    environment:\n      SERVICES: planet\n\n  nats-server:\n    image: nats:latest\n    ports:\n      - \"4222:4222\"\n"
  },
  {
    "path": "documentation/Dockerfile",
    "content": "FROM node:8.11.4\n\nWORKDIR /app/website\n\nEXPOSE 3000 35729\nCOPY ./docs /app/docs\nCOPY ./website /app/website\nRUN yarn install\n\nCMD [\"yarn\", \"start\"]\n"
  },
  {
    "path": "documentation/README.md",
    "content": "<img src=\"https://github.com/pankod/docusaurus-boilerplate/blob/master/demo.png\" alt=\"Pankod - docusaurus-boilerplate\" align=\"center\" />\n\nThis website was created with [Docusaurus](https://docusaurus.io/).\n\n# What's In This Document\n\n* [Get Started in 5 Minutes](#get-started-in-5-minutes)\n\n# Get Started in 5 Minutes\n\n1. Go to the website folder:\n\n```sh\n# Go to the folder\n$ cd website\n```\n\n2. Make sure all the dependencies for the website are installed:\n\n```sh\n# Install dependencies\n$ npm i\n```\n\n3. Run your dev server:\n\n```sh\n# Start the site\n$ npm start\n```\n"
  },
  {
    "path": "documentation/docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  docusaurus:\n    build: .\n    ports:\n      - 3000:3000\n      - 35729:35729\n    volumes:\n      - ./docs:/app/docs\n      - ./website/blog:/app/website/blog\n      - ./website/core:/app/website/core\n      - ./website/i18n:/app/website/i18n\n      - ./website/pages:/app/website/pages\n      - ./website/static:/app/website/static\n      - ./website/sidebars.json:/app/website/sidebars.json\n      - ./website/siteConfig.js:/app/website/siteConfig.js\n    working_dir: /app/website\n"
  },
  {
    "path": "documentation/docs/cli-migration-guide.md",
    "content": "---\nid: cli-migration-guide\ntitle: CLI Migrate Guide\nsidebar_label: Migration Guide\n---\n\nInitially, moleculer's `project-cli` was inside the boilerplate repository. This makes it hard to upgrade cli version for users. We decided to move project cli to it's own package. \n\nThis guide will walk you through migrating to new cli.\n\nIf you have `@pankod/pankod-cli` in your devDependencies, you can skip this guide.\n\n- Remove `project-cli` folder completely. (`rm -rf project-cli`)\n- npm install -D @pankod/pankod-cli\n\n- Add this to your package.json;\n\n```\n\"pankod\": {\n  \"projectType\": \"moleculer\"\n},\n```\n- Update your `cli` script in `package.json`;\n\n```\n\"cli\": \"pankod-cli add\",\n```\n\nThat's it! Now you should be able to use new cli, add Entity or Service.\n"
  },
  {
    "path": "documentation/docs/cli-overview.md",
    "content": "---\nid: cli-overview\ntitle: Overview\nsidebar_label: Overview\n---\n\n\n<div>\n <img width=\"600\" src=\"assets/cli.gif\" >\n</div>\n<br/>\n<br/>\n\n\nmoleculerjs-boilerplate is shipped with a CLI tool to streamline the creation of new microservices. By using the CLI tool, you may easily add entities, services, tests to your project and have all the required interfaces and imports are automatically created for you.\n<br />\n\nTo start the CLI, you may run the following npm command:\n\n```sh\nnpm run cli\n```\n\nAfter answering the questions, it will generate files in miliseconds.\n"
  },
  {
    "path": "documentation/docs/cli-usage.md",
    "content": "---\nid: cli-usage\ntitle: Usage\nsidebar_label: Usage\n---\n\n\nAfter starting, an interactive menu will let you file to be created. Firstly, you'll be asked for the type of the files whether it's a entity or service. Then you'll be prompted with the other options relevant to your selection.\n\nFor example, let's go through the steps of the creation of a service.\n\n>Enter service name\n\n - Enter the desired filename for the service. Spaces are not allowed!\n - The tool will check for the existing filenames in the project and reject if found any.\n\n>Is service open to outside?\n\n- If you choose yes, cli adds swagger tags to service file. \n\n>Are you going to have a database?\n - If yes, it adds `connectionInstance` method and import to service file.\n\n\nAfter answering questions it generates files and set imports which specified at the below.\n\n - Creates new service with given name into services directory.\n - Adds service export into ``services/index.ts`` file.\n - Creates a new interface file in `src/Interfaces/Services` directory.\n - Create index.ts file into service interface folder.\n - Adds file exports into `src/Interfaces/index.ts` file.\n - Adds service import in `test/Utils/BrokerHelper.ts` file.\n - Adds service into setupBroker method in `test/Utils/BrokerHelper.ts` file.\n - Create service helper into `src/ServiceHelper` directory.\n - Adds service into index in `src/ServiceHelper/index.ts` file.\n - Create service helper test into `test/Unit/ServiceHelper` directory.\n - Create service test into `test/Unit/MicroService` directory.\n - Create integration test into `test/Integration` directory.\n "
  },
  {
    "path": "documentation/docs/deployment.md",
    "content": "---\nid: deployment\ntitle: Deployment\nsidebar_label: Deployment\n---\n\n## Build\n\nBuilds the app for production into the dist folder.\n```sh\nnpm run build\n```\n\nOnce you built the app, you can run microservices with;\n\n```sh\nnpm run start\n```\n\n## Docker\n\nIf you want to run the app with Docker, we already included `docker-compose.yaml`, `docker-compose.env` files and scripts to start and stop Docker deployment.\n\nTo start;\n```js\nnpm run dc:up\n```\n\nTo stop;\n```js\nnpm run dc:down\n```\n<br>\n> We are using `NATS` for communication between microservices in Docker deployment.\n\n<br>\n\n*docker-compose.yaml*\n```\nversion: \"3.0\"\n\nservices:\n\n  api:\n    build: .\n    image: api\n    env_file: docker-compose.env\n    environment:\n      SERVICES: api\n      PORT: 3000\n    ports:\n      - \"3000:3000\"\n\n  attack:\n    build: .\n    image: attack\n    env_file: docker-compose.env\n    environment:\n      SERVICES: attack\n\n  planet:\n    build: .\n    image: planet\n    env_file: docker-compose.env\n    environment:\n      SERVICES: planet\n\n  nats-server:\n    image: nats:latest\n    ports:\n      - \"4222:4222\"\n```\n\nRefer to moleculer deployment documentation;\n\n https://moleculer.services/docs/0.13/deploying.html\n"
  },
  {
    "path": "documentation/docs/eslint.md",
    "content": "---\nid: eslint\ntitle: Usage\nsidebar_label: ESLint\n---\n\nESLint integrated to boilerplate for linting.\n\nLints with Eslint. Useful for CI.\n```SH\nnpm run lint \n```\n\nLints and fixes fixable problems.\n \n```SH\nnpm run format \n```\n\n>Refer to [offical documentation](https://eslint.org/) for detailed usage.\n"
  },
  {
    "path": "documentation/docs/example.md",
    "content": "---\nid: example-app\ntitle: Example App\nsidebar_label: Example App\n---\n<br>\n<img src=\"assets/alderaan.png\" align=\"center\" />\n\n>>>*\"The defense systems on Alderaan, despite the Senator's protestations to the contrary, were as strong as any in the Empire. I should conclude that our demonstration was as impressive as it was thorough.\"*\n―Darth Vader\n\n\nWe've integrated microservice example to show how services connect together. The aim of this example is to demonstrate how two different services communicate with each other.\n\nRunning `npm run setup-db` will seed the database and create a planet and a weapon. Planet's name is `Alderaan`, weapon's name is `Death Star`.\nAccording to the story, Death Star will try to destroy Alderaan;\n\n- **Death Star**: A weapon to destroy planets.\n\n- **Alderaan**: A planet far far away.\n\nTODO: Death Star is a planet destroyer weapon. It destroyed Alderaan.\n\n## Overview\n\nWe have 2 services as seen below;\n\n - Attack service with **Fire Action** (**api/attack/Fire**)\n\t\n\tDeath Star will use this service to attack another planet.\n \n - Planet service with **Defend Action** (**api/planet/Defend**)\n\n\tAlderaan will use this service to defend itself.\n\nTo get more information about **Actions**, visit [Moleculer Documentation](https://moleculer.services/docs/0.13/actions.html)\n\n## Entities:\n\n### Planet\n```js\n{\n\tname: 'Alderaan',\n\tshield: 100000\n}\n```\n\n### Weapon\n```js\n{\n\tname: 'Death Star',\n\tdamage: 1000,\n\tammo: 1000\n}\n```\n\nTo get more information about `Entities`, visit [TypeOrm Documentation](https://typeorm.io/#/entities)\n\n## Services\n\nBoth services has a structure as seen below. We can make API request to these services;\n\nLet's fire!\n\n### Attack Service\n\nAttack service will get weapon and planet names as parameters. Then it will use this information to make request to Planet service to find out how much damage is done and how much shield planet has left. \nYou can see example of calling a service from another service below, in **Communication between services** section.\n\nSee example attack request;\n\n```sh\nPOST http://localhost:3000/api/attack/Fire\n\nParams: {\n\t\"weaponName\":\"Death Star\",\n\t\"planetName\": \"Alderaan\"\n}\n\nResponse: {\n    \"planetMessage\": \"Planet took 474 damage and has 99404 shield left.\",\n    \"weaponMessage\": \"Death Star did 474 damage and left 999 ammo.\"\n}\n```\n\nThen this service will decrease ammo of the given weapon and return messages about what damage is done and how much ammo left.\nYou can see how we decrease the ammo of the weapon below, in **Repositories** section.\n\n### Planet Service:\n\nPlanet service will get weapon and planet name as parameters. Then, using **CalculateMeta** helper function, will calculate how much damage will be done.\nAfter getting the damage, service will decrease given planet's shield and return informing message about planet and how much damage is done.\n\n```sh\nPOST http://localhost:3000/api/planet/Defend\n\nParams: {\n    \"weaponName\": \"Death Star\",\n\t\"planetName\": \"Alderaan\"\n}\n\nResponse: {\n    \"damage\": 122,\n    \"planetMessage\": \"Planet took 122 damage and has 99878 shield left.\"\n}\n\n```\n\nTo get more information about `Moleculer Services`, please visit [Moleculer Documentation](https://moleculer.services/docs/0.13/services.html)\n\n## Repositories\n\nIn order to interact with the database, we are using **Repository** pattern. Every **Entity** has a corresponding **Repository**.\n\nFor example, in order to fetch **Death Star Weapon** from the database, and make it ready to fire, we should;\n```\nconst deathStar = WeaponRepository.Get('Death Star')\n```\n\nWhen a weapon fires, it loses 1 ammo. We should update the database properly by using repository.\n\n```js\nconst { remainingAmmo } = await WeaponRepository.DecreaseAmmo('Death Star');\n```\n\nIf you want to update the shield of the planet;\n\n```ts\nconst { remainingShield } = await PlanetRepository.UpdateShield('Alderaan', 5000);\n```\n\n\nTo get more information about **Repository Pattern** please [visit here](https://deviq.com/repository-pattern/)\n\n## Communication between services\n\nIn MoleculerJS we are calling other services with a simple string parameter where service name and method separated by dot.\nThis is not useful. Since we don't have autocomplete, we need to remember every service and action name to call them.\n\n```\nconst params = {...}\n\nctx.call(\"planet.Defend\", params)\n```\n\nAs the codebase goes bigger, it becomes harder and harder to remember every single service name and their actions.\nTo fix this, we introduced **ServiceHelpers** to call services. Every service has a helper;\n```\nexport namespace AttackHelper {\n\tconst prefix: string = 'attack';\n\n\texport const Fire = async (ctx: Context, params: IAttack.AttackInDto): Promise<IAttack.AttackOutDto> =>\n\t\tawait ctx.call(`${prefix}.Fire`, params);\n}\n\n```\n\nThen we can use it in other services;\n```\nAttackHelper.Fire(ctx, {...params})\n```\n\nIf we want to call `planet` service's `Defend` action inside `Attack` service, it's straightforward;\n\n```\nconst { damage, planetMessage } = await PlanetHelper.Defend(ctx, { weaponName, planetName });\n```\n\nAs you can see above, it's just invoking a function and getting variables back.\n"
  },
  {
    "path": "documentation/docs/features.md",
    "content": "---\nid: features\ntitle: What's included?\n---\n\n\nmoleculerjs-boilerplate project provides a lot of features out of the box. Below is an overview of the included technologies.\n\n* **Moleculer** - Moleculer is a fast, modern and powerful microservices framework for Node.js.\n* **Typescript** - Superset of JavaScript which primarily provides optional static typing, classes and interfaces. path support(allias)\n* **Built-in Project CLI**- Create service, model, interface and unit-test with one command by using built-in cli.\n* **Docker** - A tool designed to make it easier to create, deploy, and run applications by using containers.\n* **Eslint** - The pluggable linting utility.\n* **Swagger** - A framework backed by a large ecosystem of tools that helps developers design, build, document, and consume RESTful Web services.\n* **Jest** - Javascript testing framework , created by developers who created react\n* **TypeORM** - TypeORM is specifically an ORM that converts data between JavaScript / TypeScript to a variety of databases.\n* **Service Helpers** - Better way to consume services.\n* **Seeder** - Easy to integrate, well structured seeder for tests.\n\n"
  },
  {
    "path": "documentation/docs/getting-started.md",
    "content": "---\nid: getting-started\ntitle: Getting Started\nsidebar_label: Getting Started\n---\n\n## About Moleculer\n\nMoleculer is a fast, modern and powerful microservices framework for Node.js. It helps you to build efficient, reliable & scalable services. Moleculer provides many features for building and managing your microservices.\n\n\n### Features of Moleculer\n- Promise-based solution (async/await compatible)\n- request-reply concept\n- support streams\n- support event-driven architecture with balancing\n- built-in service registry & dynamic service discovery\n- load balanced requests & events (round-robin, random, cpu-usage, latency)\n- many fault tolerance features (Circuit Breaker, Bulkhead, Retry, Timeout, Fallback)\n- supports middlewares\n- supports versioned services\n- service mixins\n- built-in caching solution (memory, Redis)\n- pluggable transporters (TCP, NATS, MQTT, Redis, NATS Streaming, Kafka)\n- pluggable serializers (JSON, Avro, MsgPack, Protocol Buffers, Thrift)\n- pluggable validator\n- multiple services on a node/server\n- all nodes are equal, no master/leader node\n- parameter validation with fastest-validator\n- built-in health monitoring & metrics\n- official API gateway module and many other modules…\n\n<br>\n\nThis boilerplate make it easier to get started with a well-structured Moleculer Microservice.\n\nFor more information about [Moleculer](https://moleculer.services) \n\n\n"
  },
  {
    "path": "documentation/docs/setup.md",
    "content": "---\nid: setup\ntitle: Setup\n---\nTo create a new app, you may choose one of the following methods:\n#### Clone the repository:\n\n```sh\ngit clone https://github.com/pankod/moleculerjs-boilerplate.git\n```\n\n\n#### Install the dependencies:\n\n\n```sh\nnpm install\n```\n\n#### Setup Database (Optional):\n\nWe've integrated a microservice example to show how services connect together. We have an example database; you can copy this to play with services.\n\n```sh\nnpm run setup-db\n```\n\n#### Running Microservices:\n\n ```sh\n npm run dev\n ```\n\nThis command will build and run services in the `services` directory. Also it will generate documentation and start swagger UI at port 3001.\n\n#### Running with Docker\n\n```sh\nnpm run dc:up\n```\n\nThis should start services independently at port 3000.\n"
  },
  {
    "path": "documentation/docs/structure.md",
    "content": "---\nid: structure\ntitle: Structure\nsidebar_label: Structure\n---\n\nAfter the setup is complete, your app should have the following directory structure:\n\n```js\n.\n├── public\n│   ├── banner.png\n│   ├── favicon.ico\n│   └── index.html\n├── services\n│   ├── api.service.ts\n│   ├── attack.service.ts\n│   ├── index.ts\n│   └── planet.service.ts\n├── src\n│   ├── Entities\n│   │   ├── Connection.ts\n│   │   ├── Planet.ts\n│   │   ├── Weapon.ts\n│   │   └── index.ts\n│   ├── Interfaces\n│   │   ├── Meta\n│   │   │   ├── DamageMetaOutDto.d.ts\n│   │   │   └── index.ts\n│   │   ├── Repositories\n│   │   │   ├── Planet\n│   │   │   │   ├── DecreaseShieldOutDto.d.ts\n│   │   │   │   └── index.ts\n│   │   │   └── Weapon\n│   │   │       ├── DecreaseAmmoOutDto.d.ts\n│   │   │       └── index.ts\n│   │   ├── Services\n│   │   │   ├── Attack\n│   │   │   │   ├── IAttack.d.ts\n│   │   │   │   └── index.ts\n│   │   │   └── Planet\n│   │   │       ├── IPlanet.d.ts\n│   │   │       └── index.ts\n│   │   └── index.ts\n│   ├── Meta\n│   │   ├── CalculateMeta.ts\n│   │   └── index.ts\n│   ├── Repositories\n│   │   ├── ErrorHelpers.ts\n│   │   ├── Planet.ts\n│   │   ├── Shared.ts\n│   │   ├── Weapon.ts\n│   │   └── index.ts\n│   └── ServiceHelpers\n│       ├── AttackHelper.ts\n│       ├── PlanetHelper.ts\n│       └── index.ts\n├── swagger\n│   ├── config.js\n│   ├── index.js\n│   ├── package.json\n│   └── swagger.json\n├── test\n│   ├── Config\n│   │   ├── Connection.ts\n│   │   ├── SetupDatabase.ts\n│   │   └── mock.setup.ts\n│   ├── Integration\n│   │   ├── attack.spec.ts\n│   │   └── planet.spec.ts\n│   ├── Seeder\n│   │   ├── AttackSeeder.ts\n│   │   ├── PlanetSeeder.ts\n│   │   └── index.ts\n│   ├── Unit\n│   │   ├── Helper\n│   │   │   ├── AttackHelper.spec.ts\n│   │   │   └── PlanetHelper.spec.ts\n│   │   ├── Meta\n│   │   │   └── CalculateMeta.spec.ts\n│   │   ├── MicroServices\n│   │   │   ├── attack.spec.ts\n│   │   │   └── planet.spec.ts\n│   │   └── Repositories\n│   │       ├── ErrorHelpers.spec.ts\n│   │       ├── Planet.spec.ts\n│   │       └── Weapon.spec.ts\n│   └── Utils\n│       ├── BrokerHelper.ts\n│       ├── DummyContext.ts\n│       └── index.ts\n├── Dockerfile\n├── LICENSE\n├── README.md\n├── banner.png\n├── cli.gif\n├── db.sqlite\n├── db.sqlite.example\n├── docker-compose.env\n├── docker-compose.yml\n├── moleculer.config.ts\n├── moleculerjs-cover.png\n├── package-lock.json\n├── package.json\n├── swaggerConfig.json\n├── tsconfig.json\n└── tsconfig.production.json\n```\n"
  },
  {
    "path": "documentation/docs/swagger.md",
    "content": "---\nid: swagger\ntitle: Usage\nsidebar_label: Swagger\n---\n\n`swagger-jsdoc` is a library which returns the validated OpenAPI specification as JSON or YAML.\n\n`moleculerjs-boilerplate` uses `swagger-jsdoc` for generating swagger.json file.\n\nThis code block shows swagger-jsdoc in **services/attack.service** of example app.\n\n````\n\t/**\n\t* @swagger\n\t*\n\t*  attack/Fire:\n\t*    post:\n\t*      description: Attacks to the planet with given weapon.\n\t*      produces:\n\t*        - application/json\n\t*      consumes:\n\t*        - application/json\n\t*      parameters:\n\t*        - in: body\n\t*          name: params\n\t*          schema:\n\t*            type: object\n\t*            required:\n\t*              - weaponName\n\t*              - planetName\n\t*            properties:\n\t*              weaponName:\n\t*                type: string\n\t*                default: Death Star\n\t*              planetName:\n\t*                type: string\n\t*      responses:\n\t*        200:\n\t*          description: Example attack result\n\t*        422:\n\t*          description: Missing parameters\n\t*/\n````\n<br>\n\nAfter running the service you will see the example API documentation on localhost:3001 which is shown at the below.\n\n<br>\n<img src=\"assets/swagger.png\" align=\"center\" />\n<br>\n\n>Refer to [offical documentation](https://swagger.io/docs/specification/2-0/basic-structure/) for detailed usage. \n\n"
  },
  {
    "path": "documentation/docs/testing.md",
    "content": "---\nid: testing\ntitle: Testing\nsidebar_label: Testing\n---\n\nThis boilerplate uses [Jest](https://jestjs.io/docs/en/getting-started) for Unit Testing and [SuperTest](https://github.com/visionmedia/supertest) for integration tests.\n\n## Seeder\nWe have included seeder to the project. Also we have a helper called `setupDatabase`, you can include this to `beforeEach` block of your tests.\nThis helper will reset database and seed the database.\n\nIdeally, we are adding this setupDatabase helper to the `beforeEach` block. This will make sure that we run tests against freshly seeded database.\n\n```ts\nconst setupDatabase = async (): Promise<void> => {\n\tawait CreateConnection();\n\n\tawait Seeder.seed();\n};\n```\n\n```ts\nbeforeEach(async () => {\n\tawait setupDatabase();\n});\n```\n\n\n## Examples\n### Testing Service Helpers\n\n```js\n\tdescribe('Weapon service helpers', () => {\n\t\tit('should trigger Fire method', async () => {\n\t\t\tconst params: IAttack.AttackInDto = {\n\t\t\t\tweaponName: 'Death Star',\n\t\t\t\tplanetName: 'Alderaan',\n\t\t\t};\n\n\t\t\tconst result = await AttackHelper.Fire(DummyContext.getCall(params), params);\n\n\t\t\texpect(result).toBeDefined();\n\t\t});\n\t});\n```\n\n### Testing Metas\n\n```js\n\tit('should calculate remaining shield', async () => {\n\t\tconst entityManager = getManager();\n\n\t\tconst weapon = await entityManager.findOne(Weapon, { name: 'Death Star' });\n\t\tconst planet = await entityManager.findOne(Planet, { name: 'Alderaan' });\n\n\t\tconst { damage, remainingShield } = await CalculateMeta.Damage(weapon, planet);\n\n\t\texpect(remainingShield).toEqual(planet.shield - damage);\n\t});\n```\n\n### Testing Service Methods\n\n```typescript\n\tconst broker = BrokerHelper.setupBroker();\n\n\tbeforeEach(async () => {\n\t\tawait broker.start();\n\t\tawait setupDatabase();\n\t});\n\n\tafterEach(async () => {\n\t\tawait broker.stop();\n\t});\n\n\tdescribe('Test attack service', () => {\n\t\tconst params = {\n\t\t\tplanetName: 'Alderaan',\n\t\t\tweaponName: 'Death Star',\n\t\t};\n\n\t\tdescribe('Fire method', async () => {\n\t\t\tit('when ammo is up', async () => {\n\t\t\t\tconst { planetMessage, weaponMessage } = await AttackHelper.Fire(broker as any, params);\n\n\t\t\t\texpect(planetMessage).toContain('Planet took');\n\t\t\t\texpect(weaponMessage).toContain('Death Star did');\n\t\t\t});\n\n\t\t\tit('when ammo is empty', async () => {\n\t\t\t\tgetManager().update(Weapon, { name: 'Death Star' }, { ammo: 0 });\n\n\t\t\t\tconst { planetMessage, weaponMessage } = await AttackHelper.Fire(broker as any, params);\n\n\t\t\t\texpect(planetMessage).toEqual('Planet took no damage');\n\t\t\t\texpect(weaponMessage).toEqual('This weapon has no ammo');\n\t\t\t});\n\t\t});\n\t});\n```\n\n### Testing Repositories\n\n```typescript\n\tdescribe('Planet Repository Methods', () => {\n\t\tbeforeEach(async () => {\n\t\t\tawait setupDatabase();\n\t\t});\n\n\t\tafterEach(async () => {\n\t\t\tawait getConnection().close();\n\t\t});\n\n\t\tdescribe('Get', () => {\n\t\t\tit('should get planet if there is any', async () => {\n\t\t\t\tconst planetName = 'Alderaan';\n\n\t\t\t\tconst planet = await PlanetRepository.Get(planetName);\n\n\t\t\t\texpect(planet.name).toEqual(planetName);\n\t\t\t});\n\n\t\t\tit('should raise error', async () => {\n\t\t\t\tconst planetName = 'I dont exist';\n\n\t\t\t\texpect(() => PlanetRepository.Get(planetName)).toThrowError;\n\t\t\t});\n\t\t});\n\n\t\tit('should update shield', async () => {\n\t\t\tconst planetName = 'Alderaan';\n\n\t\t\tconst expectedShield = 1000;\n\n\t\t\tconst { remainingShield } = await PlanetRepository.UpdateShield(planetName, expectedShield);\n\n\t\t\texpect(remainingShield).toEqual(expectedShield);\n\t\t});\n\t});\n```\n\n### Integration Tests For Services\n\n```typescript\n\tconst request = require(\"supertest\");\n\tconst broker = BrokerHelper.setupBroker();\n\tlet server;\n\n\tbeforeEach(async () => {\n\t\tawait setupDatabase();\n\t});\n\n\tafterEach(async () => {\n\t\tawait getConnection().close();\n\t});\n\n\tbeforeAll(() => {\n\t\tconst service = broker.createService(ApiGateway);\n\t\tserver = service.server;\n\t\treturn broker.start();\n\t});\n\n\tafterAll(() => broker.stop());\n\n\tdescribe(\"Test Attack service requests\", () => {\n\t\tit(\"Test POST request on attack service Fire method\", () => {\n\n\t\t\tconst params = {\n\t\t\t\tplanetName: 'Alderaan',\n\t\t\t\tweaponName: 'Death Star'\n\t\t\t}\n\n\t\t\treturn request(server)\n\t\t\t\t.post(\"/attack/Fire\")\n\t\t\t\t.query({ ...params })\n\t\t\t\t.then(res => {\n\t\t\t\t\texpect(res.statusCode).toBe(200);\n\t\t\t\t\texpect(res.headers[\"content-type\"]).toBe(\"application/json; charset=utf-8\");\n\t\t\t\t\texpect(res.body.planetMessage).toContain('Planet took');\n\t\t\t\t\texpect(res.body.weaponMessage).toContain('Death Star did');\n\t\t\t\t});\n\t\t});\n\t});\n\n```\n"
  },
  {
    "path": "documentation/docs/typeorm.md",
    "content": "---\nid: typeorm\ntitle: TypeORM & Repository\nsidebar_label: TypeORM\n---\n\n`createConnection` method in  `src/Entities/Connection` file is responsible for creating database connection. \n\nThen, `Repositories` handles database interactions with `getManager` method of TypeORM.\n\nHere is a planet Entity example from example app;\n\n```\n//#region Global Imports\nimport { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';\n//#endregion Global Imports\n\n@Entity()\nexport class Planet {\n\t@PrimaryGeneratedColumn()\n\tid: number;\n\n\t@Column()\n\tname: string;\n\n\t@Column()\n\tshield: number;\n}\n```\n\nAnd this is Planet repository;\n\n```\n//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Planet } from '@Entities/Planet';\nimport { getResource } from './Shared';\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { DecreaseShieldOutDto } from '@Interfaces';\n//#endregion Interface Imports\n\nexport namespace PlanetRepository {\n\texport const Get = async (planetName: string): Promise<Planet> => {\n\t\treturn await getResource(Planet, { name: planetName });\n\t};\n\n\texport const DecreaseShield = async (\n\t\tplanetName: string,\n\t\tremainingShield: number,\n\t): Promise<DecreaseShieldOutDto> => {\n\t\tconst planet = await getResource(Planet, { name: planetName });\n\n\t\tplanet.shield = remainingShield;\n\n\t\tawait getManager().save(planet);\n\n\t\treturn { remainingShield: planet.shield };\n\t};\n}\n\n```\n\n>Refer to [offical documentation](https://typeorm.io/#/entities) for detailed usage. \n\n"
  },
  {
    "path": "documentation/website/config.yml",
    "content": "GIT_USER=docusaurus-bot\nUSE_SSH=true\n"
  },
  {
    "path": "documentation/website/core/Footer.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require('react');\n\nconst docs = require(\"../docs.json\");\n\nclass Footer extends React.Component {\n\n  constructor() {\n    super();\n    this.state = {\n      docs\n    }\n  }\n\n  docUrl(doc, language) {\n    const baseUrl = this.props.config.baseUrl;\n    const docsUrl = this.props.config.docsUrl;\n    const docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;\n    const langPart = `${language ? `${language}/` : ''}`;\n    return `${baseUrl}${docsPart}${langPart}${doc}`;\n  }\n\n  pageUrl(doc, language) {\n    const baseUrl = this.props.config.baseUrl;\n    return baseUrl + (language ? `${language}/` : '') + doc;\n  }\n\n  render() {\n    return (\n      <footer className=\"nav-footer\" id=\"footer\">\n        <section className=\"sitemap\">\n          <a href={this.props.config.baseUrl} className=\"nav-home\">\n            {this.props.config.footerIcon && (\n              <img\n                src={this.props.config.baseUrl + this.props.config.footerIcon}\n                alt={this.props.config.title}\n                width=\"66\"\n              />\n            )}\n          </a>\n          <div>\n            <h5>Docs</h5>\n            {\n              this.state.docs.map((doc, index) => (\n                <a key={index} href={this.docUrl(`${doc.id}.html`, this.props.language)}>\n                  {doc.title}\n                </a>\n              ))\n            }\n          </div>\n          <div>\n            <h5>Community</h5>\n            {\n              this.props.config.socialMediaUrl.map((url, index) => (\n                <a\n                  key={index}\n                  href={url.url}\n                  target=\"_blank\"\n                  rel=\"noreferrer noopener\">\n                  {url.title}\n                </a>\n              ))\n            }\n          </div>\n          <div>\n            <h5>More</h5>\n            <a href=\"https://github.com/pankod\">GitHub</a>\n            <a\n              className=\"github-button\"\n              href={this.props.config.repoUrl}\n              data-icon=\"octicon-star\"\n              data-count-href=\"/facebook/docusaurus/stargazers\"\n              data-show-count=\"true\"\n              data-count-aria-label=\"# stargazers on GitHub\"\n              aria-label=\"Star this project on GitHub\">\n              Star\n            </a>\n          </div>\n        </section>\n\n        <a\n          href=\"https://github.com/pankod/moleculerjs-boilerplate\"\n          target=\"_blank\"\n          rel=\"noreferrer noopener\"\n          className=\"fbOpenSource\">\n          <img\n            src={`${this.props.config.baseUrl}img/pankod_footer_logo.png`}\n            alt=\"Pankod Open Source\"\n            width=\"170\"\n          />\n        </a>\n        <section className=\"copyright\">{this.props.config.copyright}</section>\n      </footer>\n    );\n  }\n}\n\nmodule.exports = Footer;\n"
  },
  {
    "path": "documentation/website/docs.json",
    "content": "[\n\t{\n\t\t\"id\": \"getting-started\",\n\t\t\"title\": \"Getting Started\"\n\t},\n\t{\n\t\t\"id\": \"example-app\",\n\t\t\"title\": \"Example App\",\n\t\t\"sidebarLevel\": null\n\t},\n\t{\n\t\t\"id\": \"testing\",\n\t\t\"title\": \"Features\",\n\t\t\"sidebarLevel\": null\n\t},\n\t{\n\t\t\"id\": \"setup\",\n\t\t\"title\": \"Setup\",\n\t\t\"sidebarLevel\": null\n\t}\n]\n"
  },
  {
    "path": "documentation/website/i18n/en.json",
    "content": "{\n  \"_comment\": \"This file is auto-generated by write-translations.js\",\n  \"localized-strings\": {\n    \"next\": \"Next\",\n    \"previous\": \"Previous\",\n    \"tagline\": \"Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Helpers, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects.\",\n    \"docs\": {\n      \"cli-migration-guide\": {\n        \"title\": \"CLI Migrate Guide\",\n        \"sidebar_label\": \"Migration Guide\"\n      },\n      \"cli-overview\": {\n        \"title\": \"Overview\",\n        \"sidebar_label\": \"Overview\"\n      },\n      \"cli-usage\": {\n        \"title\": \"Usage\",\n        \"sidebar_label\": \"Usage\"\n      },\n      \"deployment\": {\n        \"title\": \"Deployment\",\n        \"sidebar_label\": \"Deployment\"\n      },\n      \"eslint\": {\n        \"title\": \"Usage\",\n        \"sidebar_label\": \"ESLint\"\n      },\n      \"example-app\": {\n        \"title\": \"Example App\",\n        \"sidebar_label\": \"Example App\"\n      },\n      \"features\": {\n        \"title\": \"What's included?\"\n      },\n      \"getting-started\": {\n        \"title\": \"Getting Started\",\n        \"sidebar_label\": \"Getting Started\"\n      },\n      \"setup\": {\n        \"title\": \"Setup\"\n      },\n      \"structure\": {\n        \"title\": \"Structure\",\n        \"sidebar_label\": \"Structure\"\n      },\n      \"swagger\": {\n        \"title\": \"Usage\",\n        \"sidebar_label\": \"Swagger\"\n      },\n      \"testing\": {\n        \"title\": \"Testing\",\n        \"sidebar_label\": \"Testing\"\n      },\n      \"typeorm\": {\n        \"title\": \"TypeORM & Repository\",\n        \"sidebar_label\": \"TypeORM\"\n      }\n    },\n    \"links\": {\n      \"Docs\": \"Docs\",\n      \"Github\": \"Github\"\n    },\n    \"categories\": {\n      \"Introduction\": \"Introduction\",\n      \"Overview\": \"Overview\",\n      \"Features\": \"Features\",\n      \"Project CLI\": \"Project CLI\"\n    }\n  },\n  \"pages-strings\": {\n    \"Help Translate|recruit community translators for your project\": \"Help Translate\",\n    \"Edit this Doc|recruitment message asking to edit the doc source\": \"Edit\",\n    \"Translate this Doc|recruitment message asking to translate the docs\": \"Translate\"\n  }\n}\n"
  },
  {
    "path": "documentation/website/package.json",
    "content": "{\n\t\"scripts\": {\n\t\t\"examples\": \"docusaurus-examples\",\n\t\t\"start\": \"docusaurus-start\",\n\t\t\"build\": \"docusaurus-build\",\n\t\t\"publish-gh-pages\": \"docusaurus-publish\",\n\t\t\"write-translations\": \"docusaurus-write-translations\",\n\t\t\"version\": \"docusaurus-version\",\n\t\t\"rename-version\": \"docusaurus-rename-version\"\n\t},\n\t\"devDependencies\": {\n\t\t\"docusaurus\": \"^1.9.0\"\n\t}\n}\n"
  },
  {
    "path": "documentation/website/pages/en/help.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require('react');\n\nconst CompLibrary = require('../../core/CompLibrary.js');\n\nconst Container = CompLibrary.Container;\nconst GridBlock = CompLibrary.GridBlock;\n\nfunction Help(props) {\n\tconst { config: siteConfig, language = '' } = props;\n\tconst { baseUrl, docsUrl } = siteConfig;\n\tconst docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;\n\tconst langPart = `${language ? `${language}/` : ''}`;\n\tconst docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`;\n\n\tconst supportLinks = [\n\t\t{\n\t\t\tcontent: `Learn more using the [documentation on this site.](${docUrl(\n\t\t\t\t'doc1.html',\n\t\t\t)})`,\n\t\t\ttitle: 'Browse Docs',\n\t\t},\n\t\t{\n\t\t\tcontent: 'Ask questions about the documentation and project',\n\t\t\ttitle: 'Join the community',\n\t\t},\n\t\t{\n\t\t\tcontent: \"Find out what's new with this project\",\n\t\t\ttitle: 'Stay up to date',\n\t\t},\n\t];\n\n\treturn (\n\t\t<div className=\"docMainWrapper wrapper\">\n\t\t\t<Container className=\"mainContainer documentContainer postContainer\">\n\t\t\t\t<div className=\"post\">\n\t\t\t\t\t<header className=\"postHeader\">\n\t\t\t\t\t\t<h1>Need help?</h1>\n\t\t\t\t\t</header>\n\t\t\t\t\t<p>This project is maintained by a dedicated group of people.</p>\n\t\t\t\t\t<GridBlock contents={supportLinks} layout=\"threeColumn\" />\n\t\t\t\t</div>\n\t\t\t</Container>\n\t\t</div>\n\t);\n}\n\nmodule.exports = Help;\n"
  },
  {
    "path": "documentation/website/pages/en/index.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require('react');\n\nconst CompLibrary = require('../../core/CompLibrary.js');\n\nconst MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */\nconst Container = CompLibrary.Container;\nconst GridBlock = CompLibrary.GridBlock;\n\nclass HomeSplash extends React.Component {\n\trender() {\n\t\tconst { siteConfig, language = '' } = this.props;\n\t\tconst { baseUrl, docsUrl } = siteConfig;\n\t\tconst docsPart = `${docsUrl ? `${docsUrl}/` : ''}`;\n\t\tconst langPart = `${language ? `${language}/` : ''}`;\n\t\tconst docUrl = doc => `${baseUrl}${docsPart}${langPart}${doc}`;\n\n\t\tconst SplashContainer = props => (\n\t\t\t<div className=\"homeContainer\">\n\t\t\t\t<div className=\"homeSplashFade\">\n\t\t\t\t\t<div className=\"wrapper homeWrapper\">{props.children}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\n\t\tconst ProjectTitle = () => (\n\t\t\t<h2 className=\"projectTitle\">\n\t\t\t\t{siteConfig.headerTitle}\n\t\t\t\t<small className=\"header-title\" >{siteConfig.tagline}</small>\n\t\t\t</h2>\n\t\t);\n\n\t\tconst PromoSection = props => (\n\t\t\t<div className=\"section promoSection\">\n\t\t\t\t<div className=\"promoRow\">\n\t\t\t\t\t<div className=\"pluginRowBlock\">{props.children}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\n\t\tconst Button = props => (\n\t\t\t<div className=\"pluginWrapper buttonWrapper\">\n\t\t\t\t<a className=\"button\" href={props.href} target={props.target}>\n\t\t\t\t\t{props.children}\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t);\n\n\t\treturn (\n\t\t\t<SplashContainer>\n\t\t\t\t<div className=\"inner\">\n\t\t\t\t\t<img className=\"home-banner\" src=\"img/banner4.png\" />\n\t\t\t\t\t<ProjectTitle siteConfig={siteConfig} />\n\n\t\t\t\t</div>\n\t\t\t\t<div className=\"top-badges\">\n\t\t\t\t\t<a href=\"https://codeclimate.com/github/pankod/moleculerjs-boilerplate/maintainability\">\n\t\t\t\t\t\t<img src=\"https://api.codeclimate.com/v1/badges/077c02d5cb9ec7d8a654/maintainability\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a href=\"https://codeclimate.com/github/pankod/moleculerjs-boilerplate/test_coverage\">\n\t\t\t\t\t\t<img src=\"https://api.codeclimate.com/v1/badges/077c02d5cb9ec7d8a654/test_coverage\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a href=\"https://travis-ci.org/pankod/moleculerjs-boilerplate\">\n\t\t\t\t\t\t<img src=\"https://travis-ci.org/pankod/moleculerjs-boilerplate.svg?branch=master\" alt=\"Build Status\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a href=\"https://david-dm.org/pankod/moleculerjs-boilerplate\">\n\t\t\t\t\t\t<img src=\"https://david-dm.org/pankod/moleculerjs-boilerplate.svg\" alt=\"Dependency Status\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a href=\"https://david-dm.org/pankod/moleculerjs-boilerplate#info=devDependencies\">\n\t\t\t\t\t\t<img src=\"https://david-dm.org/pankod/moleculerjs-boilerplate/dev-status.svg\" alt=\"devDependency Status\" />\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</SplashContainer>\n\t\t);\n\t}\n}\n\nclass Index extends React.Component {\n\trender() {\n\t\tconst { config: siteConfig, language = '' } = this.props;\n\t\tconst { baseUrl } = siteConfig;\n\n\t\tconst Block = props => (\n\t\t\t<Container\n\t\t\t\tpadding={['bottom', 'top']}\n\t\t\t\tid={props.id}\n\t\t\t\tbackground={props.background}>\n\t\t\t\t<GridBlock\n\t\t\t\t\talign={props.align}\n\t\t\t\t\tcontents={props.children}\n\t\t\t\t\tlayout={props.layout}\n\t\t\t\t/>\n\t\t\t</Container>\n\t\t);\n\n\t\tconst FeatureCallout = () => (\n\t\t\t<div\n\t\t\t\tclassName=\"productShowcaseSection paddingBottom\"\n\t\t\t\tstyle={{ textAlign: 'center' }}>\n\t\t\t\t<h2>Features </h2>\n\t\t\t</div>\n\t\t);\n\n\t\tconst TryOut = () => (\n\t\t\t<Block id=\"try\">\n\t\t\t\t{[\n\t\t\t\t\t{\n\t\t\t\t\t\tcontent:\n\t\t\t\t\t\t\t'Jest is a testing tool from Facebook that makes it easy to perform unit testing in JavaScript.',\n\t\t\t\t\t\timage: `${baseUrl}img/testing.png`,\n\t\t\t\t\t\timageAlign: 'left',\n\t\t\t\t\t\ttitle: 'Jest',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t</Block>\n\t\t);\n\n\t\tconst LearnHow = () => (\n\t\t\t<Block background=\"light\">\n\t\t\t\t{[\n\t\t\t\t\t{\n\t\t\t\t\t\tcontent:\n\t\t\t\t\t\t\t'Pankod boilerplate is shipped with a CLI tool to streamline the creation of new components.',\n\t\t\t\t\t\timage: `${baseUrl}img/cli.gif`,\n\t\t\t\t\t\timageAlign: 'right',\n\t\t\t\t\t\ttitle: 'Built-in Project CLI',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t</Block>\n\t\t);\n\t\tconst LastFeature = () => (\n\t\t\t<Block background=\"light\">\n\t\t\t\t{[\n\t\t\t\t\t{\n\t\t\t\t\t\tcontent: 'Provides easy communication contract between services.',\n\t\t\t\t\t\timage: `${baseUrl}img/service-helpers.png`,\n\t\t\t\t\t\timageAlign: 'right',\n\t\t\t\t\t\ttitle: 'Service Helpers'\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t</Block>\n\t\t);\n\n\t\tconst Features = () => (\n\t\t\t<React.Fragment>\n\t\t\t\t<Block layout=\"fourColumn\" align='center'>\n\t\t\t\t\t{[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Progressive microservices framework for Node.js.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/moleculer-logo2.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Moleculer',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Superset of JavaScript which primarily provides optional static typing, classes and interfaces.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/typescript-logo.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'TypeScript',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'TypeORM is specifically an ORM that converts data between JavaScript / TypeScript to a variety of databases',\n\t\t\t\t\t\t\timage: `${baseUrl}img/typeorm.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'TypeORM',\n\t\t\t\t\t\t\tclassName: 'orm'\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Create services, models and interfaces with one command by using built-in cli.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/cli-logo.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Project CLI',\n\t\t\t\t\t\t}\n\n\n\n\t\t\t\t\t]}\n\t\t\t\t</Block>\n\n\t\t\t\t<Block layout=\"fourColumn\" align='center'>\n\t\t\t\t\t{[\n\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Jest is a testing tool from Facebook that makes it easy to perform unit testing in JavaScript.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/jest-logo.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Jest',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Create, deploy, and run applications by using docker containers.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/docker2.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Docker',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Tools that helps developers design, build, document, and consume RESTful Web services.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/swagger.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Swagger',\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontent: 'Linter for the JavaScript programming language.',\n\t\t\t\t\t\t\timage: `${baseUrl}img/eslint-logo.png`,\n\t\t\t\t\t\t\timageAlign: 'top',\n\t\t\t\t\t\t\ttitle: 'Eslint',\n\t\t\t\t\t\t}\n\t\t\t\t\t]}\n\t\t\t\t</Block>\n\t\t\t</React.Fragment>\n\t\t);\n\n\n\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t<HomeSplash siteConfig={siteConfig} language={language} />\n\t\t\t\t<div className=\"mainContainer homeMain\">\n\t\t\t\t\t<Features />\n\t\t\t\t\t<FeatureCallout />\n\t\t\t\t\t<LearnHow />\n\t\t\t\t\t<TryOut />\n\t\t\t\t\t<LastFeature />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\nmodule.exports = Index;\n"
  },
  {
    "path": "documentation/website/pages/en/users.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nconst React = require('react');\n\nconst CompLibrary = require('../../core/CompLibrary.js');\n\nconst Container = CompLibrary.Container;\n\nclass Users extends React.Component {\n\trender() {\n\t\tconst { config: siteConfig } = this.props;\n\t\tif ((siteConfig.users || []).length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst editUrl = `${siteConfig.repoUrl}/edit/master/website/siteConfig.js`;\n\t\tconst showcase = siteConfig.users.map(user => (\n\t\t\t<a href={user.infoLink} key={user.infoLink}>\n\t\t\t\t<img src={user.image} alt={user.caption} title={user.caption} />\n\t\t\t</a>\n\t\t));\n\n\t\treturn (\n\t\t\t<div className=\"mainContainer\">\n\t\t\t\t<Container padding={['bottom', 'top']}>\n\t\t\t\t\t<div className=\"showcaseSection\">\n\t\t\t\t\t\t<div className=\"prose\">\n\t\t\t\t\t\t\t<h1>Who is Using This?</h1>\n\t\t\t\t\t\t\t<p>This project is used by many folks</p>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"logos\">{showcase}</div>\n\t\t\t\t\t\t<p>Are you using this project?</p>\n\t\t\t\t\t\t<a href={editUrl} className=\"button\">\n\t\t\t\t\t\t\tAdd your company\n            </a>\n\t\t\t\t\t</div>\n\t\t\t\t</Container>\n\t\t\t</div>\n\t\t);\n\t}\n}\n\nmodule.exports = Users;\n"
  },
  {
    "path": "documentation/website/sidebars.json",
    "content": "{\n\t\"docs\": {\n\t\t\"Introduction\": [\n\t\t\t\"getting-started\",\n\t\t\t\"features\"\n\t\t],\n\t\t\"Overview\": [\n\t\t\t\"setup\",\n\t\t\t\"example-app\",\n\t\t\t\"structure\",\n\t\t\t\"deployment\"\n\t\t],\n\t\t\"Features\": [\n\t\t\t\"testing\",\n\t\t\t\"swagger\",\n\t\t\t\"eslint\",\n\t\t\t\"typeorm\"\n\t\t],\n\t\t\"Project CLI\": [\n\t\t\t\"cli-overview\",\n\t\t\t\"cli-usage\",\n\t\t\t\"cli-migration-guide\"\n\t\t]\n\t}\n}\n"
  },
  {
    "path": "documentation/website/siteConfig.js",
    "content": "/**\n * Copyright (c) 2017-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// See https://docusaurus.io/docs/site-config for all the possible\n// site configuration options.\n\n// List of projects/orgs using your project for the users page.\nconst users = [\n\t{\n\t\tcaption: 'User1',\n\t\t// You will need to prepend the image path with your baseUrl\n\t\t// if it is not '/', like: '/test-site/img/image.jpg'.\n\t\timage: '/img/undraw_open_source.svg',\n\t\tinfoLink: 'https://www.facebook.com',\n\t\tpinned: true,\n\t},\n];\n\nconst organizationName = 'pankod';\nconst projectName = 'moleculerjs-boilerplate';\nconst packageName = 'moleculerjs-boilerplate';\nconst url = [\n\t{\n\t\ttitle: 'Twitter',\n\t\turl: 'https://twitter.com/PankodDev',\n\t},\n];\n\nconst siteConfig = {\n\ttitle: 'Pankod', // Title for your website.\n\theaderTitle: 'moleculerjs-boilerplate',\n\ttagline:\n\t\t'Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Helpers, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects.',\n\turl: 'https://pankod.github.io', // Your website URL\n\tbaseUrl: '/moleculerjs-boilerplate/', // Base URL for your project */\n\t// For github.io type URLs, you would set the url and baseUrl like:\n\t//   url: 'https://facebook.github.io',\n\t//   baseUrl: '/test-site/',\n\n\tsocialMediaUrl: url,\n\tpackageName: packageName,\n\n\t// Used for publishing and more\n\tprojectName: projectName,\n\torganizationName: organizationName,\n\t// For top-level user or org sites, the organization is still the same.\n\t// e.g., for the https://JoelMarcey.github.io site, it would be set like...\n\t//   organizationName: 'JoelMarcey'\n\n\t// For no header links in the top nav bar -> headerLinks: [],\n\theaderLinks: [\n\t\t{ doc: 'getting-started', label: 'Docs' },\n\t\t/* \t\t{ page: 'users', label: 'Help' }, */\n\t\t{ href: 'https://github.com/pankod/' + packageName, label: 'Github' },\n\t\t{ search: true },\n\t\t{ languages: true },\n\t],\n\n\t// If you have users set above, you add it here:\n\tusers,\n\n\t/* path to images for header/footer */\n\theaderIcon: 'img/footer_icon.png',\n\tfooterIcon: 'img/footer_icon.png',\n\tfavicon: 'img/favicon.png',\n\n\t/* Colors for website */\n\tcolors: {\n\t\tprimaryColor: '#2C3E50',\n\t\tsecondaryColor: '#83878D',\n\t},\n\n\t/* Custom fonts for website */\n\t/*\n\tfonts: {\n\t  myFont: [\n\t\t\"Times New Roman\",\n\t\t\"Serif\"\n\t  ],\n\t  myOtherFont: [\n\t\t\"-apple-system\",\n\t\t\"system-ui\"\n\t  ]\n\t},\n\t*/\n\n\t// This copyright info is used in /core/Footer.js and blog RSS/Atom feeds.\n\tcopyright: `Copyright © ${new Date().getFullYear()} ${organizationName}`,\n\n\thighlight: {\n\t\t// Highlight.js theme to use for syntax highlighting in code blocks.\n\t\ttheme: 'tomorrow-night',\n\t},\n\n\t// Add custom scripts here that would be placed in <script> tags.\n\tscripts: ['https://buttons.github.io/buttons.js'],\n\n\t// On page navigation for the current documentation page.\n\tonPageNav: 'separate',\n\t// No .html extensions for paths.\n\tcleanUrl: true,\n\n\t// Open Graph and Twitter card images.\n\t// Google Analytics id\n\tgaTrackingId: 'UA-143750629-1',\n\n\t// Facebook settings\n\tfacebookAppId: '',\n\tfacebookPixelId: '',\n\tfacebookComments: false,\n\n\t// Twitter settings\n\ttwitter: '',\n\togImage: 'img/undraw_online.svg',\n\ttwitterImage: 'img/undraw_tweetstorm.svg',\n\n\t// Show documentation's last contributor's name.\n\t// enableUpdateBy: true,\n\n\t// Show documentation's last update time.\n\t// enableUpdateTime: true,\n\n\t// You may provide arbitrary config keys to be used as needed by your\n\t// template. For example, if you need your repo's URL...\n\trepoUrl: 'https://github.com/pankod/' + packageName,\n\n\t// Custom css\n\tseparateCss: [],\n};\n\nmodule.exports = siteConfig;\n"
  },
  {
    "path": "documentation/website/static/css/custom.css",
    "content": "/* your custom css */\n.nav-footer {\n\tbackground-color: #2c3e50;\n}\n\n.gridBlock {\n\talign-items: baseline;\n}\n.top-badges {\n\tmargin-top: 20px;\n}\n.top-badges > a {\n\tmargin: 0 2px;\n}\n.promoSection {\n\tmargin-top: 50px;\n}\n.home-banner {\n\tmargin-bottom: 50px;\n\tmargin-top: 30px;\n}\n\n.homeMain{\n\tpadding-top: 0 !important;\n\tpadding-bottom: 0 !important;\n}\n.blockImage{\n\twidth: 15%;\n}\n.projectTitle > small{\n\tfont-size: 42%;\n\tcolor:#696969;\n\tline-height: 1.4;\n\n}\n\n@media only screen and (min-device-width: 360px) and (max-device-width: 736px) {\n}\n\n@media only screen and (min-width: 1024px) {\n}\n\n@media only screen and (max-width: 1023px) {\n}\n\n@media only screen and (min-width: 1400px) {\n}\n\n@media only screen and (min-width: 1500px) {\n}\n"
  },
  {
    "path": "moleculer.config.ts",
    "content": "'use strict';\nimport { BrokerOptions } from 'moleculer';\nimport 'reflect-metadata';\nimport * as Moleculer from 'moleculer';\nimport MoleculerRetryableError = Moleculer.Errors.MoleculerRetryableError;\n\n/**\n * Moleculer ServiceBroker configuration file\n *\n * More info about options: https://moleculer.services/docs/0.14/broker.html#Broker-options\n *\n * Overwrite options in production:\n * ================================\n * \tYou can overwrite any option with environment variables.\n * \tFor example to overwrite the \"logLevel\", use `LOGGER=warn` env var.\n * \tTo overwrite a nested parameter, e.g. retryPolicy.retries, use `RETRYPOLICY_RETRIES=10` env var.\n *\n * \tTo overwrite broker’s deeply nested default options, which are not presented in \"moleculer.config.ts\",\n * \tvia environment variables, use the `MOL_` prefix and double underscore `__` for nested properties in .env file.\n * \tFor example, to set the cacher prefix to `MYCACHE`, you should declare an env var as `MOL_CACHER__OPTIONS__PREFIX=MYCACHE`.\n */\nconst brokerConfig: BrokerOptions = {\n\t// Namespace of nodes to segment your nodes on the same network.\n\tnamespace: '',\n\t// Unique node identifier. Must be unique in a namespace.\n\tnodeID: undefined,\n\n\t// Enable/disable logging or use custom logger. More info: https://moleculer.services/docs/0.14/logging.html\n\tlogger: true,\n\t// Log level for built-in console logger. Available values: trace, debug, info, warn, error, fatal\n\tlogLevel: 'info',\n\t// Log formatter for built-in console logger. Available values: default, simple, short. It can be also a `Function`.\n\tlogFormatter: 'default',\n\t// Custom object & array printer for built-in console logger.\n\tlogObjectPrinter: undefined,\n\n\t// Define transporter.\n\t// More info: https://moleculer.services/docs/0.14/networking.html\n\ttransporter: {\n\t\ttype: 'TCP',\n\t\toptions: {\n\t\t\tudpDiscovery: false,\n\t\t},\n\t},\n\n\t// Define a serializer.\n\t// Available values: \"JSON\", \"Avro\", \"ProtoBuf\", \"MsgPack\", \"Notepack\", \"Thrift\".\n\t// More info: https://moleculer.services/docs/0.14/networking.html\n\tserializer: 'JSON',\n\n\t// Number of milliseconds to wait before reject a request with a RequestTimeout error. Disabled: 0\n\trequestTimeout: 10 * 1000,\n\n\t// Retry policy settings. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Retry\n\tretryPolicy: {\n\t\t// Enable feature\n\t\tenabled: false,\n\t\t// Count of retries\n\t\tretries: 5,\n\t\t// First delay in milliseconds.\n\t\tdelay: 100,\n\t\t// Maximum delay in milliseconds.\n\t\tmaxDelay: 1000,\n\t\t// Backoff factor for delay. 2 means exponential backoff.\n\t\tfactor: 2,\n\t\t// A function to check failed requests.\n\t\tcheck: (err: Error) => err && err instanceof MoleculerRetryableError && !!err.retryable,\n\t},\n\n\t// Limit of calling level. If it reaches the limit, broker will throw an MaxCallLevelError error. (Infinite loop protection)\n\tmaxCallLevel: 100,\n\n\t// Number of seconds to send heartbeat packet to other nodes.\n\theartbeatInterval: 5,\n\t// Number of seconds to wait before setting node to unavailable status.\n\theartbeatTimeout: 15,\n\n\t// Tracking requests and waiting for running requests before shutdowning. More info: https://moleculer.services/docs/0.14/fault-tolerance.html\n\ttracking: {\n\t\t// Enable feature\n\t\tenabled: false,\n\t\t// Number of milliseconds to wait before shutdowning the process\n\t\tshutdownTimeout: 5000,\n\t},\n\n\t// Disable built-in request & emit balancer. (Transporter must support it, as well.)\n\tdisableBalancer: false,\n\n\t// Settings of Service Registry. More info: https://moleculer.services/docs/0.14/registry.html\n\tregistry: {\n\t\t// Define balancing strategy.\n\t\t// Available values: \"RoundRobin\", \"Random\", \"CpuUsage\", \"Latency\"\n\t\tstrategy: 'RoundRobin',\n\t\t// Enable local action call preferring.\n\t\tpreferLocal: true,\n\t},\n\n\t// Settings of Circuit Breaker. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Circuit-Breaker\n\tcircuitBreaker: {\n\t\t// Enable feature\n\t\tenabled: false,\n\t\t// Threshold value. 0.5 means that 50% should be failed for tripping.\n\t\tthreshold: 0.5,\n\t\t// Minimum request count. Below it, CB does not trip.\n\t\tminRequestCount: 20,\n\t\t// Number of seconds for time window.\n\t\twindowTime: 60,\n\t\t// Number of milliseconds to switch from open to half-open state\n\t\thalfOpenTime: 10 * 1000,\n\t\t// A function to check failed requests.\n\t\tcheck: (err: Error) => err && err instanceof MoleculerRetryableError && err.code >= 500,\n\t},\n\n\t// Settings of bulkhead feature. More info: https://moleculer.services/docs/0.14/fault-tolerance.html#Bulkhead\n\tbulkhead: {\n\t\t// Enable feature.\n\t\tenabled: false,\n\t\t// Maximum concurrent executions.\n\t\tconcurrency: 10,\n\t\t// Maximum size of queue\n\t\tmaxQueueSize: 100,\n\t},\n\n\t// Enable parameters validation. More info: https://moleculer.services/docs/0.13/validating.html\n\tvalidator: true,\n\n\t// Enable metrics function. More info: https://moleculer.services/docs/0.14/metrics.html\n\tmetrics: {\n\t\tenabled: true,\n\t},\n\n\t// Register internal services (\"$node\"). More info: https://moleculer.services/docs/0.14/services.html#Internal-services\n\tinternalServices: true,\n\t// Register internal middlewares. More info: https://moleculer.services/docs/0.14/middlewares.html#Internal-middlewares\n\tinternalMiddlewares: true,\n\n\t// Watch the loaded services and hot reload if they changed. You can also enable it in Moleculer Runner with `--hot` argument\n\thotReload: false,\n\n\t// Register custom middlewares\n\tmiddlewares: [],\n\n\t// Called after broker created.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tcreated(broker) {},\n\n\t// Called after broker starte.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tstarted(broker) {},\n\n\t// Called after broker stopped.\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tstopped(broker) {},\n\n\t// Register custom REPL commands.\n\treplCommands: undefined,\n};\n\nexport = brokerConfig;"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"moleculerjs-boilerplate\",\n  \"version\": \"1.0.0\",\n  \"description\": \"My Moleculer microservices project\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"dev\": \"ts-node -r tsconfig-paths/register ./node_modules/moleculer/bin/moleculer-runner.js --hot --repl --config moleculer.config.ts services/**/*.service.ts & npm run swagger\",\n    \"start\": \"TS_NODE_PROJECT=tsconfig.production.json node -r tsconfig-paths/register ./node_modules/moleculer/bin/moleculer-runner.js dist/services\",\n    \"cli\": \"pankod-cli add\",\n    \"test\": \"jest --coverage --runInBand\",\n    \"lint\": \"eslint -c .eslintrc.js --ext .ts {services,src,test}/**\",\n    \"format\": \"eslint -c .eslintrc.js --ext .ts --fix {services,src,test}/**\",\n    \"dc:up\": \"docker-compose up --build -d\",\n    \"dc:down\": \"docker-compose down\",\n    \"swagger\": \"swagger-jsdoc -d swagger/config.js -o swagger/swagger.json services/*.service.ts && node ./swagger/index.js\",\n    \"setup-db\": \"cp db.sqlite.example db.sqlite\"\n  },\n  \"pankod\": {\n    \"project\": \"moleculer\"\n  },\n  \"keywords\": [\n    \"microservices\",\n    \"moleculer\",\n    \"typescript\",\n    \"typeorm\",\n    \"swagger\",\n    \"eslint\",\n    \"jest\",\n    \"supertest\"\n  ],\n  \"author\": \"Pankod <info@pankod.com>\",\n  \"devDependencies\": {\n    \"@pankod/pankod-cli\": \"^0.2.3\",\n    \"@types/jest\": \"^23.1.1\",\n    \"@types/node\": \"^10.12.12\",\n    \"@types/supertest\": \"^2.0.8\",\n    \"@typescript-eslint/eslint-plugin\": \"^1.9.0\",\n    \"@typescript-eslint/parser\": \"^1.9.0\",\n    \"eslint\": \"^5.16.0\",\n    \"eslint-config-prettier\": \"^4.3.0\",\n    \"eslint-plugin-prettier\": \"^3.1.0\",\n    \"jest\": \"^23.6.0\",\n    \"jest-cli\": \"^23.6.0\",\n    \"moleculer-repl\": \"^0.5.3\",\n    \"prettier\": \"^1.17.1\",\n    \"supertest\": \"^4.0.2\",\n    \"swagger-ui-express\": \"^4.0.2\",\n    \"ts-jest\": \"^23.10.5\",\n    \"ts-node\": \"^7.0.1\",\n    \"typescript\": \"^3.3.3333\"\n  },\n  \"dependencies\": {\n    \"cors\": \"^2.8.5\",\n    \"express\": \"^4.16.4\",\n    \"moleculer\": \"^0.14.5\",\n    \"moleculer-decorators\": \"^1.2.0\",\n    \"moleculer-web\": \"^0.8.0\",\n    \"nats\": \"^1.3.0\",\n    \"reflect-metadata\": \"^0.1.13\",\n    \"sqlite3\": \"^4.1.1\",\n    \"swagger-jsdoc\": \"^3.2.9\",\n    \"tsconfig-paths\": \"^3.8.0\",\n    \"typeorm\": \"^0.2.18\"\n  },\n  \"engines\": {\n    \"node\": \">= 8.x.x\"\n  },\n  \"jest\": {\n    \"coverageDirectory\": \"<rootDir>/coverage\",\n    \"testEnvironment\": \"node\",\n    \"moduleFileExtensions\": [\n      \"ts\",\n      \"js\"\n    ],\n    \"moduleNameMapper\": {\n      \"^@(Test)(.*)$\": \"<rootDir>/test/$2\",\n      \"@Entities/Connection\": \"<rootDir>/test/Config/Connection\",\n      \"^@([A-Z].*)$\": \"<rootDir>/src/$1\"\n    },\n    \"transform\": {\n      \"^.+\\\\.(ts)$\": \"ts-jest\"\n    },\n    \"testMatch\": [\n      \"**/*.spec.(ts)\"\n    ],\n    \"setupTestFrameworkScriptFile\": \"<rootDir>/test/Config/mock.setup.ts\",\n    \"globals\": {\n      \"ts-jest\": {\n        \"tsConfig\": \"<rootDir>/tsconfig.json\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<title>MoleculerJS Boilerplate | Pankod</title>\n\t\t<style>\n\t\t\tbody {\n\t\t\t\twidth: 100%;\n\t\t\t\theight: 100%;\n\t\t\t\tbackground: #000;\n\t\t\t\toverflow: hidden;\n\t\t\t}\n\n\t\t\t.fade {\n\t\t\t\tposition: relative;\n\t\t\t\twidth: 100%;\n\t\t\t\tmin-height: 60vh;\n\t\t\t\ttop: -25px;\n\t\t\t\tbackground-image: linear-gradient(0deg, transparent, black 75%);\n\t\t\t\tz-index: 1;\n\t\t\t}\n\n\t\t\t.star-wars {\n\t\t\t\tdisplay: flex;\n\t\t\t\tjustify-content: center;\n\t\t\t\tposition: relative;\n\t\t\t\theight: 800px;\n\t\t\t\tcolor: #feda4a;\n\t\t\t\tfont-family: 'Pathway Gothic One', sans-serif;\n\t\t\t\tfont-size: 500%;\n\t\t\t\tfont-weight: 600;\n\t\t\t\tletter-spacing: 6px;\n\t\t\t\tline-height: 150%;\n\t\t\t\tperspective: 500px;\n\t\t\t\ttext-align: justify;\n\t\t\t}\n\n\t\t\t.crawl {\n\t\t\t\tposition: relative;\n\t\t\t\ttop: 99999px;\n\t\t\t\ttransform-origin: 50% 100%;\n\t\t\t\tanimation: crawl 60s linear;\n\t\t\t}\n\n\t\t\t.crawl > .title {\n\t\t\t\tfont-size: 90%;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\n\t\t\t.crawl > .title h2 {\n\t\t\t\tmargin: 0 0 100px;\n\t\t\t\ttext-transform: uppercase;\n\t\t\t}\n\n\t\t\t@keyframes crawl {\n\t\t\t\t0% {\n\t\t\t\t\ttop: -100px;\n\t\t\t\t\ttransform: rotateX(20deg) translateZ(0);\n\t\t\t\t}\n\t\t\t\t100% {\n\t\t\t\t\ttop: -6000px;\n\t\t\t\t\ttransform: rotateX(25deg) translateZ(-2500px);\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"fade\"></div>\n\n\t\t<section class=\"star-wars\">\n\t\t\t<div class=\"crawl\">\n\t\t\t\t<div class=\"title\">\n\t\t\t\t\t<h2>MoleculerJS Boilerplate</h2>\n\t\t\t\t\t<p>Pankod Open Source</p>\n\t\t\t\t</div>\n\n\t\t\t\t<p>\n\t\t\t\t\tMoleculerJS Microservice Boilerplate with Typescript, TypeORM, CLI, Service\n\t\t\t\t\tHelpers, Swagger, Jest, Docker, Eslint support and everything you will ever need\n\t\t\t\t\tto deploy rock solid projects...\n\t\t\t\t</p>\n\t\t\t\t<p>\n\t\t\t\t\tA microservice is a single self-contained unit which, together with many others,\n\t\t\t\t\tmakes up a large application. By splitting your app into small units every part\n\t\t\t\t\tof it is independently deployable and scalable, can be written by different\n\t\t\t\t\tteams and in different programming languages and can be tested individually.\n\t\t\t\t</p>\n\t\t\t\t<p>\n\t\t\t\t\tMoleculer is a fast, modern and powerful microservices framework for Node.js. It\n\t\t\t\t\thelps you to build efficient, reliable & scalable services. This boilerplate\n\t\t\t\t\tmake it easier to get started with a well-structured Node.js microservices with\n\t\t\t\t\tTypescript.\n\t\t\t\t</p>\n\t\t\t\t<p>\n\t\t\t\t\tMoleculerJS boilerplate is shipped with a CLI tool to streamline the creation of\n\t\t\t\t\tnew microservices and entities. By using the CLI tool, you may easily add\n\t\t\t\t\tentities, services to your project and have all the required interfaces and\n\t\t\t\t\timports are automatically created for you.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t</section>\n\t</body>\n</html>\n"
  },
  {
    "path": "services/api.service.ts",
    "content": "//#region Global Imports\nimport { ServiceSchema } from 'moleculer';\nimport ApiGateway = require('moleculer-web');\n//#endregion Global Imports\n\nconst ApiService: ServiceSchema = {\n\tname: 'api',\n\n\tmixins: [ApiGateway],\n\n\t// More info about settings: https://moleculer.services/docs/0.13/moleculer-web.html\n\tsettings: {\n\t\tport: process.env.PORT || 3000,\n\n\t\troutes: [\n\t\t\t{\n\t\t\t\taliases: {},\n\t\t\t\tcors: {\n\t\t\t\t\tcredentials: true,\n\t\t\t\t\tmethods: ['GET', 'OPTIONS', 'POST'],\n\t\t\t\t\torigin: ['*'],\n\t\t\t\t},\n\t\t\t\tpath: '/api',\n\t\t\t},\n\t\t],\n\n\t\t// Serve assets from 'public' folder\n\t\tassets: {\n\t\t\tfolder: 'public',\n\t\t},\n\t},\n};\n\nexport = ApiService;\n"
  },
  {
    "path": "services/attack.service.ts",
    "content": "//#region Global Imports\nimport { Context, Service as MoleculerService } from 'moleculer';\nimport { Action, Method, Service } from 'moleculer-decorators';\nimport { getConnection } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { WeaponRepository } from '@Repositories';\nimport { PlanetHelper } from '@ServiceHelpers';\nimport connectionInstance from '@Entities/Connection';\n\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { IAttack } from '@Interfaces';\n//#endregion Interface Imports\n\n@Service({\n\tname: 'attack',\n})\nclass AttackService extends MoleculerService {\n\tpublic async started() {\n\t\treturn await connectionInstance();\n\t}\n\n\t@Action({\n\t\tparams: {\n\t\t\tweaponName: { type: 'string', min: 2 },\n\t\t\tplanetName: { type: 'string', min: 2 },\n\t\t},\n\t})\n\tpublic async Fire(ctx: Context<IAttack.FireInDto>): Promise<IAttack.FireOutDto> {\n\t\tconst response = await this.FireMethod(ctx);\n\n\t\treturn response;\n\t}\n\n\t@Method\n\t/**\n\t * @swagger\n\t *\n\t *  /attack/Fire:\n\t *    post:\n\t *      description: Attacks to the planet with given weapon.\n\t *      produces:\n\t *        - application/json\n\t *      consumes:\n\t *        - application/json\n\t *      parameters:\n\t *        - in: body\n\t *          name: params\n\t *          schema:\n\t *            type: object\n\t *            required:\n\t *              - weaponName\n\t *              - planetName\n\t *            properties:\n\t *              weaponName:\n\t *                type: string\n\t *                example: Death Star\n\t *              planetName:\n\t *                type: string\n\t *                example: Alderaan\n\t *      responses:\n\t *        200:\n\t *          description: Example attack result\n\t *        422:\n\t *          description: Missing parameters\n\t */\n\tpublic async FireMethod(ctx: Context<IAttack.FireInDto>): Promise<IAttack.FireOutDto> {\n\t\tconst { planetName, weaponName } = ctx.params;\n\n\t\tconst weapon = await WeaponRepository.Get(weaponName);\n\n\t\tif (weapon.ammo <= 0) {\n\t\t\treturn {\n\t\t\t\tplanetMessage: 'Planet took no damage',\n\t\t\t\tweaponMessage: 'This weapon has no ammo',\n\t\t\t};\n\t\t}\n\n\t\tconst { remainingAmmo } = await WeaponRepository.DecreaseAmmo(weaponName);\n\n\t\tconst { damage, planetMessage } = await PlanetHelper.Defend(ctx, {\n\t\t\tweaponName,\n\t\t\tplanetName,\n\t\t});\n\n\t\tconst weaponMessage = `${weapon.name} did ${damage} damage and left ${remainingAmmo} ammo.`;\n\n\t\treturn {\n\t\t\tplanetMessage,\n\t\t\tweaponMessage,\n\t\t};\n\t}\n\tpublic async stopped() {\n\t\treturn await getConnection().close();\n\t}\n}\n\nmodule.exports = AttackService;\n"
  },
  {
    "path": "services/index.ts",
    "content": "export { AttackService } from './attack.service';\nexport { PlanetService } from './planet.service';\n"
  },
  {
    "path": "services/planet.service.ts",
    "content": "//#region Global Imports\nimport { Context, Service as MoleculerService } from 'moleculer';\nimport { Action, Method, Service } from 'moleculer-decorators';\nimport { getConnection } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { PlanetRepository, WeaponRepository } from '@Repositories';\nimport { CalculateMeta } from '@Meta';\nimport { Planet, Weapon } from '@Entities';\nimport connectionInstance from '@Entities/Connection';\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { IPlanet } from '@Interfaces';\n//#endregion Interface Imports\n\n@Service({\n\tname: 'planet',\n})\nclass PlanetService extends MoleculerService {\n\tpublic async started() {\n\t\treturn await connectionInstance();\n\t}\n\n\t@Action({\n\t\tparams: {\n\t\t\tweaponName: { type: 'string', min: 2 },\n\t\t\tplanetName: { type: 'string', min: 2 },\n\t\t},\n\t})\n\tpublic async Defend(ctx: Context<IPlanet.DefendInDto>): Promise<IPlanet.DefendOutDto> {\n\t\tconst response = await this.DefendMethod(ctx);\n\n\t\treturn response;\n\t}\n\n\t@Method\n\t/**\n\t * @swagger\n\t *\n\t *  /planet/Defend:\n\t *    post:\n\t *      description: Attacks to the planet with given weapon.\n\t *      produces:\n\t *        - application/json\n\t *      consumes:\n\t *        - application/json\n\t *      parameters:\n\t *        - in: body\n\t *          name: params\n\t *          schema:\n\t *            type: object\n\t *            required:\n\t *              - weaponName\n\t *              - planetName\n\t *            properties:\n\t *              weaponName:\n\t *                type: string\n\t *                example: Death Star\n\t *              planetName:\n\t *                type: string\n\t *                example: Alderaan\n\t *      responses:\n\t *        200:\n\t *          description: Example attack result\n\t *        422:\n\t *          description: Missing parameters\n\t */\n\tpublic async DefendMethod(ctx: Context<IPlanet.DefendInDto>): Promise<IPlanet.DefendOutDto> {\n\t\tconst { planetName, weaponName } = ctx.params;\n\n\t\tconst planet: Planet = await PlanetRepository.Get(planetName);\n\t\tconst weapon: Weapon = await WeaponRepository.Get(weaponName);\n\n\t\tconst { damage, remainingShield } = await CalculateMeta.Damage(weapon, planet);\n\n\t\tawait PlanetRepository.DecreaseShield(planetName, remainingShield);\n\n\t\tlet message;\n\n\t\tif (remainingShield > 0) {\n\t\t\tmessage = `Planet took ${damage} damage and has ${remainingShield} shield left.`;\n\t\t} else {\n\t\t\tmessage = 'Planet shield ruined! war is lost!';\n\t\t}\n\n\t\treturn { damage, planetMessage: message };\n\t}\n\n\tpublic async stopped() {\n\t\treturn await getConnection().close();\n\t}\n}\n\nmodule.exports = PlanetService;\n"
  },
  {
    "path": "src/Entities/Connection.ts",
    "content": "//#region Global Imports\nimport { createConnection, Connection } from 'typeorm';\n//#endregion Global Imports\n\nexport default async (): Promise<Connection | undefined> => {\n\ttry {\n\t\treturn await createConnection({\n\t\t\ttype: 'sqlite',\n\t\t\tname: 'default',\n\t\t\tdatabase: './db.sqlite',\n\t\t\tentities: [__dirname + '/*'],\n\t\t\tsynchronize: true,\n\t\t});\n\t} catch (error) {\n\t\treturn undefined;\n\t}\n};\n"
  },
  {
    "path": "src/Entities/Planet.ts",
    "content": "//#region Global Imports\nimport { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';\n//#endregion Global Imports\n\n@Entity()\nexport class Planet {\n\t@PrimaryGeneratedColumn()\n\tid?: number;\n\n\t@Column()\n\tname: string;\n\n\t@Column()\n\tshield: number;\n\n\tconstructor(name: string, shield: number) {\n\t\tthis.name = name;\n\t\tthis.shield = shield;\n\t}\n}\n"
  },
  {
    "path": "src/Entities/Weapon.ts",
    "content": "//#region Global Imports\nimport { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';\n//#endregion Global Imports\n\n@Entity()\nexport class Weapon {\n\t@PrimaryGeneratedColumn()\n\tid?: number;\n\n\t@Column()\n\tname: string;\n\n\t@Column()\n\tdamage: number;\n\n\t@Column()\n\tammo: number;\n\n\tconstructor(name: string, damage: number, ammo: number) {\n\t\tthis.name = name;\n\t\tthis.damage = damage;\n\t\tthis.ammo = ammo;\n\t}\n}\n"
  },
  {
    "path": "src/Entities/index.ts",
    "content": "export { Planet } from './Planet';\nexport { Weapon } from './Weapon';\n"
  },
  {
    "path": "src/Interfaces/Meta/DamageMetaOutDto.d.ts",
    "content": "export interface DamageMetaOutDto {\n\tdamage: number;\n\tremainingShield: number;\n}\n"
  },
  {
    "path": "src/Interfaces/Meta/index.ts",
    "content": "export { DamageMetaOutDto } from './DamageMetaOutDto';\n"
  },
  {
    "path": "src/Interfaces/Repositories/Planet/DecreaseShieldOutDto.d.ts",
    "content": "export interface DecreaseShieldOutDto {\n\tremainingShield: number;\n}\n"
  },
  {
    "path": "src/Interfaces/Repositories/Planet/index.ts",
    "content": "export { DecreaseShieldOutDto } from './DecreaseShieldOutDto';\n"
  },
  {
    "path": "src/Interfaces/Repositories/Weapon/DecreaseAmmoOutDto.d.ts",
    "content": "export interface DecreaseAmmoOutDto {\n\tremainingAmmo: number;\n}\n"
  },
  {
    "path": "src/Interfaces/Repositories/Weapon/index.ts",
    "content": "export { DecreaseAmmoOutDto } from './DecreaseAmmoOutDto';\n"
  },
  {
    "path": "src/Interfaces/Services/Attack/IAttack.d.ts",
    "content": "export namespace IAttack {\n\texport interface FireInDto {\n\t\tplanetName: string;\n\t\tweaponName: string;\n\t}\n\n\texport interface FireOutDto {\n\t\tplanetMessage: string;\n\t\tweaponMessage: string;\n\t}\n}\n"
  },
  {
    "path": "src/Interfaces/Services/Attack/index.ts",
    "content": "export { IAttack } from './IAttack';\n"
  },
  {
    "path": "src/Interfaces/Services/Planet/IPlanet.d.ts",
    "content": "export namespace IPlanet {\n\texport interface DefendInDto {\n\t\tplanetName: string;\n\t\tweaponName: string;\n\t}\n\n\texport interface DefendOutDto {\n\t\tdamage: number;\n\t\tplanetMessage: string;\n\t}\n}\n"
  },
  {
    "path": "src/Interfaces/Services/Planet/index.ts",
    "content": "export { IPlanet } from './IPlanet';\n"
  },
  {
    "path": "src/Interfaces/index.ts",
    "content": "export * from '@Interfaces/Meta';\nexport * from '@Interfaces/Repositories/Planet';\nexport * from '@Interfaces/Repositories/Weapon';\nexport * from '@Interfaces/Services/Attack';\nexport * from '@Interfaces/Services/Planet';\n"
  },
  {
    "path": "src/Meta/CalculateMeta.ts",
    "content": "//#endregion Local Imports\nimport { Planet, Weapon } from '@Entities';\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { DamageMetaOutDto } from '@Interfaces';\n//#endregion Interface Imports\n\nexport namespace CalculateMeta {\n\texport const Damage = async (weapon: Weapon, planet: Planet): Promise<DamageMetaOutDto> => {\n\t\tconst { damage: weaponDamage } = weapon;\n\t\tconst { shield } = planet;\n\n\t\tconst damage = Math.floor(Math.random() * weaponDamage);\n\n\t\tconst remainingShield = shield - damage;\n\n\t\treturn { damage, remainingShield };\n\t};\n}\n"
  },
  {
    "path": "src/Meta/index.ts",
    "content": "export { CalculateMeta } from '@Meta/CalculateMeta';\n"
  },
  {
    "path": "src/Repositories/ErrorHelpers.ts",
    "content": "//#region Global Imports\nimport { Errors } from 'moleculer';\n//#endregion Global Imports\n\nexport const Throw404 = <R extends {}>(resource: R | undefined, message: string): R => {\n\tif (!resource) {\n\t\tthrow new Errors.MoleculerError(message, 404, 'Not Found');\n\t}\n\treturn resource;\n};\n"
  },
  {
    "path": "src/Repositories/Planet.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Planet } from '@Entities/Planet';\nimport { getResource } from './Shared';\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { DecreaseShieldOutDto } from '@Interfaces';\n//#endregion Interface Imports\n\nexport namespace PlanetRepository {\n\texport const Get = async (planetName: string): Promise<Planet> => {\n\t\treturn await getResource(Planet, { where: { name: planetName } });\n\t};\n\n\texport const DecreaseShield = async (\n\t\tplanetName: string,\n\t\tremainingShield: number,\n\t): Promise<DecreaseShieldOutDto> => {\n\t\tconst planet = await getResource(Planet, { where: { name: planetName } });\n\n\t\tplanet.shield = remainingShield;\n\n\t\tawait getManager().save(planet);\n\n\t\treturn { remainingShield: planet.shield };\n\t};\n}\n"
  },
  {
    "path": "src/Repositories/Shared.ts",
    "content": "//#region Global Imports\nimport { getManager, ObjectType } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Throw404 } from './ErrorHelpers';\n//#endregion Local Imports\n\nexport const getResource = async <E extends {}>(\n\tentityClass: ObjectType<E>,\n\toptions: {},\n): Promise<E> => {\n\tconst resource = await getManager().findOne(entityClass, options);\n\n\tThrow404(resource, `Resource can't be found with options: ${JSON.stringify(options)}`);\n\n\treturn resource as E;\n};\n"
  },
  {
    "path": "src/Repositories/Weapon.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Weapon } from '@Entities/Weapon';\nimport { getResource } from './Shared';\n//#endregion Local Imports\n\n//#region Interfaces Imports\nimport { DecreaseAmmoOutDto } from '@Interfaces';\n//#endregion Interfaces Imports\n\nexport namespace WeaponRepository {\n\texport const Get = async (weaponName: string): Promise<Weapon> => {\n\t\treturn await getResource(Weapon, { where: { name: weaponName } });\n\t};\n\n\texport const DecreaseAmmo = async (weaponName: string): Promise<DecreaseAmmoOutDto> => {\n\t\tconst weapon = await getResource(Weapon, { where: { name: weaponName } });\n\n\t\tweapon.ammo = weapon.ammo - 1;\n\n\t\tgetManager().save(weapon);\n\n\t\treturn { remainingAmmo: weapon.ammo };\n\t};\n}\n"
  },
  {
    "path": "src/Repositories/index.ts",
    "content": "export { WeaponRepository } from '@Repositories/Weapon';\nexport { PlanetRepository } from '@Repositories/Planet';\n"
  },
  {
    "path": "src/ServiceHelpers/AttackHelper.ts",
    "content": "//#region Global Imports\nimport { Context } from 'moleculer';\n//#endregion Global Imports\n\n//#region Interface Imports\nimport { IAttack } from '@Interfaces';\n//#endregion Interface Imports\n\nexport namespace AttackHelper {\n\tconst prefix: string = 'attack';\n\n\texport const Fire = async (\n\t\tctx: Context,\n\t\tparams: IAttack.FireInDto,\n\t): Promise<IAttack.FireOutDto> => await ctx.call(`${prefix}.Fire`, params);\n}\n"
  },
  {
    "path": "src/ServiceHelpers/PlanetHelper.ts",
    "content": "//#region Global Imports\nimport { Context } from 'moleculer';\n//#endregion Global Imports\n\n//#region Interface Imports\nimport { IPlanet } from '@Interfaces';\n//#endregion Interface Imports\n\nexport namespace PlanetHelper {\n\tconst prefix: string = 'planet';\n\n\texport const Defend = async (\n\t\tctx: Context,\n\t\tparams: IPlanet.DefendInDto,\n\t): Promise<IPlanet.DefendOutDto> => await ctx.call(`${prefix}.Defend`, params);\n}\n"
  },
  {
    "path": "src/ServiceHelpers/index.ts",
    "content": "export { AttackHelper } from '@ServiceHelpers/AttackHelper';\nexport { PlanetHelper } from '@ServiceHelpers/PlanetHelper';\n"
  },
  {
    "path": "swagger/config.js",
    "content": "const swaggerJSDoc = require('swagger-jsdoc');\n\nconst swaggerDefinition = {\n\tinfo: {\n\t\ttitle: 'Pankod MoleculerJS Boilerplate', // Title of the documentation\n\t\tversion: '1.0.0', // Version of the app\n\t\tdescription:\n\t\t\t'Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Clients, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects..', // short description of the app\n\t},\n\thost: 'localhost:3000', // the host or url of the app\n\tbasePath: '/api', // the basepath of your endpoint\n};\n\n// options for the swagger docs\nconst options = {\n\t// import swaggerDefinitions\n\tdefinition: swaggerDefinition,\n\texplorer: true,\n\n\t// path to the API docs\n\tapis: ['./*.service.ts'],\n};\n// initialize swagger-jsdoc\nconst swaggerSpec = swaggerJSDoc(options);\n\nmodule.exports = swaggerSpec;\n"
  },
  {
    "path": "swagger/index.js",
    "content": "const express = require('express');\nconst swaggerUi = require('swagger-ui-express');\nconst cors = require('cors');\nconst bodyParser = require('body-parser');\n\nconst swaggerFile = require('./swagger.json');\nconst app = express();\n\napp.use(function (req, res, next) {\n\tres.header(\"Access-Control-Allow-Origin\", \"*\");\n\tres.header(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization, Accept\");\n\tres.header('Access-Control-Allow-Credentials', 'true');\n\tnext();\n});\n\napp.use(cors());\napp.use(bodyParser.json()); // support json encoded bodies\napp.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies\n\nconst PORT = 3001;\n\nconst options = {\n\texplorer: true,\n\tenableCORS: false\n};\n\napp.use('/', swaggerUi.serve, swaggerUi.setup(swaggerFile, options));\n\napp.listen(PORT, () =>\n\tconsole.log(`swagger ui listening on port ${PORT}!`),\n);"
  },
  {
    "path": "swagger/package.json",
    "content": "{\n\t\"main\": \"index.js\"\n}"
  },
  {
    "path": "swagger/swagger.json",
    "content": "{\n  \"info\": {\n    \"title\": \"Pankod MoleculerJS Boilerplate\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Moleculer JS Microservice Boilerplate with Typescript, TypeORM, CLI, Service Clients, Swagger, Jest, Docker, Eslint support and everything you will ever need to deploy rock solid projects..\"\n  },\n  \"host\": \"localhost:3000\",\n  \"basePath\": \"/api\",\n  \"swagger\": \"2.0\",\n  \"paths\": {\n    \"/attack/Fire\": {\n      \"post\": {\n        \"description\": \"Attacks to the planet with given weapon.\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"parameters\": [\n          {\n            \"in\": \"body\",\n            \"name\": \"params\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"weaponName\",\n                \"planetName\"\n              ],\n              \"properties\": {\n                \"weaponName\": {\n                  \"type\": \"string\",\n                  \"example\": \"Death Star\"\n                },\n                \"planetName\": {\n                  \"type\": \"string\",\n                  \"example\": \"Alderaan\"\n                }\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Example attack result\"\n          },\n          \"422\": {\n            \"description\": \"Missing parameters\"\n          }\n        }\n      }\n    },\n    \"/planet/Defend\": {\n      \"post\": {\n        \"description\": \"Attacks to the planet with given weapon.\",\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"parameters\": [\n          {\n            \"in\": \"body\",\n            \"name\": \"params\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"weaponName\",\n                \"planetName\"\n              ],\n              \"properties\": {\n                \"weaponName\": {\n                  \"type\": \"string\",\n                  \"example\": \"Death Star\"\n                },\n                \"planetName\": {\n                  \"type\": \"string\",\n                  \"example\": \"Alderaan\"\n                }\n              }\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Example attack result\"\n          },\n          \"422\": {\n            \"description\": \"Missing parameters\"\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {},\n  \"responses\": {},\n  \"parameters\": {},\n  \"securityDefinitions\": {},\n  \"tags\": []\n}"
  },
  {
    "path": "swaggerConfig.json",
    "content": "{\n\t\"swagger\": {\n\t\t\"baseUrl\": \"./\",\n\t\t\"outputDirectory\": \"./swagger\",\n\t\t\"entryFile\": \"./services/index.ts\",\n\t\t\"host\": \"localhost:3000\",\n\t\t\"basePath\": \"/api\",\n\t\t\"securityDefinitions\": {\n\t\t\t\"api_key\": {\n\t\t\t\t\"type\": \"apiKey\",\n\t\t\t\t\"name\": \"access_token\",\n\t\t\t\t\"in\": \"query\"\n\t\t\t},\n\t\t\t\"tsoa_auth\": {\n\t\t\t\t\"type\": \"oauth2\",\n\t\t\t\t\"authorizationUrl\": \"http://swagger.io/api/oauth/dialog\",\n\t\t\t\t\"flow\": \"implicit\",\n\t\t\t\t\"scopes\": {\n\t\t\t\t\t\"write:pets\": \"modify things\",\n\t\t\t\t\t\"read:pets\": \"read things\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"yaml\": true\n\t}\n}"
  },
  {
    "path": "test/Config/Connection.ts",
    "content": "//#region Global Imports\nimport { createConnection, Connection } from 'typeorm';\n//#region Global Imports\n\nexport default async (): Promise<Connection | undefined> => {\n\ttry {\n\t\treturn await createConnection({\n\t\t\ttype: 'sqlite',\n\t\t\tname: 'default',\n\t\t\tdatabase: ':memory:',\n\t\t\tentities: ['./src/Entities/*.ts'],\n\t\t\tsynchronize: true,\n\t\t\tdropSchema: true,\n\t\t});\n\t} catch (error) {\n\t\treturn undefined;\n\t}\n};\n"
  },
  {
    "path": "test/Config/SetupDatabase.ts",
    "content": "//#region Local Imports\nimport Seeder from '../Seeder';\nimport CreateConnection from './Connection';\n//#region Local Imports\n\nconst setupDatabase = async (): Promise<void> => {\n\tawait CreateConnection();\n\n\tawait Seeder.seed();\n};\n\nexport default setupDatabase;\n"
  },
  {
    "path": "test/Config/mock.setup.ts",
    "content": ""
  },
  {
    "path": "test/Integration/attack.spec.ts",
    "content": "//#region Global Imports\nimport ApiGateway = require('moleculer-web');\nimport { getConnection } from 'typeorm';\nimport request from 'supertest';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { BrokerHelper } from '@Test/Utils';\nimport * as supertest from 'supertest';\n//#endregion Local Imports\n\nconst broker = BrokerHelper.setupBroker();\nlet server: {};\n\nbeforeEach(async () => {\n\tawait setupDatabase();\n});\n\nafterEach(async () => {\n\tawait getConnection().close();\n});\n\nbeforeAll(async () => {\n\tconst service = broker.createService(ApiGateway);\n\tserver = service.server;\n\treturn broker.start();\n});\n\nafterAll(async () => broker.stop());\n\ndescribe('Test Attack service requests', () => {\n\tit('Test POST request on attack service Fire method', async () => {\n\t\tconst params = {\n\t\t\tplanetName: 'Alderaan',\n\t\t\tweaponName: 'Death Star',\n\t\t};\n\n\t\treturn request(server)\n\t\t\t.post('/attack/Fire')\n\t\t\t.query({ ...params })\n\t\t\t.then((res: supertest.Response) => {\n\t\t\t\texpect(res.status).toBe(200);\n\t\t\t\texpect(res.header['content-type']).toBe('application/json; charset=utf-8');\n\t\t\t\texpect(res.body.planetMessage).toContain('Planet took');\n\t\t\t\texpect(res.body.weaponMessage).toContain('Death Star did');\n\t\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/Integration/planet.spec.ts",
    "content": "//#region Global Imports\nimport ApiGateway = require('moleculer-web');\nimport { getConnection } from 'typeorm';\nimport request from 'supertest';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { BrokerHelper } from '@Test/Utils';\nimport * as supertest from 'supertest';\n//#endregion Local Imports\n\nconst broker = BrokerHelper.setupBroker();\nlet server: {};\n\nbeforeEach(async () => {\n\tawait setupDatabase();\n});\n\nafterEach(async () => {\n\tawait getConnection().close();\n});\n\nbeforeAll(async () => {\n\tconst service = broker.createService(ApiGateway);\n\tserver = service.server;\n\treturn broker.start();\n});\n\nafterAll(async () => broker.stop());\n\ndescribe('Test Planet service requests', () => {\n\tit('Test POST request on planet service Defend method', async () => {\n\t\tconst params = {\n\t\t\tplanetName: 'Alderaan',\n\t\t\tweaponName: 'Death Star',\n\t\t};\n\n\t\treturn request(server)\n\t\t\t.post('/planet/Defend')\n\t\t\t.query({ ...params })\n\t\t\t.then((res: supertest.Response) => {\n\t\t\t\texpect(res.status).toBe(200);\n\t\t\t\texpect(res.header['content-type']).toBe('application/json; charset=utf-8');\n\t\t\t\texpect(res.body.planetMessage).toContain('Planet took');\n\t\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/Seeder/AttackSeeder.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Weapon } from '@Entities/Weapon';\n//#region Local Imports\n\nconst seed = async (): Promise<void> => {\n\tconst entityManager = getManager();\n\tawait entityManager.insert(Weapon, { name: 'Death Star', ammo: 1000, damage: 1000 });\n};\n\nexport default {\n\tseed,\n};\n"
  },
  {
    "path": "test/Seeder/PlanetSeeder.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#region Global Imports\n\n//#region Local Imports\nimport { Planet } from '@Entities/Planet';\n//#region Local Imports\n\nconst seed = async (): Promise<void> => {\n\tconst entityManager = getManager();\n\tawait entityManager.insert(Planet, { name: 'Alderaan', shield: 100000 });\n};\n\nexport default {\n\tseed,\n};\n"
  },
  {
    "path": "test/Seeder/index.ts",
    "content": "//#region Local Imports\nimport PlanetSeeder from './PlanetSeeder';\nimport AttackSeeder from './AttackSeeder';\n//#region Local Imports\n\nconst seed = async (): Promise<void> => {\n\tawait PlanetSeeder.seed();\n\tawait AttackSeeder.seed();\n};\n\nexport default {\n\tseed,\n};\n"
  },
  {
    "path": "test/Unit/Entities/Connection.spec.ts",
    "content": "import CreateConnection from '../../../src/Entities/Connection';\nimport { Connection, getConnection } from 'typeorm';\n\ndescribe('Connection', async () => {\n\tit('should return connection and connect', async () => {\n\t\tconst connection = await CreateConnection();\n\n\t\texpect(connection).toBeInstanceOf(Connection);\n\t\texpect(getConnection().isConnected).toBe(true);\n\t});\n\n\tit('should not fail for 2nd connection', async () => {\n\t\tawait CreateConnection();\n\n\t\texpect(async () => await CreateConnection()).not.toThrow();\n\t});\n});\n"
  },
  {
    "path": "test/Unit/Meta/CalculateMeta.spec.ts",
    "content": "//#region Global Imports\nimport { getManager, getConnection } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { CalculateMeta } from '@Meta';\nimport { Planet, Weapon } from '@Entities';\n//#endregion Local Imports\n\ndescribe('CalculateMeta constructor', () => {\n\tit('should be defined', () => {\n\t\texpect(CalculateMeta).toBeDefined();\n\t});\n});\n\ndescribe('CalculateMeta functions', () => {\n\tbeforeEach(async () => {\n\t\tawait setupDatabase();\n\t});\n\n\tafterEach(async () => {\n\t\tawait getConnection().close();\n\t});\n\n\tit('should calculate remaining shield', async () => {\n\t\tconst entityManager = getManager();\n\n\t\tconst weapon = await entityManager.findOne(Weapon, { where: { name: 'Death Star' } });\n\t\tconst planet = await entityManager.findOne(Planet, { where: { name: 'Alderaan' } });\n\n\t\tconst { damage, remainingShield } = await CalculateMeta.Damage(weapon!, planet!);\n\n\t\texpect(remainingShield).toEqual(planet!.shield - damage);\n\t});\n});\n"
  },
  {
    "path": "test/Unit/MicroServices/attack.spec.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { AttackHelper } from '@ServiceHelpers';\nimport { Weapon } from '@Entities';\nimport { BrokerHelper } from '@Test/Utils';\nimport { IAttack } from '@Interfaces';\n//#endregion Local Imports\n\nconst broker = BrokerHelper.setupBroker();\n\nbeforeEach(async () => {\n\tawait broker.start();\n\tawait setupDatabase();\n});\n\nafterEach(async () => {\n\tawait broker.stop();\n});\n\ndescribe('Test attack service', () => {\n\tconst params: IAttack.FireInDto = {\n\t\tplanetName: 'Alderaan',\n\t\tweaponName: 'Death Star',\n\t};\n\n\tdescribe('Fire method', async () => {\n\t\tit('when ammo is up', async () => {\n\t\t\t// eslint-disable-next-line\n\t\t\tconst { planetMessage, weaponMessage } = await AttackHelper.Fire(broker as any, params);\n\n\t\t\texpect(planetMessage).toContain('Planet took');\n\t\t\texpect(weaponMessage).toContain('Death Star did');\n\t\t});\n\n\t\tit('when ammo is empty', async () => {\n\t\t\tgetManager().update(Weapon, { name: 'Death Star' }, { ammo: 0 });\n\n\t\t\t// eslint-disable-next-line\n\t\t\tconst { planetMessage, weaponMessage } = await AttackHelper.Fire(broker as any, params);\n\n\t\t\texpect(planetMessage).toEqual('Planet took no damage');\n\t\t\texpect(weaponMessage).toEqual('This weapon has no ammo');\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/Unit/MicroServices/planet.spec.ts",
    "content": "//#region Global Imports\nimport { getManager } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { PlanetHelper } from '@ServiceHelpers';\nimport { Planet } from '@Entities/Planet';\nimport { BrokerHelper } from '@Test/Utils';\nimport { IPlanet } from '@Interfaces';\n//#endregion Local Imports\n\nconst broker = BrokerHelper.setupBroker();\n\nbeforeEach(async () => {\n\tawait broker.start();\n\tawait setupDatabase();\n});\n\nafterEach(async () => {\n\tawait broker.stop();\n});\n\ndescribe('Test Defend service', () => {\n\tdescribe('Defend method', async () => {\n\t\tconst params: IPlanet.DefendInDto = {\n\t\t\tplanetName: 'Alderaan',\n\t\t\tweaponName: 'Death Star',\n\t\t};\n\n\t\tit('when shield is up', async () => {\n\t\t\t// eslint-disable-next-line\n\t\t\tconst { planetMessage } = await PlanetHelper.Defend(broker as any, params);\n\n\t\t\texpect(planetMessage).toContain('Planet took');\n\t\t});\n\n\t\tit('when shield is down', async () => {\n\t\t\tgetManager().update(Planet, { name: 'Alderaan' }, { shield: 1 });\n\n\t\t\t/* eslint-disable */\n\t\t\t// First fire to break shield entirely\n\t\t\tawait PlanetHelper.Defend(broker as any, params);\n\t\t\tconst { planetMessage } = await PlanetHelper.Defend(broker as any, params);\n\t\t\t/* eslint-enable */\n\n\t\t\texpect(planetMessage).toEqual('Planet shield ruined! war is lost!');\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/Unit/Repositories/ErrorHelpers.spec.ts",
    "content": "//#region Global Imports\nimport { Errors } from 'moleculer';\n//#endregion Global Imports\n\n//#region Local Imports\nimport { Throw404 } from '@Repositories/ErrorHelpers';\n//#endregion Local Imports\n\ndescribe('Throw 404', () => {\n\tit('should be defined', () => {\n\t\texpect(Throw404).toBeDefined();\n\t});\n\n\tit('shouldnt throw error if resource is present', () => {\n\t\texpect(() => Throw404({ resource: 'test' }, 'Test Error')).not.toThrow();\n\t});\n\n\tit('should throw error when resource not present', () => {\n\t\texpect(() => Throw404(undefined, 'Test Error')).toThrowError(Errors.MoleculerError);\n\t});\n});\n"
  },
  {
    "path": "test/Unit/Repositories/Planet.spec.ts",
    "content": "//#region Global Imports\nimport { getConnection } from 'typeorm';\n//#endregion Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { PlanetRepository } from '@Repositories';\n//#endregion Local Imports\n\ndescribe('Planet Repository Constructor', () => {\n\tit('should be defined', () => {\n\t\texpect(PlanetRepository).toBeDefined();\n\t});\n});\n\ndescribe('Planet Repository Methods', () => {\n\tbeforeEach(async () => {\n\t\tawait setupDatabase();\n\t});\n\n\tafterEach(async () => {\n\t\tawait getConnection().close();\n\t});\n\n\tdescribe('Get', () => {\n\t\tit('should get planet if there is any', async () => {\n\t\t\tconst planetName = 'Alderaan';\n\n\t\t\tconst planet = await PlanetRepository.Get(planetName);\n\n\t\t\texpect(planet.name).toEqual(planetName);\n\t\t});\n\n\t\tit('should raise error', async () => {\n\t\t\tconst planetName = 'I dont exist';\n\n\t\t\texpect(async () => PlanetRepository.Get(planetName)).toThrowError;\n\t\t});\n\t});\n\n\tit('should update shield', async () => {\n\t\tconst planetName = 'Alderaan';\n\n\t\tconst expectedShield = 1000;\n\n\t\tconst { remainingShield } = await PlanetRepository.DecreaseShield(\n\t\t\tplanetName,\n\t\t\texpectedShield,\n\t\t);\n\n\t\texpect(remainingShield).toEqual(expectedShield);\n\t});\n});\n"
  },
  {
    "path": "test/Unit/Repositories/Weapon.spec.ts",
    "content": "//#region Global Imports\nimport { getManager, getConnection } from 'typeorm';\n//#region Global Imports\n\n//#region Local Imports\nimport setupDatabase from '@Test/Config/SetupDatabase';\nimport { WeaponRepository } from '@Repositories';\nimport { Weapon } from '@Entities';\n//#endregion Local Imports\n\ndescribe('Test WeaponRepository constructor', () => {\n\tit('should be defined', () => {\n\t\texpect(WeaponRepository).toBeDefined();\n\t});\n});\n\ndescribe('Weapon Repository Methods', () => {\n\tbeforeEach(async () => {\n\t\tawait setupDatabase();\n\t});\n\n\tafterEach(async () => {\n\t\tawait getConnection().close();\n\t});\n\n\tdescribe('GetWeapon', async () => {\n\t\tit('should get weapon', async () => {\n\t\t\tconst weaponName = 'Death Star';\n\n\t\t\tconst weapon = await WeaponRepository.Get(weaponName);\n\n\t\t\texpect(weapon.name).toEqual(weaponName);\n\t\t});\n\n\t\tit('should throw an error if weapon not found', async () => {\n\t\t\tconst weaponName = `I don't exist`;\n\n\t\t\tawait expect(WeaponRepository.Get(weaponName)).rejects.toThrow(\n\t\t\t\t'{\"name\":\"I don\\'t exist\"}',\n\t\t\t);\n\t\t});\n\t});\n\n\tit('Decrease Ammo', async () => {\n\t\tconst entityManager = getManager();\n\n\t\tconst weaponName = 'Death Star';\n\t\tconst weapon = await entityManager.findOne(Weapon, { where: { name: weaponName } });\n\n\t\tconst expectedAmmo = weapon!.ammo - 1;\n\n\t\tconst { remainingAmmo } = await WeaponRepository.DecreaseAmmo(weaponName);\n\n\t\texpect(remainingAmmo).toEqual(expectedAmmo);\n\t});\n});\n"
  },
  {
    "path": "test/Unit/ServiceHelpers/AttackHelper.spec.ts",
    "content": "//#region Local Imports\nimport { AttackHelper } from '@ServiceHelpers';\nimport { DummyContext } from '@Test/Utils';\n//#endregion Local Imports\n\n//#region Interface Imports\nimport { IAttack } from '@Interfaces';\n//#region Interface Imports\n\ndescribe('Weapon helper service helper constructor', () => {\n\tit('should be defined', async () => {\n\t\texpect(AttackHelper).toBeDefined();\n\t});\n});\n\ndescribe('Weapon service helpers', () => {\n\tit('should trigger Fire method', async () => {\n\t\tconst params: IAttack.FireInDto = {\n\t\t\tweaponName: 'Death Star',\n\t\t\tplanetName: 'Alderaan',\n\t\t};\n\n\t\tconst result = await AttackHelper.Fire(DummyContext.getCall(params), params);\n\n\t\texpect(result).toBeDefined();\n\t});\n});\n"
  },
  {
    "path": "test/Unit/ServiceHelpers/PlanetHelper.spec.ts",
    "content": "//#region Local Imports\nimport { PlanetHelper } from '@ServiceHelpers';\nimport { DummyContext } from '@Test/Utils';\n//#region Local Imports\n\n//#region Interface Imports\nimport { IPlanet } from '@Interfaces';\n//#region Interface Imports\n\ndescribe('Planet service helper constructor', () => {\n\tit('should be defined', async () => {\n\t\texpect(PlanetHelper).toBeDefined();\n\t});\n});\n\ndescribe('Planet service helpers', () => {\n\tit('should trigger Defend method', async () => {\n\t\tconst params: IPlanet.DefendInDto = {\n\t\t\tweaponName: 'Death Star',\n\t\t\tplanetName: 'Alderaan',\n\t\t};\n\n\t\tconst result = await PlanetHelper.Defend(DummyContext.getCall(params), params);\n\n\t\texpect(result).toBeDefined();\n\t});\n});\n"
  },
  {
    "path": "test/Utils/BrokerHelper.ts",
    "content": "//#region Global Imports\nimport { ServiceBroker } from 'moleculer';\n//#endregion Global Imports\n\n/* eslint-disable */\n//#region Local Imports\nconst AttackService = require('../../services/attack.service');\nconst PlanetService = require('../../services/planet.service');\n//#endregion Local Imports\n/* eslint-enable */\n\nexport namespace BrokerHelper {\n\texport const setupBroker = () => {\n\t\tconst broker = new ServiceBroker({ logger: false });\n\n\t\tbroker.createService(AttackService);\n\t\tbroker.createService(PlanetService);\n\n\t\treturn broker;\n\t};\n}\n"
  },
  {
    "path": "test/Utils/DummyContext.spec.ts",
    "content": "import { DummyContext } from './DummyContext';\nimport { Context } from 'moleculer';\n\ndescribe('Dummy Context', async () => {\n\tit('should define getCall', async () => {\n\t\tconst ctx = DummyContext.getCall({});\n\n\t\texpect(ctx).toBeInstanceOf(Context);\n\t\texpect(ctx.call).toBeDefined();\n\t\texpect(await ctx.call('test', {})).toEqual({});\n\t});\n});\n"
  },
  {
    "path": "test/Utils/DummyContext.ts",
    "content": "//#region Global Imports\nimport { Context, Endpoint, ServiceBroker } from 'moleculer';\n//#endregion Global Imports\n\nexport namespace DummyContext {\n\tconst broker = new ServiceBroker({ logger: false, maxCallLevel: 5 });\n\n\tconst endpoint: Endpoint = {\n\t\tbroker,\n\t\tid: 'server-123',\n\t\tnode: {},\n\t\tlocal: true,\n\t\tstate: false,\n\t};\n\n\texport const getCall = (data: object) => {\n\t\tconst ctx = Context.create(broker, endpoint, data);\n\t\t// eslint-disable-next-line\n\t\tctx.call = jest.fn(async () => (broker.Promise as any).resolve({}));\n\n\t\treturn ctx;\n\t};\n}\n"
  },
  {
    "path": "test/Utils/index.ts",
    "content": "export { DummyContext } from './DummyContext';\nexport { BrokerHelper } from './BrokerHelper';\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"experimentalDecorators\": true,\n\t\t\"emitDecoratorMetadata\": true,\n\t\t\"esModuleInterop\": true,\n\t\t\"noImplicitAny\": true,\n\t\t\"noImplicitReturns\": true,\n\t\t\"noImplicitThis\": true,\n\t\t\"strict\": true,\n\t\t\"module\": \"commonjs\",\n\t\t\"pretty\": true,\n\t\t\"types\": [\n\t\t\t\"jest\",\n\t\t\t\"node\"\n\t\t],\n\t\t\"outDir\": \"dist\",\n\t\t\"sourceMap\": true,\n\t\t\"target\": \"es6\",\n\t\t\"allowJs\": true,\n\t\t\"baseUrl\": \".\",\n\t\t\"paths\": {\n\t\t\t\"@MicroServices/*\": [\n\t\t\t\t\"services/*\"\n\t\t\t],\n\t\t\t\"@MicroServices\": [\n\t\t\t\t\"services\"\n\t\t\t],\n\t\t\t\"@Interfaces/*\": [\n\t\t\t\t\"src/Interfaces/*\"\n\t\t\t],\n\t\t\t\"@Interfaces\": [\n\t\t\t\t\"src/Interfaces\"\n\t\t\t],\n\t\t\t\"@Repositories/*\": [\n\t\t\t\t\"src/Repositories/*\"\n\t\t\t],\n\t\t\t\"@Repositories\": [\n\t\t\t\t\"src/Repositories\"\n\t\t\t],\n\t\t\t\"@ServiceHelpers/*\": [\n\t\t\t\t\"src/ServiceHelpers/*\"\n\t\t\t],\n\t\t\t\"@ServiceHelpers\": [\n\t\t\t\t\"src/ServiceHelpers\"\n\t\t\t],\n\t\t\t\"@Meta/*\": [\n\t\t\t\t\"src/Meta/*\"\n\t\t\t],\n\t\t\t\"@Meta\": [\n\t\t\t\t\"src/Meta\"\n\t\t\t],\n\t\t\t\"@Entities/*\": [\n\t\t\t\t\"src/Entities/*\"\n\t\t\t],\n\t\t\t\"@Entities\": [\n\t\t\t\t\"src/Entities\"\n\t\t\t],\n\t\t\t\"@Test/*\": [\n\t\t\t\t\"test/*\"\n\t\t\t],\n\t\t\t\"@Test\": [\n\t\t\t\t\"test\"\n\t\t\t]\n\t\t}\n\t},\n\t\"exclude\": [\n\t\t\"node_modules\"\n\t],\n\t\"include\": [\n\t\t\"./src/**/*.ts\",\n\t\t\"./services/**/*.ts\",\n\t\t\"./test/**/*.ts\"\n\t]\n}\n"
  },
  {
    "path": "tsconfig.production.json",
    "content": "{\n\t\"extends\": \"./tsconfig\",\n\t\"compilerOptions\": {\n\t\t\"baseUrl\": \"./dist\",\n\t},\n}\n"
  }
]