[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: 🐞 Bug\nabout: File a bug/issue\ntitle: '[BUG] <title>'\nlabels: Bug, Needs Triage\nassignees: ''\n\n---\n\n<!--\nNote: Please search to see if an issue already exists for the bug you encountered.\n-->\n\n### Current Behavior:\n<!-- A concise description of what you're experiencing. -->\n\n### Expected Behavior:\n<!-- A concise description of what you expected to happen. -->\n\n### Steps To Reproduce:\n<!--\nExample: steps to reproduce the behavior:\n1. In this environment...\n2. With this config...\n3. Run '...'\n4. See error...\n-->\n\n### Environment:\n<!--\nExample:\n- OS: Ubuntu 20.04\n- Node: 13.14.0\n- npm: 7.6.3\n-->\n\n### Anything else:\n<!--\nLinks? References? Anything that will give us more context about the issue that you are encountering!\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/eslint.yml",
    "content": "name: Check ESLint on Pull Request\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  fix:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out Git repository\n        uses: actions/checkout@v2\n      - name: installing eslint \n        run: npm i -g eslint && npm run install --force\n      - name: Fixing Files\n        run: eslint . --ext .js --fix\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\npackage-lock.json\n.history"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.3.1](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.3.0...v1.3.1) (2022-09-28)\n\n\n### Bug Fixes\n\n* **server:** missing constant ([eeccc59](https://github.com/DhiWise/dhiwise-nodejs/commit/eeccc59c8890d3f43ff6e36d243659c27158f7f8))\n\n\n\n\n\n# [1.3.0](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.2.0...v1.3.0) (2022-04-25)\n\n\n### Bug Fixes\n\n* **Clean Code Sequelize:** bug Fixes for Clean code sequelize ([fc7ba02](https://github.com/DhiWise/dhiwise-nodejs/commit/fc7ba024dae562f758f89dac6fada9bf04d52809))\n* **clean-code:** ejs variable updated ([44f91af](https://github.com/DhiWise/dhiwise-nodejs/commit/44f91afd4bd249d2ae528acd1b56a7e2909e02b4))\n* **eslint fixes:** eslint rules violation removed ([7682a2a](https://github.com/DhiWise/dhiwise-nodejs/commit/7682a2af8031955655e5c943be580fb18f2cce5a))\n* **file upload in cc:** fix file upload in controller of cc ([387562a](https://github.com/DhiWise/dhiwise-nodejs/commit/387562a1b9ecc6636200c6c9fb7d56451a0c5878))\n* **file-upload-cc:** steps added ([f06995e](https://github.com/DhiWise/dhiwise-nodejs/commit/f06995e53f9eb75c63bc54da5f61b9e7d3e5bdb0))\n* **minor bug fixes:** - ([876f01a](https://github.com/DhiWise/dhiwise-nodejs/commit/876f01aea94c8f803030554fd123c9aa4654555b))\n* **model data save warning:** when model data change and change the model without save ask warning p ([791f20f](https://github.com/DhiWise/dhiwise-nodejs/commit/791f20fc716e3acba8271ca6109e36b460848d09))\n* **overlay issue no able to click:** propstypes forbidden remove and overlay issue fix ([3abc5fa](https://github.com/DhiWise/dhiwise-nodejs/commit/3abc5fab37b580789691effb46231cbb9dd1c760)), closes [#27](https://github.com/DhiWise/dhiwise-nodejs/issues/27)\n* **Remove configuration tab in routes:** file upload - removal form custom routes ([98a7e54](https://github.com/DhiWise/dhiwise-nodejs/commit/98a7e540e5bface7478edf1940914df4e53ef42e))\n\n\n### Features\n\n* **Clean-code file uplaod:** file upload use-cases added for clean-code architecture ([af56105](https://github.com/DhiWise/dhiwise-nodejs/commit/af5610501d7d98897ab02115873c76ee9f75b4bc))\n* **Clean-code mongoose:** comments added ([c6b432c](https://github.com/DhiWise/dhiwise-nodejs/commit/c6b432cf69dbe0ff58745f554af92e9d04129473))\n* **server:** custom routes with query builder for mvc architecture ([6949d44](https://github.com/DhiWise/dhiwise-nodejs/commit/6949d441687cdb2a23b76f580a0b88f408663678))\n\n\n\n\n\n# [1.2.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.1.0...v1.2.0) (2022-02-02)\n\n\n### Bug Fixes\n\n* **bug fixes and code enhancement:** fixed some issues ([501675e](https://github.com/DhiWise/nodejs-code-generator/commit/501675e7f528d79a5cb4e84c5d24a4562e74fe2d))\n\n\n### Features\n\n* **custom routes in clean-code architecture with use case:** custom routes with query builder added ([f38092d](https://github.com/DhiWise/nodejs-code-generator/commit/f38092d1790f21a562403a6c1638245c846665ee))\n* **use-case added in clean code architecture:** a service layer in clean code architecture ([e7cbfc4](https://github.com/DhiWise/nodejs-code-generator/commit/e7cbfc4f15956d7b2343eb6275fcea6beaf0fa40))\n\n\n\n\n\n# [1.1.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.0.0...v1.1.0) (2022-01-11)\n\n\n### Bug Fixes\n\n* **eslint formatting:** resolved eslint errors ([2c71bf2](https://github.com/DhiWise/nodejs-code-generator/commit/2c71bf2661c5e1599de3cb242b5431dce8720137))\n\n\n### Features\n\n* add confirmation popup when second time build application ([a7fe3c0](https://github.com/DhiWise/nodejs-code-generator/commit/a7fe3c001fab1972a8f2f151feb6deb18220c3e5)), closes [#20](https://github.com/DhiWise/nodejs-code-generator/issues/20)\n"
  },
  {
    "path": "CLEAN_CODE.md",
    "content": "# NodeJS,Express Project in Clean-Code Architecture with Mongoose/Sequelize\n\n**supported version of nodejs > 12**,\n**supported version of mongoose-4.0**,\n**supported version of sequelize-6.6.5**\n\n## About \n- This is a Node application, developed in Clean-code architecture with Node.js, ExpressJS.\n\n## How to run\n1. ```$ npm install```\n2. ```$ npm start```\n\n## Folder structure:\n```\n  ├── app.js              - starting point of the application\n  ├── config\t\t\t        - application configuration files\n  ├── constants           - contains commonly used constants \n  ├── controller          - contains business logic \n  ├── entity              - entity of models\n  ├── helper              - helper files\n  ├── model       \t\t    - models of application (DB schema files)\n  ├── postman      \t\t    - API documentation - postman collection files\n  ├── routes       \t\t    - contains all the routes of application\n  ├── services     \t\t    - contains commonly used services\n  ├── views        \t\t    - templates\n  ├── utils        \t\t    - contains utility functions   \n  └── validation          - contains validations \n```\n\n### Detail Description of Files and folders\n\n1. app.js\n- entry point of application.\n\n2. config\n- passport strategy files\n- database connection files\n\n3. constants\n- constants used across application.\n\n4. controller\n- Controller files that contains Business logic\n```\n\t├── controller               \n      └── platform\n\t\t\t├── <model>.js  - contains business logic\n\t\t\t└── index.js  - contains dependency injection\n```\n\n5. entity\n- These are the business objects of your application. These should not be affected by any change external to them, and these should be the most stable code within your application. \nThese can be POJOs, objects with methods, or even data structures.\n\n6. helpers\n- helper function, used to assist in providing some functionality, which isn't the main goal of the application or class in which they are used.\n\n7. middleware\n- Middleware files for authentication, authorization and role-access.\n\n8. models\n- Database models \n\n9. postman\n- Postman collection of APIs (Import this JSON in Postman to run the APIs)\n\n10. public \n- Assets used in application\n\n11. routes\n```\n\t├── routes\n\t\t├── platform\n\t\t\t├── <model>Routes.js   - contains CRUD operation routes\n\t\t\t└── index.js               - exports model Routes\n\t\t└── index.js                 - exports platform routes\n\n```\n- index.js file, exports platform routes, imported into app.js to access all the routes.\n\n12. services\n```\n\t├── services\n\t\t├── jobs                     - cron jobs\n\t\t├── dbService.js             - Database service\n\t\t└── auth.js                  - Authentication module service\n\n```\n\n13. utils\n```\n\t├── utils\n\t\t├── messages.js              - Messages used in sending response \n\t\t├── responseCode.js          - response codes \n\t\t└── validateRequest.js       - validate request based on model schema\n\n```\n\n14. validation\n- Joi validations files for every model\n\n15. env files\n- You can add credentials and port, database values as per your environment(Development/Production).\n- If you are running test environment then test cases will run using test database,and its configuration is there inside app.js\n\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\nhelp@dhiwise.com.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nWe will appreciate developers' contribution to improve node.js code generator, to make it even better. Therefore, any contributions related to features, issues, documentation, translation, guides, and more are all welcomed.\n\n## Got a question?\n\nYou can ask questions, consult with more experienced DhiWise users, and discuss DhiWise-related topics in the our [Discord channel](https://discord.gg/hTuNauNjyJ).\n\n## Bugs\n\nIf you find a bug in the source code, you can help us by [submitting an issue](https://github.com/DhiWise/nodejs-code-generator/issues/new?assignees=&labels=type%3A%20bug&template=bug_report.md&title=) to our GitHub Repository. Even better, you can submit a Pull Request with a fix.\n\n## Feature Suggestion\n\nYou can request a new feature by [submitting an issue](https://github.com/DhiWise/nodejs-code-generator/issues/new?assignees=&labels=type%3A%20feature%20request&template=feature_request.md&title=) to our GitHub Repository.\n\nIf you would like to implement a new feature, please submit an issue with a proposal for your work first, to be sure that we can use it. Please consider what kind of change it is:\n\n- For a Major Feature, first open an issue and outline your proposal so that it can be discussed. This will also allow us to better coordinate our efforts, prevent duplication of work, and help you craft the change so that it's successfully integrated in the project.\n\n- Small Features can be added directly [submitted as a Pull Request](#submit-pr).\n\n## What do I need to know to help?\n\nIf you want to help out with a code contribution, our project uses the following stack:\n\n### Server-side\n\n- [Node.JS](https://nodejs.org/)\n\n### Client-side\n\n- [React](https://reactjs.org/docs/getting-started.html)\n\n### Testing\n\n- [Jest](https://jestjs.io/) (for testing)\n\n\n## <a name=\"submit-pr\"></a> How do I make a contribution?\n\nNever made an open source contribution before? Wondering how contributions work in the in our project? Here's a quick rundown!\n\nFind an issue that you're interested in addressing, or a feature that you'd like to add.\nYou can use [this view](https://github.com/dhiwise/nodejs-code-generator/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) which helps new contributors find easy gateways into our project.\n\nFork the repository associated with the issue to your local GitHub organization. This means that you'll have a copy of the repository under your-GitHub-username/repository-name.\nClone the repository to your local machine:\n\n```\ngit clone https://github.com/DhiWise/nodejs-code-generator\n\n```\n\nCreate a new branch for your fix:\n\n```\ngit checkout -b branch-name-here\n```\n\nMake the appropriate changes for the issue you are trying to address or the feature that you want to add.\n\nOnce done, stage the changes that are ready to be committed:\n\n```\ngit add .\n```\n\nCommit the changes with a short message.\n\n```\ngit commit -m \"<type>:<package>:<message>\"\n```\n\nCLI for better commit messages\n\n```\nnpm run commit\n```\n\n\nPush the changes to the remote repository using:\n\n```\ngit push origin branch-name-here\n```\n\n### Branch Guidelines\n1. If you are fixing a bug, start the branch name with bug/bug-name\n2. If you are adding a feature, start the branch name with feature/feature-name\n3. Submit you branch to master by creating a PR.\n\nIn the description of the pull request, explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer.\n\nIt's okay if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it!\n\nWait for the pull request to be reviewed by a maintainer.\n\nMake changes to the pull request if the reviewing maintainer recommends them.\n\nCelebrate your success after your pull request is merged!\n\n### Git Commit Messages\n\nWe structure our commit messages like this:\n\n```\n<type>(<package>): <subject>\n```\n\nExample\n\n```\nfix(server): missing entity on init\n```\n\nList of types:\n\n- feat: A new feature\n- fix: A bug fix\n- docs: Changes to the documentation\n- refactor: A code change that neither fixes a bug nor adds a feature\n- perf: A code change that improves performance\n- test: Adding missing or correcting existing tests\n\n### Code of conduct\n\nPlease note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.\n\n[Code of Conduct](https://github.com/DhiWise/nodejs-code-generator/blob/master/CODE_OF_CONDUCT.md)\n\nOur Code of Conduct means that you are responsible for treating everyone on the project with respect and courtesy.\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2021 DhiWise Pvt. Ltd.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "MVC_ARCHITECTURE.md",
    "content": "# Node.JS,Express Project in MVC Architecture with Mongoose/Sequelize\n\n**supported version of nodejs > 12**,\n**supported version of mongoose-4.0**,\n**supported version of sequelize-6.6.5**\n\n## About \n- This is a Node application, developed using MVC pattern with Node.js, ExpressJS.\n\n## Initial\n1. ```$ npm install```\n2. ```$ npm start```\n\n## Folder structure:\n```\n  ├── app.js       - starting point of the application\n  ├── config       - application configuration files\n  ├── constants    - contains commonly used constants \n  ├── controller   - contains business logic\n  ├── model        - models of application (DB schema files)\n  ├── postman      - API documentation - postman collection files\n  ├── routes       - contains all the routes of application\n  ├── services     - contains commonly used services\n  ├── views        - templates\n  └── utils        - contains utility functions    \n```\n\n### Detail Description of Files and folders\n\n1. app.js\n- entry point of application.\n\n2. config\n- passport strategy files\n- database connection files\n\n3. constants\n- constants used across application.\n\n4. controllers\n- Controller files that contains Business logic\n```\n\t├── controller\n\t\t└── platform\n\t\t\t└── <model>Controller.js   - contains CRUD Operations\n```\n\n5. middleware\n- Middleware files for authentication, authorization and role-access.\n\n6. models\n- Database models \n\n7. postman\n- Postman collection of APIs (Import this JSON in Postman to run the APIs)\n\n8. public \n- Assets used in application\n\n9. routes\n```\n\t├── routes\n\t\t├── platform\n\t\t\t├── <model>Routes.js  - contains CRUD operation routes\n\t\t\t└── index.js              - exports model Routes\n\t\t└── index.js                - exports platform routes\n\n```\n- index.js file, exports platform routes, imported into app.js to access all the routes.\n\n10. services\n```\n\t├── services\n\t\t├── jobs                     - cron jobs\n\t\t└── auth.js                  - Authentication module service\n\n```\n\n11. utils\n```\n\t├── utils\n\t\t├── validations              - joi validations files for every model\n\t\t├── dbService.js             - Database functions \n\t\t├── messages.js              - Messages used in sending response \n\t\t├── responseCode.js          - response codes \n\t\t└── validateRequest.js       - validate request based on model schema\n\n```\n\n12. env files\n- You can add credentials, port, database-name etc as per your environment(Development/Production).\n- If you are running test environment then test cases will run using test database,and its configuration is there inside app.js\n"
  },
  {
    "path": "README.md",
    "content": "[![GitHub stars](https://img.shields.io/github/stars/DhiWise/nodejs-code-generator?style=flat-square&color=yellow)](https://github.com/DhiWise/nodejs-code-generator)\n[![Issues](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square&color=66bb6a)](https://github.com/DhiWise/nodejs-code-generator/issues)\n\n# Node.js Code Generator\n<p>\nNode.js code generator is a developer-centric platform to build backend CRUD APIs along with other essential features to boost developers' productivity time by twofold!\n\nDevelopers just need to add their schema data to reduce their work related to models into a few simple configurations. Developers can also configure platforms , routes, role access, authentication & more for their application.\n\nMost importantly, the Node.js code generator gives developers total code ownership. The code it generates is bug-free and easily customizable\n</p>\n\n## Table of contents\n\n* [Get started](#get-started)\n\n* [Supported Architectures](#supported-architectures)\n\n* [Features](#features-of-generated-code)\n\n* [Documentation](#documentation)\n\n## Get started \nAfter a successful run, a user can configure different settings using UI, and build an app to generate the code.\n1. To run ```npm i && npm run start```\n> :warning: Note: Use ```npm i --force``` If your npm installation fails. As Node version >= 14 will give you errors if peer dependency in different packages have ambiguation in versions.\n2. With ```npm run start``` project will run on 3000 port.\n3. Run http://localhost:3000 and you will see \"create application\" form. After creating an application you can configure modules and build the app to get the source code.\n<img src=\"https://development-dhvs.s3.ap-south-1.amazonaws.com/uploads/user-profile/open-source.gif\" alt=\"create-application\"/>\n4. After a successful build, Generated code will resides inside the **packages/server/output** folder.\n\n## Supported architectures\n\nThis project provides two architectures to choose from, while creating an application.\n### <a href=\"https://github.com/DhiWise/nodejs-code-generator/blob/master/CLEAN_CODE.md\">Clean Code</a>\nThe main rule of clean architecture is that code dependencies can only move from the outer levels inward. Code on the inner layers can have no knowledge of functions on the outer layers.\n\n### <a href=\"https://github.com/DhiWise/nodejs-code-generator/blob/master/MVC_ARCHITECTURE.md\">MVC - Model-View-Controller</a>\nThe Model-View-Controller (MVC) is an architectural pattern that separates an application into three main logical components: the model, the view, and the controller. Each of these components are built to handle specific development aspects of an application.\n\n## Features of generated code\n1. User Authentication and Authorization (using Passport)\n2. Social Login APIs\n3. CRUD APIs with middleware and attributes' selection\n4. List API with pagination, populate and queries\n5. Upload attachment API with validation and storage options like (Local server or S3 public/private bucket)\n6. Role-Permission\n8. Hooks and Indexes\n9. Policy/middleware\n10. API request body validation (Using joi)\n11. API response with standard error and message pattern\n12. Test cases\n13. Postman collection and API documentation\n15. Constants\n17. Environment Variables for development, QA and production\n18. Custom API setup\n19. Multiple Platform selection and User type configuration\n20. MVC and Clean-code architecture \n21. Supported Databases <br>\n    a. MongoDB<br>\n    b. SQL Server<br>\n    c. MYSQL<br>\n    d. PostgreSQL\n\n## Documentation\n\nHere's the Documentation of <a href=\"https://docs.dhiwise.com/docs/node/generate-apis/\">How you can use generated APIs</a>\n\n## Contribution\nHave you found a bug? :lady_beetle: <a href=\"https://github.com/DhiWise/nodejs-code-generator/issues/new?assignees=&labels=type%3A%20bug&template=bug_report.md&title=\">Please report it here</a>\nor have a nice feature 💡 to contribute? Add it <a href=\"https://github.com/DhiWise/nodejs-code-generator/issues/new?assignees=&labels=type%3A%20feature%20request&template=feature_request.md&title=\"> here </a> \n<br/>\nOur <a href=\"https://github.com/DhiWise/nodejs-code-generator/blob/master/CONTRIBUTING.md\">Contribution guide </a> will help you how to contribute.\n\n## Support\nIf you have problems or questions go to our Discord channel, we will then try to help you as quickly as possible: https://discord.gg/hTuNauNjyJ\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"npmClient\": \"npm\",\n  \"version\": \"1.3.1\",\n  \"lerna\": \"4.0.0\",\n  \"command\": {\n    \"publish\": {\n      \"conventionalCommits\": true,\n      \"yes\": true\n    }\n  }\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nodejs-code-generator\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"author\": {\n    \"name\": \"DhiWise\",\n    \"url\": \"https://www.dhiwise.com\"\n  },\n  \"scripts\": {\n    \"start\": \"lerna run start\",\n    \"install\": \"lerna clean -y && lerna bootstrap --hoist\",\n    \"test\": \"jest --runInBand\",\n    \"commit\": \"cz\",\n    \"release_prepatch\": \"lerna publish prepatch --conventional-commits && conventional-github-releaser --preset angular\",\n    \"release_patch\": \"lerna publish patch --conventional-commits && conventional-github-releaser --preset angular\",\n    \"release_premajor\": \"lerna publish premajor --conventional-commits && conventional-github-releaser --preset angular\",\n    \"release\": \"lerna publish --conventional-commits && conventional-github-releaser --preset angular\",\n    \"lint\": \"eslint . --ext .js --fix\"\n  },\n  \"jest\": {\n    \"modulePathIgnorePatterns\": [\n      \"packages/server/output/*\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@babel/eslint-parser\": \"^7.15.8\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.14.5\",\n    \"@babel/plugin-transform-react-jsx\": \"^7.14.9\",\n    \"commitizen\": \"^4.2.4\",\n    \"conventional-github-releaser\": \"^3.1.2\",\n    \"cz-lerna-changelog\": \"^2.0.3\",\n    \"eslint\": \"^7.32.0\",\n    \"eslint-config-airbnb\": \"^18.2.1\",\n    \"eslint-import-resolver-alias\": \"^1.1.2\",\n    \"eslint-plugin-import\": \"^2.22.2\",\n    \"eslint-plugin-jsx-a11y\": \"^6.4.1\",\n    \"eslint-plugin-react\": \"^7.26.1\",\n    \"eslint-plugin-react-hooks\": \"^4.2.0\",\n    \"lerna\": \"^4.0.0\",\n    \"react-app-rewire-aliases\": \"^0.2.0\",\n    \"react-app-rewired\": \"^2.1.8\",\n    \"react-error-overlay\": \"^6.0.9\",\n    \"supertest\": \"^6.1.6\"\n  },\n  \"config\": {\n    \"commitizen\": {\n      \"path\": \"./node_modules/cz-lerna-changelog\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/client/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true,\n    \"es2021\": true\n  },\n  \"extends\": [\n    \"plugin:react/recommended\",\n    \"airbnb\"\n  ],\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    },\n    \"ecmaVersion\": 12,\n    \"sourceType\": \"module\",\n    \"requireConfigFile\": false,\n    \"babelOptions\": {\n      \"presets\": [\n        \"@babel/preset-react\",\n        [\n          \"@babel/env\",\n          {\n            \"targets\": {\n              \"edge\": \"17\",\n              \"firefox\": \"60\",\n              \"chrome\": \"67\",\n              \"safari\": \"11.1\"\n            },\n            \"useBuiltIns\": \"usage\",\n            \"corejs\": \"3.6.4\"\n          }\n        ]\n      ],\n      \"plugins\": [\n        \"@babel/plugin-transform-react-jsx\",\n        \"@babel/plugin-proposal-class-properties\"\n      ]\n    }\n  },\n  \"plugins\": [\n    \"react\"\n  ],\n  \"rules\": {\n    \"jsx-a11y/label-has-for\": \"off\",\n    \"jsx-a11y/label-has-associated-control\": \"off\",\n    \"max-len\": \"off\",\n    \"linebreak-style\": \"off\",\n    \"global-require\": \"off\",\n    \"no-console\": \"off\",\n    \"react/prop-types\": \"off\",\n    \"jsx-a11y/click-events-have-key-events\": \"off\",\n    \"jsx-a11y/no-static-element-interactions\": \"off\",\n    \"jsx-a11y/mouse-events-have-key-events\": \"off\",\n    \"jsx-a11y/no-redundant-roles\": \"off\",\n    \"jsx-a11y/no-noninteractive-tabindex\": \"off\",\n    \"jsx-a11y/no-noninteractive-element-interactions\": \"off\",\n    \"react/require-default-props\": \"off\",\n    \"react/button-has-type\": \"off\",\n    \"react/no-unknown-property\":\"off\",\n    \"react/destructuring-assignment\": [\n      \"off\",\n      {\n        \"ignoreClassFields\": true\n      }\n    ],\n    \"no-bitwise\": \"off\",\n    \"no-unused-expressions\": [\n      \"error\",\n      {\n        \"allowShortCircuit\": true,\n        \"allowTernary\": true\n      }\n    ],\n    \"no-underscore-dangle\": \"off\",\n    \"react/no-unescaped-entities\": \"off\",\n    \"react/jsx-filename-extension\": [\n      1,\n      {\n        \"extensions\": [\n          \".js\",\n          \".jsx\"\n        ]\n      }\n    ],\n    \"import/prefer-default-export\": \"off\"\n  },\n  \"parser\": \"@babel/eslint-parser\",\n  \"settings\": {\n    \"import/resolver\": {\n      \"alias\": [\n        [\n          \"@assets\",\n          \"./src/assets\"\n        ],\n        [\n          \"@constant\",\n          \"./src/constant\"\n        ]\n      ],\n      \"node\": {\n        \"extensions\": [\n          \".js\",\n          \".jsx\",\n          \".ts\",\n          \".tsx\"\n        ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/client/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules   \n/.history\n/.pnp\n.pnp.js\npackage-lock.json\nyarn.lock\n/.vscode\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "packages/client/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.3.1](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.3.0...v1.3.1) (2022-09-28)\n\n**Note:** Version bump only for package @nodejs-code-generator/client\n\n\n\n\n\n# [1.3.0](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.2.0...v1.3.0) (2022-04-25)\n\n\n### Bug Fixes\n\n* **eslint fixes:** eslint rules violation removed ([7682a2a](https://github.com/DhiWise/dhiwise-nodejs/commit/7682a2af8031955655e5c943be580fb18f2cce5a))\n* **file upload in cc:** fix file upload in controller of cc ([387562a](https://github.com/DhiWise/dhiwise-nodejs/commit/387562a1b9ecc6636200c6c9fb7d56451a0c5878))\n* **model data save warning:** when model data change and change the model without save ask warning p ([791f20f](https://github.com/DhiWise/dhiwise-nodejs/commit/791f20fc716e3acba8271ca6109e36b460848d09))\n* **overlay issue no able to click:** propstypes forbidden remove and overlay issue fix ([3abc5fa](https://github.com/DhiWise/dhiwise-nodejs/commit/3abc5fab37b580789691effb46231cbb9dd1c760)), closes [#27](https://github.com/DhiWise/dhiwise-nodejs/issues/27)\n* **Remove configuration tab in routes:** file upload - removal form custom routes ([98a7e54](https://github.com/DhiWise/dhiwise-nodejs/commit/98a7e540e5bface7478edf1940914df4e53ef42e))\n\n\n\n\n\n# [1.2.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.1.0...v1.2.0) (2022-02-02)\n\n**Note:** Version bump only for package @nodejs-code-generator/client\n\n\n\n\n\n# [1.1.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.0.0...v1.1.0) (2022-01-11)\n\n\n### Features\n\n* add confirmation popup when second time build application ([a7fe3c0](https://github.com/DhiWise/nodejs-code-generator/commit/a7fe3c001fab1972a8f2f151feb6deb18220c3e5)), closes [#20](https://github.com/DhiWise/nodejs-code-generator/issues/20)\n"
  },
  {
    "path": "packages/client/README.md",
    "content": "# Client    \n\nThis is a node code generator panel by using you can give input's and generate code.\n\n## Run\n##### `npm start`\n \n Open http://localhost:3000 to view it in the browser.\n"
  },
  {
    "path": "packages/client/babel-plugin-macros.config.js",
    "content": "module.exports = {\n  twin: {\n    config: 'tailwind.config.js',\n    preset: 'styled-components',\n    autoCssProp: true,\n    dataTwProp: true,\n    debugPlugins: false,\n    debug: false,\n  },\n};\n"
  },
  {
    "path": "packages/client/babel.config.json",
    "content": "{\n\t\"presets\": [\n\t\t\"@babel/preset-react\",\n\t\t[\n\t\t\t\"@babel/env\",\n\t\t\t{\n\t\t\t\t\"targets\": {\n\t\t\t\t\t\"edge\": \"17\",\n\t\t\t\t\t\"firefox\": \"60\",\n\t\t\t\t\t\"chrome\": \"67\",\n\t\t\t\t\t\"safari\": \"11.1\"\n\t\t\t\t},\n\t\t\t\t\"useBuiltIns\": \"usage\",\n\t\t\t\t\"corejs\": \"3.6.4\"\n\t\t\t}\n\t\t]\n\t],\n\t\"plugins\": [\"@babel/plugin-transform-react-jsx\",\"@babel/plugin-proposal-class-properties\"]\n}"
  },
  {
    "path": "packages/client/config-overrides.js",
    "content": "const rewireAliases = require('react-app-rewire-aliases');\nconst { paths } = require('react-app-rewired');\nconst path = require('path');\n\n/* config-overrides.js */\nmodule.exports = function override(config, env) {\n  return rewireAliases.aliasesOptions({\n    '@assets': path.resolve(__dirname, `./${paths.appSrc}/assets`),\n    '@constant': path.resolve(__dirname, `./${paths.appSrc}/constant/`),\n  })(config, env);\n};\n"
  },
  {
    "path": "packages/client/package.json",
    "content": "{\n  \"name\": \"@nodejs-code-generator/client\",\n  \"version\": \"1.3.1\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@babel/parser\": \"^7.15.8\",\n    \"@babel/traverse\": \"^7.15.4\",\n    \"@dhiwise/icons\": \"^0.0.9\",\n    \"@monaco-editor/react\": \"^4.0.7\",\n    \"@reduxjs/toolkit\": \"^1.6.2\",\n    \"@tailwindcss/postcss7-compat\": \"^2.2.17\",\n    \"@testing-library/jest-dom\": \"^5.14.1\",\n    \"@testing-library/react\": \"^11.2.7\",\n    \"@testing-library/user-event\": \"^12.8.3\",\n    \"array-move\": \"^3.0.1\",\n    \"autoprefixer\": \"^10.3.7\",\n    \"axios\": \"^0.23.0\",\n    \"classnames\": \"^2.3.1\",\n    \"copy-to-clipboard\": \"^3.3.1\",\n    \"dayjs\": \"^1.10.7\",\n    \"event-source-polyfill\": \"^1.0.25\",\n    \"immutability-helper\": \"^3.1.1\",\n    \"jsonlint\": \"git+https://github.com/DhiWise/jsonlint\",\n    \"lodash\": \"^4.17.21\",\n    \"memoize-one\": \"^6.0.0\",\n    \"monaco-jsx-highlighter\": \"^1.1.8\",\n    \"omit-deep-lodash\": \"^1.1.5\",\n    \"pluralize\": \"^8.0.0\",\n    \"postcss\": \"^8.3.9\",\n    \"postcss-cli\": \"^9.0.1\",\n    \"postcss-custom-properties\": \"^12.0.0\",\n    \"postcss-import\": \"^14.0.2\",\n    \"postcss-nested\": \"^5.0.6\",\n    \"prop-types\": \"^15.7.2\",\n    \"rc-drawer\": \"^4.4.2\",\n    \"react\": \"^17.0.2\",\n    \"react-app-rewire-aliases\": \"^0.2.0\",\n    \"react-app-rewired\": \"^2.1.8\",\n    \"react-awesome-query-builder\": \"^4.7.0\",\n    \"react-content-loader\": \"^6.0.3\",\n    \"react-datepicker\": \"^4.2.1\",\n    \"react-dnd\": \"^10.0.2\",\n    \"react-dnd-html5-backend\": \"^9.5.1\",\n    \"react-dom\": \"^17.0.2\",\n    \"react-dropdown-tree-select\": \"git+https://github.com/DhiWise/react-dropdown-tree-select\",\n    \"react-helmet\": \"^6.1.0\",\n    \"react-hook-form\": \"^6.15.4\",\n    \"react-loadable\": \"^5.5.0\",\n    \"react-lottie\": \"^1.2.3\",\n    \"react-modal\": \"^3.14.3\",\n    \"react-popover\": \"^0.5.10\",\n    \"react-pro-sidebar\": \"^0.7.1\",\n    \"react-redux\": \"^7.2.5\",\n    \"react-router\": \"^5.2.1\",\n    \"react-router-dom\": \"^5.3.0\",\n    \"react-scripts\": \"4.0.3\",\n    \"react-scrollbar\": \"^0.5.6\",\n    \"react-select\": \"^5.1.0\",\n    \"react-sortable-hoc\": \"^2.0.0\",\n    \"react-table\": \"^7.7.0\",\n    \"react-tabs\": \"^3.2.2\",\n    \"react-tiny-popover\": \"^7.0.1\",\n    \"react-toast-notifications\": \"^2.5.1\",\n    \"react-tooltip\": \"^4.2.21\",\n    \"react-virtualized-auto-sizer\": \"^1.0.6\",\n    \"react-window\": \"^1.8.6\",\n    \"react-window-infinite-loader\": \"^1.0.7\",\n    \"recoil\": \"^0.4.1\",\n    \"redux-persist\": \"^6.0.0\",\n    \"redux-persist-transform-encrypt\": \"^3.0.1\",\n    \"snake-case\": \"^3.0.4\",\n    \"tailwindcss\": \"^2.2.17\",\n    \"three\": \"^0.137.0\",\n    \"use-onclickoutside\": \"^0.4.0\",\n    \"web-vitals\": \"^1.1.2\"\n  },\n  \"scripts\": {\n    \"start\": \"npm run watch:css && react-app-rewired start\",\n    \"build\": \"npm run watch:css && react-app-rewired build\",\n    \"test\": \"react-app-rewired test\",\n    \"eject\": \"react-scripts eject\",\n    \"fix:lint\": \"npx eslint --fix --ext .js src\",\n    \"watch:css\": \"postcss src/assets/css/tailwind.css -o src/assets/css/main.css\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\",\n      \"react-app/jest\"\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@babel/eslint-parser\": \"^7.15.8\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.14.5\",\n    \"@babel/plugin-transform-react-jsx\": \"^7.14.9\",\n    \"eslint\": \"^7.32.0\",\n    \"eslint-config-airbnb\": \"^18.2.1\",\n    \"eslint-import-resolver-alias\": \"^1.1.2\",\n    \"eslint-plugin-import\": \"^2.22.2\",\n    \"eslint-plugin-jsx-a11y\": \"^6.4.1\",\n    \"eslint-plugin-react\": \"^7.26.1\",\n    \"eslint-plugin-react-hooks\": \"^4.2.0\"\n  }\n}\n"
  },
  {
    "path": "packages/client/postcss.config.js",
    "content": "module.exports = {\n  plugins: [\n    require('postcss-import'),\n    require('tailwindcss'),\n    require('postcss-nested'),\n    require('postcss-custom-properties'),\n    require('autoprefixer'),\n  ],\n};\n"
  },
  {
    "path": "packages/client/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"utf-8\" />\n  <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <meta name=\"theme-color\" content=\"#000000\" />\n  <meta name=\"description\" content=\"Web site created using create-react-app\" />\n  <link rel=\"apple-touch-icon\" href=\"%PUBLIC_URL%/logo192.png\" />\n  <!--\n      manifest.json provides metadata used when your web app is installed on a\n      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n    -->\n  <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n  <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n  <title>DhiWise</title>\n</head>\n\n<body>\n  <noscript>You need to enable JavaScript to run this app.</noscript>\n  <div id=\"root\" class=\"dhiwise_body\"></div>\n  <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n</body>\n\n</html>"
  },
  {
    "path": "packages/client/public/manifest.json",
    "content": "{\n  \"short_name\": \"React App\",\n  \"name\": \"Create React App Sample\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    },\n    {\n      \"src\": \"logo192.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"192x192\"\n    },\n    {\n      \"src\": \"logo512.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"512x512\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "packages/client/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "packages/client/src/App.css",
    "content": ".App {\n  text-align: center;\n}\n\n.App-logo {\n  height: 40vmin;\n  pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  .App-logo {\n    animation: App-logo-spin infinite 20s linear;\n  }\n}\n\n.App-header {\n  background-color: #282c34;\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  font-size: calc(10px + 2vmin);\n  color: white;\n}\n\n.App-link {\n  color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "packages/client/src/App.js",
    "content": "import React from 'react';\nimport { RecoilRoot } from 'recoil';\nimport { ToastProvider } from 'react-toast-notifications';\nimport { Provider } from 'react-redux';\nimport { PersistGate } from 'redux-persist/integration/react';\nimport { persistStore } from 'redux-persist';\nimport {\n  BrowserRouter as Router,\n} from 'react-router-dom';\nimport store from './redux/store';\nimport Root from './config/Root';\n\nconst persistor = persistStore(store);\n\nfunction MainApp() {\n  return (\n    <RecoilRoot>\n\n      <Provider store={store}>\n        <PersistGate loading={null} persistor={persistor}>\n          <ToastProvider>\n            <Router>\n              <Root />\n            </Router>\n          </ToastProvider>\n        </PersistGate>\n      </Provider>\n\n    </RecoilRoot>\n  );\n}\nfunction App() {\n  return <MainApp />;\n}\n\nexport default App;\n"
  },
  {
    "path": "packages/client/src/api/applicationConfig.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport const createApplicationConfig = (payload) => apiClient(API_URLS.applicationConfig.create, payload);\nexport const getApplicationConfig = (payload) => apiClient(API_URLS.applicationConfig.paginate, payload);\nexport const updateApplicationConfig = (applicationConfigId, payload) => apiClient(`${API_URLS.applicationConfig.url}/${applicationConfigId}`, payload, 'PUT');\n"
  },
  {
    "path": "packages/client/src/api/applicationConstant.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\n// Application node  Constant Services\n\nexport const createConstant = (payload) => apiClient(API_URLS.constant.create, payload);\nexport const updateConstant = (constantId, payload) => apiClient(`${API_URLS.constant.url}/${constantId}`, payload, 'PUT');\nexport const fetchConstant = (payload) => apiClient(API_URLS.constant.paginate, payload);\nexport const deleteConstant = (payload) => apiClient(API_URLS.constant.delete, payload);\n"
  },
  {
    "path": "packages/client/src/api/applicationPolicy.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\n// Application node  Constant Services\n\nexport const createPolicy = (payload) => apiClient(API_URLS.policy.create, payload);\nexport const updatePolicy = (policyId, payload) => apiClient(`${API_URLS.policy.url}/${policyId}`, payload, 'PUT');\nexport const fetchPolicy = (payload) => apiClient(API_URLS.policy.paginate, payload);\nexport const deletePolicy = (payload) => apiClient(API_URLS.policy.delete, payload);\n"
  },
  {
    "path": "packages/client/src/api/config.js",
    "content": "import axios from 'axios';\n\nexport const defaultAxios = axios.create({\n  headers: {\n    'Content-Type': 'application/json',\n    'Cache-Control': 'no-cache',\n    Pragma: 'no-cache',\n    Expires: '0',\n  },\n});\n\nexport function apiClient(url, data = {}, method = 'POST', header = {}, rest, options) {\n  return new Promise((resolve, reject) => {\n    const headers = {\n      ...header,\n    };\n\n    defaultAxios({\n      method,\n      url,\n      headers,\n      data,\n      ...rest,\n    }).then((res) => {\n      if (res?.data?.code === 'OK') {\n        resolve(res?.data);\n      } else if (options?.isHandleCatch) {\n        resolve(res?.data);\n      } else {\n        let msg = res?.data?.message || res?.response?.data?.message;\n        if (res?.data?.isAlert) { msg = { msg }; }\n        if (res?.data?.data && options?.isHandleError) { msg = { msg, data: res?.data?.data }; }\n        reject(msg);\n      }\n    }).catch((err) => {\n      let msg = err?.response?.data?.message; // || 'Can\\'t connect to server';\n      if (err?.response?.data?.isAlert) { msg = { msg }; }\n      if (options?.isErrorResponse) { msg = err?.response?.data; }\n      reject(msg);\n    });\n  });\n}\n"
  },
  {
    "path": "packages/client/src/api/constants.js",
    "content": "const projectServiceUrl = process?.env?.REACT_APP_PROJECT_SERVICE_URL;\n\nconst version = 'web/v1';\n\nexport const API_URLS = {\n  route: {\n    url: `${projectServiceUrl}/${version}/project-route`,\n    create: `${projectServiceUrl}/${version}/project-route/create`,\n    paginate: `${projectServiceUrl}/${version}/project-route/paginate`,\n    delete: `${projectServiceUrl}/${version}/project-route/destroy`,\n  },\n  application: {\n    create: `${projectServiceUrl}/${version}/application/create`,\n    generate: `${projectServiceUrl}/${version}/application/generate`,\n    edit: `${projectServiceUrl}/${version}/application`,\n    openVsCode: `${projectServiceUrl}/${version}/application/open-generated-code`,\n    lastAppRedirect: `${projectServiceUrl}/${version}/application/last-application`,\n    destroy: `${projectServiceUrl}/${version}/application/destroy`,\n  },\n  schema: {\n    create: `${projectServiceUrl}/${version}/schema/create`,\n    paginate: `${projectServiceUrl}/${version}/schema/paginate`,\n    update: `${projectServiceUrl}/${version}/schema`,\n    delete: `${projectServiceUrl}/${version}/schema/destroy`,\n    get: `${projectServiceUrl}/${version}/schema/get`,\n    multipleCreate: `${projectServiceUrl}/${version}/schema/insert-default-models`,\n  },\n  schemaDetail: {\n    paginate: `${projectServiceUrl}/${version}/schema-detail/paginate`,\n    upsert: `${projectServiceUrl}/${version}/schema-detail/upsert`,\n  },\n  constant: {\n    url: `${projectServiceUrl}/${version}/project-constant`,\n    create: `${projectServiceUrl}/${version}/project-constant/create`,\n    paginate: `${projectServiceUrl}/${version}/project-constant/paginate`,\n    delete: `${projectServiceUrl}/${version}/project-constant/destroy`,\n  },\n  policy: {\n    url: `${projectServiceUrl}/${version}/project-policy`,\n    create: `${projectServiceUrl}/${version}/project-policy/create`,\n    paginate: `${projectServiceUrl}/${version}/project-policy/paginate`,\n    delete: `${projectServiceUrl}/${version}/project-policy/destroy`,\n  },\n  applicationConfig: {\n    url: `${projectServiceUrl}/${version}/application-config`,\n    create: `${projectServiceUrl}/${version}/application-config/create`,\n    paginate: `${projectServiceUrl}/${version}/application-config/paginate`,\n  },\n  master: {\n    getByCode: `${projectServiceUrl}/${version}/master/get-by-code`,\n  },\n  envVariables: {\n    get: `${projectServiceUrl}/${version}/env-variables/details`,\n    upsert: `${projectServiceUrl}/${version}/env-variables/upsert`,\n  },\n  projectRoleAccess: {\n    url: `${projectServiceUrl}/${version}/project-role-access`,\n    upsert: `${projectServiceUrl}/${version}/project-role-access/upsert`,\n    paginate: `${projectServiceUrl}/${version}/project-role-access/paginate`,\n    delete: `${projectServiceUrl}/${version}/project-role-access/destroy`,\n  },\n};\n"
  },
  {
    "path": "packages/client/src/api/envVariable.js",
    "content": "import { apiClient } from '.';\nimport { API_URLS } from './constants';\n\nexport const getEnvs = (payload) => apiClient(API_URLS.envVariables.get, payload);\nexport const upsertEnvs = (payload) => apiClient(API_URLS.envVariables.upsert, payload);\n"
  },
  {
    "path": "packages/client/src/api/index.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport { apiClient, API_URLS };\n"
  },
  {
    "path": "packages/client/src/api/master.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport const fetchByCode = (payload) => apiClient(API_URLS.master.getByCode, payload);\n"
  },
  {
    "path": "packages/client/src/api/models.js",
    "content": "import { apiClient } from '.';\nimport { API_URLS } from './constants';\n\nexport const getModelPermissions = (payload) => apiClient(API_URLS.schemaDetail.paginate, payload);\nexport const upsertModelPermissions = (payload) => apiClient(API_URLS.schemaDetail.upsert, payload);\nexport const deleteModel = (payload) => apiClient(API_URLS.schema.delete, payload);\nexport const createModel = (payload) => apiClient(API_URLS.schema.create, payload);\nexport const updateModelApi = (payload, id) => apiClient(`${API_URLS.schema.update}/${id}`, payload, 'PUT');\n\n// Library Model\nexport const createMultipleModels = (payload) => apiClient(`${API_URLS.schema.multipleCreate}`, payload);\n\n// get specific Model Detail\nexport const getModel = (id) => apiClient(`${API_URLS.schema.get}/${id}`, null, 'GET');\n"
  },
  {
    "path": "packages/client/src/api/policy.js",
    "content": "import { apiClient } from '.';\nimport { API_URLS } from './constants';\n\nexport const createPolicy = (payload) => apiClient(API_URLS.policy.create, payload);\nexport const updatePolicy = (policyId, payload) => apiClient(`${API_URLS.policy.url}/${policyId}`, payload, 'PUT');\nexport const getPolicies = (payload) => apiClient(API_URLS.policy.paginate, payload);\nexport const deletePolicy = (payload) => apiClient(API_URLS.policy.delete, payload);\n"
  },
  {
    "path": "packages/client/src/api/project.js",
    "content": "/* eslint-disable implicit-arrow-linebreak */\nimport { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport const createNewApplication = (appData) => apiClient(API_URLS.application.create, appData, 'POST', {}, {}, { isErrorResponse: true });\n\nexport const editApplication = (id, payload) => apiClient(`${API_URLS.application.edit}/${id}`, payload, 'PUT');\n\nexport const redirectApplication = () => apiClient(`${API_URLS.application.lastAppRedirect}`, {}, 'GET');\n\nexport const destroyApplication = (payload) => apiClient(`${API_URLS.application.destroy}`, payload);\n"
  },
  {
    "path": "packages/client/src/api/projectRoleAccess.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport const getProjectRoleAccess = (payload) => apiClient(API_URLS.projectRoleAccess.paginate, payload);\nexport const upsertProjectRoleAccess = (payload) => apiClient(API_URLS.projectRoleAccess.upsert, payload);\nexport const deleteProjectRoleAccess = (payload) => apiClient(API_URLS.projectRoleAccess.delete, payload);\n"
  },
  {
    "path": "packages/client/src/api/routes.js",
    "content": "import { apiClient } from './config';\nimport { API_URLS } from './constants';\n\nexport const createNodeRoute = (payload) => apiClient(API_URLS.route.create, payload);\nexport const updateNodeRoute = (routeId, payload) => apiClient(`${API_URLS.route.url}/${routeId}`, payload, 'PUT');\nexport const getModelRoutes = (payload) => apiClient(API_URLS.route.paginate, payload);\nexport const deleteModelRoute = (payload) => apiClient(API_URLS.route.delete, payload);\n"
  },
  {
    "path": "packages/client/src/assets/css/Table.css",
    "content": ".custom-table table{\n    @apply w-full;\n}\n.custom-table table tbody{\n    /* box-shadow:0 0 0 2px var(--color-gray-200); */\n    border-radius: 5px;\n}\n.custom-table table tr td,\n.custom-table table tr th{\n    padding:0.6rem 0.5rem;\n    font-size:14px;\n    text-align: left;\n    text-transform: inherit;\n}\n.custom-table table tr td{\n    border-top: 1px solid var(--color-gray-200);\n    word-break: break-word;\n}\n.custom-table table tr th{\n    /* @apply uppercase; */\n}\n.custom-table table tr{\n    /* box-shadow:0 0 0 1px var(--color-gray-200); */\n}\n.custom-table table thead tr{\n    box-shadow: none;\n}\n.custom-table table tr:first-child{\n    border-radius:5px 5px 0 0;\n}\n.custom-table table tr:last-child{\n    border-radius:0 0 5px 5px;\n}\n.custom-table td{\n    min-width: min-content;\n}\n.codeTable table th,\n.codeTable table td{\n    min-width: 40px;\n    /* max-width: 40px; */\n    /* width: 40px; */\n}\n.react-json-view .requiredProperty svg,.react-json-view .uniqueProperty svg{\n    fill: green;\n}\n\n.subAtt .spark-checkbox-inner{\n    background-color: var(--color-gray-inputSub);\n    border: 1px solid var(--color-gray-300);\n}\n.tableAuto{\n    overflow: auto;\n    height: 100%;\n    /* width: 1532px; */\n    scrollbar-width: thin;\n    padding: 0 0 0 0;\n}\n/* .tableAuto .scrollarea{\n    width: 100%;\n    height: calc(100vh - 207px);\n}\n.tableAuto .content{\n    min-width: 1532px;\n    padding-right: 10px;\n    overflow: visible;\n} */\n.tableScroll{\n    min-width: min-content;\n    padding: 0 0;\n    overflow: auto;\n    height:100%\n}\n.tableScroll .spark-checkbox-inner{\n    margin: 0;\n}\n.tableScroll td{\n    padding-right: 10px;\n}\n\n/* td {\n    min-width: 250px;\n    width: 250px;\n} */\n.modelPermissionTable .permissionTableList{\n    width: 26rem;\n    min-width: 26rem;\n    max-width: 26rem;\n}\n.modelPermissionLeft{\n    min-width: 250px;\n    width: 250px;\n    max-width: 250px;\n}\n.envTable td{\n    min-width: 250px;\n}\n.envTable .tableInputSelect{\n    width: 100%;\n}\ntable{\n    width: 100%;\n}\n.viewAttributeTable tr td:first-child{\n    min-width: 60%;\n    width: 60%;\n}\n.viewAttributeTable tr td:last-child{\n    min-width: 40%;\n    width: 40%;\n}\n.tableInputSelect{\n    width: 8em;\n    min-width: 8rem;\n}\n.smallInput{\n    width: 7em;\n    min-width: 7rem;\n}\n.tableCheck{\n    width: 3em;\n    min-width: 3rem;\n}\n\n\n/* table component */\n.dhiTable{\n    overflow: auto;\n}\n.dhiTable tr th{\n    padding-top: 0.3rem;\n    padding-bottom: 0.3rem;\n    font-size: 14px;\n    color: var(--color-text-primary);\n    font-weight: 400;\n    background-color: var(--color-gray-200);\n}\n.dhiTable tr td{\n    padding-top: 0.5rem;\n    padding-bottom: 0.5rem;\n    font-size: 14px;\n    color: var(--color-text-primary);\n    font-weight: 400;\n    /* text-align: center; */\n    border-top:1px solid var(--color-gray-200);\n}\n.onlyReadView tr td{\n    border-top: none;\n    border-bottom:1px solid var(--color-gray-350);\n    border-right:1px solid var(--color-gray-350);\n}\n.dhiTable tr td,\n.dhiTable tr th{\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n    white-space: nowrap;\n    width: auto;\n}\n.firstColTable tr td:first-child,\n.firstColTable tr th:first-child{\n    width: 80px;\n    min-width: 80px;\n    max-width: 80px;\n}\n.dhiTable thead tr:first-child th{\n    position: sticky;\n    top: 0;\n    z-index: 1;\n}\n.dhiTable tr .subRow tr:first-child th{\n    position: relative;\n    z-index: 0;\n}\n/* .dhiTable.leftSpace tr th:nth-child(2),\n.dhiTable.leftSpace tr td:nth-child(2){\n    padding-left:54px;\n} */\n/* sub row */\n.subRow{\n    padding: 10px 1.25rem 10px 1.25rem !important;\n    border-top: none !important;\n}\n.subRow tr,\n.subRow td{\n    background: var(--color-gray-200);\n    text-align: left;\n}\n.subRow td {\n    /* border-top: none; */\n    padding-top: 0.2rem !important;\n    padding-bottom: 0.2rem !important;\n    font-size: 0.875rem !important;\n}\n.onlyReadView .subRow td{\n    /* padding-top: 0.2rem !important;\n    padding-bottom: 0.2rem !important; */\n    padding: 0.5rem !important;\n    border: 1px solid var(--color-gray-100) !important;\n    border-top: none !important;\n    border-right: none !important;\n    text-align: left;\n}\n.onlyReadView .subRow td:first-child{\n    border-left: none !important;\n}\n/* .onlyReadView .subRow{\n    border-right: none !important;\n} */\n.onlyReadView .subRow th{\n    border-bottom: 1px solid var(--color-gray-100);\n}\n.onlyReadView thead{\n    position: sticky;\n    top: 0;\n    z-index: 1;\n}\n.subRow tr:first-child td{\n    padding-top: 10px !important;\n}\n.subRow tr:last-child td{\n    padding-bottom: 10px !important;\n}\n.firstColTable tr td.subRow td:first-child,\n.firstColTable tr td.subRow th:first-child{\n    width: 60px;\n    min-width: 60px;\n    max-width: 60px;\n}\n\n.reactTable thead:before{\n    content: \"\";\n    width: 100%;\n    height: 36px;\n    position: fixed;\n    left: 0;\n    background: var(--color-gray-200);\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/Table1.css",
    "content": ".dhiTable_second  thead th{\n    text-transform: uppercase;\n    font-size: 14px;\n    font-weight: bold;\n    padding: 9px 10px;\n}\n.dhiTable_second tbody tr{\n    box-shadow: 5px 0px 19px -5px var(--color-gray-100);\n    background-color: var(--color-gray-black);\n}\n.dhiTable_second td{\n    padding: 6px 10px;\n    font-size: 14px;\n}"
  },
  {
    "path": "packages/client/src/assets/css/animation.css",
    "content": ".checkAnimation{\n    animation: zoom 0.75s;\n}\n@keyframes zoom {\n    0% {\n        transform: scale(0);\n    }\n    5% {\n        transform: scale(0.25);\n    }\n    12% {\n        transform: scale(0.50);\n    }\n    100% {\n        transform: scale(1);\n    }\n}\n.animationIcon{\n    animation: rotating 1.5s infinite;\n}\n@keyframes rotating {\n    0% {\n        transform: scale(0.5);\n    }\n    10% {\n        transform: scale(0.9);\n    }\n    50% {\n        transform: scale(1);\n    }\n    100% {\n        transform: scale(1);\n    }\n}\n\n@keyframes showAnimate {\n    0% {\n        transform: scale(0.5);\n    }\n    10% {\n        transform: scale(0.9);\n    }\n    50% {\n        transform: scale(1);\n    }\n    100% {\n        transform: scale(1);\n    }\n}\n\n/* animation projectt svg */\n.projectnotFoundImg svg path:nth-child(2) {\n    stroke: var(--color--black-svg);\n    stroke-width: 0.5;\n}\n\n.nodDataFound svg g path {\n    fill: var(--color--black-svg);\n    stroke: var(--color--black-svg);\n}\n\n.nodDataFound svg g>g:nth-child(3) g path {\n    fill: var(--color-bg-secondary);\n}"
  },
  {
    "path": "packages/client/src/assets/css/components/components.css",
    "content": "@import \"../../../components/Checkbox/checkbox.css\";\n@import \"../../../components/DatePicker/datepicker.css\";\n@import \"../../../components/SelectTree/selectTreeCss.css\";\n@import \"../Table.css\";\n@import \"../Table1.css\";\n@import \"../scroll.css\";\n@import \"../dropdown.css\";\n@import \"../popover.css\";\n@import \"../logo.css\";\n@import \"../tooltip.css\";\n@import \"../editor.css\";\n@import \"../notification.css\";\n@import \"../method.css\";"
  },
  {
    "path": "packages/client/src/assets/css/components/style.css",
    "content": "@import \"../tailwind.css\";\n\n@font-face {\n    font-family: 'circular';\n    src: url(\"../../fonts/circular/CustomFont-Book.woff2\");\n    font-weight: 400;\n    font-style: normal;\n    font-display: swap;\n}\n@font-face {\n    font-family: 'circular';\n    src: url(\"../../fonts/circular/CustomFont-Medium.woff2\");\n    font-weight: 500;\n    font-style: normal;\n    font-display: swap;\n}\n@font-face {\n    font-family: 'circular';\n    src: url(\"../../fonts/circular/CustomFont-Bold.woff2\");\n    font-weight: 600;\n    font-style: normal;\n    font-display: swap;\n}\n@font-face {\n    font-family: 'circular';\n    src: url(\"../../fonts/circular/CustomFont-Black.woff2\");\n    font-weight: 700;\n    font-style: normal;\n    font-display: swap;\n}\n\nbody {\n    @apply min-h-screen tracking-normal;\n    font-family: \"circular\";\n    font-weight: 400;\n    /* font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Noto Sans\", Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; */\n    color: var(--color-text-primary);\n    background-color: var(--color-gray-black);\n}\n\n.display-webkit {\n    display: -webkit-box;\n}\n\n.react-tel-input {\n    font-family: inherit !important;\n}\n\n.spacing-dw1 {\n    padding: 0.10rem 0.5rem !important;\n}\n\n.shadows-dw {\n    box-shadow: rgba(0, 0, 0, 0.06) 0px 8px 16px 0px;\n}\n\n.shadows-dw1 {\n    box-shadow: rgba(0, 0, 0, 0.08) 4px -3px 13px 0px;\n}\n.shadow-keyboard{\n    box-shadow:0 -1px 0 var(--gray-200, #525252) inset;\n}\n\n/* Popup */\n.ReactModal__Body--open .dhiwise_body,\n.tox-dialog__disable-scroll .dhiwise_body,\n.ReactModal__Body--open .fullScreen .drawer {\n    filter: blur(5px);\n    transition: fillter 0.3s;\n}\n\n.min-h-64 {\n    min-height: 16rem;\n}\n.min-h-auto{\n    min-height:auto !important;\n}\n\n.border-b-1 {\n    border-bottom-width: 1px;\n}\n\n\n\n.colorChangeSvg .a {\n    fill: #fff;\n}\n\n.ReactModal__Body--open {\n    overflow: hidden;\n}\n\n\n.bg-transparent {\n    background-color: transparent !important;\n}\n\n.top-49 {\n    top: 49px;\n}\n\n/* toggle */\n.toggleBox:last-child {\n    border-right: none;\n}\n\n/* select */\n.spark-select svg {\n    fill: var(--color--black-svg) !important;\n}\n\n.bg-opacity-80 {\n    background: rgba(0, 0, 0, 0.8);\n}\n\n.ReactModalPortal .ReactModal__Overlay {\n    z-index: 999999 !important;\n    background: rgba(0, 0 ,0 ,0.73);\n}\n.ReactModalPortal .ReactModal__Overlay.backPopup{\n    z-index: 9999 !important;\n}\n\n.groupSelect {\n    margin: 0 -18px;\n}\n\n/* buildDropdown */\n.buildDropdown {\n    position: fixed !important;\n    /* bottom: 30px;\n    left: 50px !important;\n    right: auto !important; */\n    overflow: visible !important;\n}\n.position-div.menuBottom{\n    /* position: fixed !important; */\n    bottom: 30px;\n    left: 50px !important;\n    right: auto !important;\n    min-width: 200px !important;\n}\n/* accordin */\n[aria-expanded=\"false\"] .uparrow {\n    display: none;\n}\n\n[aria-expanded=\"true\"] .downarrow {\n    display: none;\n}\n\n/* header */\n.headerAccountDropdown {\n    padding: 0 !important;\n    min-width: 327px !important;\n}\n@media(max-width:767px){\n    .position-div.right.headerAccountDropdown{\n        min-width: 290px !important;\n        width:290px;\n        right: -10px !important;\n    }\n}\n.schemaDropdown{\n    min-width: 200px !important;\n}\n\n/* project  */\n.projectListDropdown{\n    min-width: 220px !important;\n}\n.projectAppGroup:hover .projectAppList,\n.projectGroup:hover .projectList{\n    display: flex;\n}\n.projectAppGroup:first-child{\n    border-top: none;\n}\n\n/* space */\n.-right-100 {\n    right: -100%;\n}\n\n\n.min-h-body {\n    min-height: calc(100vh - 48px);\n}\n\n.notifyMesseg .min-h-body {\n    min-height: calc(100vh - 84px);\n}\n\n/* drawer size */\n.drawerSize {\n    width: 690px;\n}\n\n.gadient {\n    background: linear-gradient(to top, black, transparent);\n}\n\n/* folder select */\n.codeFolderListDisable .rstm-tree-item{\n    cursor: not-allowed;\n}\n.rstm-tree-item--active {\n    background-color: var(--color-bg-primary);\n}\n\n.rstm-tree-item--active .defultSelect,\n.activeSelect {\n    display: none;\n}\n\n.rstm-tree-item--active .activeSelect,\n.defultSelect {\n    display: block;\n}\n\n.leftFolder .rstm-tree-item--active svg {\n    fill: #fff !important;\n}\n\n.leftFolder .rstm-tree-item .tagLabelBox {\n    width: 100%;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    display: flex;\n    align-items: center;\n}\n.leftFolder .tagGroup {\n    width: 100%;\n}\n.rstm-tree-item {\n    width: 100%;\n    padding-top: .15rem;\n    padding-bottom: .15rem;\n    border: 1px solid transparent;\n    display: flex;\n}\n\n.rstm-tree-item--focused {\n    border: 1px solid var(--color-bg-primary) !important;\n}\n\n/* desciption doted */\n.descriptionDoted {\n    max-height: 48px;\n    -webkit-line-clamp: 2;\n    -webkit-box-orient: vertical;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    line-height: 1.625;\n    overflow: hidden;\n    display: -webkit-box;\n}\n\n/* input autofill */\ninput:-webkit-autofill,\ninput:-webkit-autofill:hover,\ninput:-webkit-autofill:focus,\ntextarea:-webkit-autofill,\ntextarea:-webkit-autofill:hover,\ntextarea:-webkit-autofill:focus {\n    border: 1px solid var(--color-gray-70);\n    -webkit-text-fill-color: var(--color-text-primary);\n    -webkit-box-shadow: 0 0 0px 1000px var(--color-gray-input) inset;\n    transition: background-color 5000s ease-in-out 0s;\n}\n\n\n.fillnone{\n    fill: none !important;\n}\n.word-break{\n    word-break: break-word;\n}\n.min-w-40{\n    min-width: 10rem;\n}\n.min-w-32{\n    min-width: 8rem;\n}\n/* Input */\ninput::-webkit-calendar-picker-indicator {\n    display: none;\n}\ninput{\n    caret-color: var(--color-text-primary);\n}\n.max-w-48{\n    max-width: 12rem;\n}\n.lifeCycleAction .lifeCycleActionList:first-child,\n.firstBorderNone .listClass:first-child{\n    border-top: none;\n}\n/* group hover */\n.groupBox:hover .groupItem{\n    display: block;\n}\n.imgHoverGroup:hover .imgHover{\n    display: block;\n}\n.imgHoverGroup:hover .imgDefault{\n    display: none;\n}\n.primaryShadow:focus{\n    box-shadow: 0 0 0 3px rgb(0 97 255 / 40%);\n}\n.dangerShadow:focus{\n    box-shadow: 0 0 0 3px rgba(var(--color-button-danger), 40%);\n}\n.ghostShadow:focus{\n    /* box-shadow: 0 0 0 3px rgba(var(--color-button-ghost), 40%); */\n    box-shadow: 0 0 0 3px rgba(var(--color-button-secondary), 40%);\n}\n.outlineShadow:focus{\n    box-shadow: 0 0 0 3px rgb(var(--color-button-outline), 40%);\n}\n.secondaryShadow:focus{\n    box-shadow: 0 0 0 3px rgba(var(--color-button-secondary), 40%);\n}\n.groupBox:hover .imgClass{\n    transform: scale(1.7);\n}\n.screenFilter .position-div{\n    min-width: 320px !important;\n}\n\n/* Chrome, Safari, Edge, Opera */\ninput::-webkit-outer-spin-button,\ninput::-webkit-inner-spin-button {\n  -webkit-appearance: none;\n  margin: 0;\n}\n\n/* Firefox */\ninput[type=number] {\n  -moz-appearance: textfield;\n}\n\n.z-100{\n    z-index: 100 !important;\n}\n@media(max-width:767px){\n    .memberDropdown{\n        min-width: 290px !important;\n        width: 290px;\n    }\n}\n\n.react-select__indicator{\n    padding: 6px !important; \n}\n\n.shadows-box{\n    box-shadow: 0 0 20px 6px rgba(var(--color-black-100), 58%);\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/drawer.css",
    "content": ".drawer {\n  position: fixed;\n  z-index: 100000;\n  transition: width 0s ease 0.3s, height 0s ease 0.3s, transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer > * {\n  transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), box-shadow 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer.drawer-open {\n  transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer .drawer-mask {\n  background: #000;\n  opacity: 0;\n  width: 100%;\n  height: 0;\n  position: absolute;\n  top: 0;\n  left: 0;\n  transition: opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), height 0s ease 0.3s;\n}\n.drawer-content-wrapper {\n  position: absolute;\n  background: var(--color-gray-black);\n}\n.drawer-content {\n  overflow: auto;\n  z-index: 1;\n  position: relative;\n}\n.drawer-handle {\n  position: absolute;\n  top: 72px;\n  width: 41px;\n  height: 40px;\n  cursor: pointer;\n  z-index: 0;\n  text-align: center;\n  line-height: 40px;\n  font-size: 16px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background: #fff;\n}\n.drawer-handle-icon {\n  width: 14px;\n  height: 2px;\n  background: #333;\n  position: relative;\n  transition: background 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer-handle-icon:before,\n.drawer-handle-icon:after {\n  content: '';\n  display: block;\n  position: absolute;\n  background: #333;\n  width: 100%;\n  height: 2px;\n  transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer-handle-icon:before {\n  top: -5px;\n}\n.drawer-handle-icon:after {\n  top: 5px;\n}\n.drawer-left,\n.drawer-right {\n  width: 0%;\n  height: 100%;\n}\n.drawer-left .drawer-content,\n.drawer-right .drawer-content{\n  display: flex;\n  flex-direction: column;\n}\n.drawer-left .drawer-content-wrapper,\n.drawer-right .drawer-content-wrapper,\n.drawer-left .drawer-content,\n.drawer-right .drawer-content {\n  height: 100%;\n}\n.drawer-left.drawer-open,\n.drawer-right.drawer-open {\n  width: 100%;\n}\n.drawer-left.drawer-open.no-mask,\n.drawer-right.drawer-open.no-mask {\n  width: 0%;\n}\n.drawer-left {\n  top: 0;\n  left: 0;\n}\n.drawer-left .drawer-handle {\n  right: -40px;\n  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n  border-radius: 0 4px 4px 0;\n}\n.drawer-left.drawer-open .drawer-content-wrapper {\n  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);\n}\n.drawer-right {\n  top: 0;\n  right: 0;\n}\n.drawer-right .drawer-content-wrapper {\n  right: 0;\n}\n.drawer-right .drawer-handle {\n  left: -40px;\n  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);\n  border-radius: 4px 0 0 4px;\n}\n.drawer-right.drawer-open .drawer-content-wrapper {\n  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);\n}\n.drawer-right.drawer-open.no-mask {\n  right: 1px;\n  transform: translateX(1px);\n}\n.drawer-top,\n.drawer-bottom {\n  width: 100%;\n  height: 0%;\n}\n.drawer-top .drawer-content-wrapper,\n.drawer-bottom .drawer-content-wrapper,\n.drawer-top .drawer-content,\n.drawer-bottom .drawer-content {\n  width: 100%;\n}\n.drawer-top .drawer-content,\n.drawer-bottom .drawer-content {\n  height: 100%;\n}\n.drawer-top.drawer-open,\n.drawer-bottom.drawer-open {\n  height: 100%;\n}\n.drawer-top.drawer-open.no-mask,\n.drawer-bottom.drawer-open.no-mask {\n  height: 0%;\n}\n.drawer-top .drawer-handle,\n.drawer-bottom .drawer-handle {\n  left: 50%;\n  margin-left: -20px;\n}\n.drawer-top {\n  top: 0;\n  left: 0;\n}\n.drawer-top .drawer-handle {\n  top: auto;\n  bottom: -40px;\n  /* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); */\n  border-radius: 0 0 4px 4px;\n}\n.drawer-top.drawer-open .drawer-content-wrapper {\n  /* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); */\n}\n.drawer-bottom {\n  bottom: 0;\n  left: 0;\n}\n.drawer-bottom .drawer-content-wrapper {\n  bottom: 0;\n}\n.drawer-bottom .drawer-handle {\n  top: -40px;\n  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);\n  border-radius: 4px 4px 0 0;\n}\n.drawer-bottom.drawer-open .drawer-content-wrapper {\n  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);\n}\n.drawer-bottom.drawer-open.no-mask {\n  bottom: 1px;\n  transform: translateY(1px);\n}\n.drawer.drawer-open .drawer-mask {\n  opacity: .73;\n  height: 100%;\n  transition: opacity 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.drawer.drawer-open .drawer-handle-icon {\n  background: transparent;\n}\n.drawer.drawer-open .drawer-handle-icon:before {\n  transform: translateY(5px) rotate(45deg);\n}\n.drawer.drawer-open .drawer-handle-icon:after {\n  transform: translateY(-5px) rotate(-45deg);\n}\n\n.drawer-content-wrapper{\n  width: 690px;\n}\n.drawer-right .drawer-content-wrapper{\n  border-left: 1px solid var(--color-gray-100);\n}\n.drawer-left .drawer-content-wrapper{\n  border-right: 1px solid var(--color-gray-100);\n}\n.fullScreen .drawer-content-wrapper{\n  width: 100%;\n  border: none;\n}\n.smallSidebar .drawer-content-wrapper{\n  width: 520px;\n}\n@media (max-width:767px) {\n  .mobileDrawer .drawer-content-wrapper{\n    width: 300px;\n  }\n  .mobileDrawer2 .drawer-content-wrapper{\n    width: 90%;\n  }\n}\n.drawer-bottom .drawer-mask{\n  display: none;\n}\n.drawer-bottom .drawer-content{\n  box-shadow: rgb(0 0 0 / 8%) 4px -3px 13px 0px;\n  border: 1px solid var(--color-gray-100);\n  background-color: var(--color-gray-black);\n}\n.ant-scrolling-effect .dhiwise_body{\n  filter: blur(5px);\n  transition: fillter 0.3s;\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/dropdown.css",
    "content": "\n.dropdown-menu:hover {\n    background-color: #0061ff;\n    color: #fff;\n}\n\n.dropdown-menu:hover svg {\n    fill: #fff;\n}\n.dropdown-min{\n    min-width: min-content !important;\n}\n.border-primary-light {\n    border-color: #e9f1ff;\n}\n\n.primary-gray-text-color {\n    color: var(--color-text-primary);\n}\n\n.show {\n    display: block !important;\n}\n\n.position-div.right {\n    right: 0 !important;\n    left: auto !important;\n}\n\n.position-div.left {\n    left: 0 !important;\n    right: auto !important;\n}\n\n.position-div {\n    background: var(--color-bg-white) !important;\n    border: 1px solid var(--color-gray-90);\n    border-radius: 0 0 5px 5px;\n    /* box-shadow: none !important; */\n    box-shadow: rgba(0, 0, 0, 0.06) 0px 8px 16px 0px !important;\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/editor.css",
    "content": ".monaco-editor,\n.monaco-editor-background,\n.monaco-editor .inputarea.ime-input {\n    background-color: var(--color-gray-black) !important;\n}\n\n.monaco-editor .margin {\n    background-color: var(--color-gray-black) !important;\n}\n\n.mtk4,\n.mtk9,\n.mtk1 {\n    color: var(--color-gray-white) !important;\n}\n\n.mtk5 {\n    color: var(--color-bg-secondary) !important;\n}\n.readonlyEditor .monaco-editor .view-lines {\n    cursor: not-allowed !important;\n}\n\n.readonlyEditor .monaco-editor .selected-text {\n    background-color: transparent !important;\n}\n\n.readonlyEditor .monaco-mouse-cursor-text {\n    cursor: no-drop !important;\n    background: transparent !important;\n    border: none !important;\n    color: transparent !important;\n}\n.smallEditor .margin-view-overlays{\n    display: none;\n}\n.kCxsfG{\n    padding: 12px !important;\n    background-color: var(--color-gray-200) !important;\n}\n.copyPestCode pre,\n.copyPestCode code{\n    font-size: 14px;\n}\n.htmlDescription a{\n    color: var(--color-text-dark);\n    margin: 0 4px; \n    display: inline-block;\n}\n.copyEditor button .icon{\n    display: none;\n}\n@media(max-width:1280px){\n    .copyPestCode pre,\n    .copyPestCode code{\n        font-size: 12px;\n    }\n}"
  },
  {
    "path": "packages/client/src/assets/css/logo.css",
    "content": ".themeLogo .c,\n.themeLogo .st2 {\n    fill: var(--color--black-svg);\n}\n\n.themeLogo .a,\n.themeLogo .st0 {\n    fill: var(--color--secondry-svg);\n}\n\n.themeLogo .b,\n.themeLogo .st1 {\n    fill: var(--color--theme-svg);\n}\n\n.themeSmallLogo .cls-1,\n.themeSmallLogo .cls-4 {\n    fill: none;\n}\n\n.themeSmallLogo .cls-2 {\n    clip-path: url(#clip-path);\n}\n\n.themeSmallLogo .cls-3 {\n    opacity: 0.5;\n}\n\n.themeSmallLogo .cls-4 {\n    stroke: #e0e0e0;\n    stroke-miterlimit: 10;\n}\n\n.themeSmallLogo .cls-5 {\n    fill: var(--color--secondry-svg);\n}\n\n.themeSmallLogo .cls-6 {\n    fill: var(--color--theme-svg);\n}\n\n.themeWhiteLogo .cls-1 {\n    fill: var(--color--black-svg);\n}"
  },
  {
    "path": "packages/client/src/assets/css/main.css",
    "content": ""
  },
  {
    "path": "packages/client/src/assets/css/method.css",
    "content": "\n/* methodList */\n.methodList {\n    border: 1px solid var(--color-bg-active);\n    color: var(--color-bg-active);\n    border-radius: var(--border-radius);\n    padding: 0.1rem 0.1rem;\n    font-size: 12px;\n    line-height: 20px;\n}\n\n.methodList.put {\n    border: 1px solid var(--color-bg-yellow);\n    color: var(--color-bg-yellow);\n}\n\n.methodList.post {\n    border: 1px solid var(--color-bg-active);\n    color: var(--color-bg-active);\n}\n\n.methodList.delete {\n    border: 1px solid var(--color-bg-deactive);\n    color: var(--color-bg-deactive);\n}\n\n.methodList.get {\n    border: 1px solid var(--color-bg-gray);\n    color: var(--color-bg-gray);\n}\n\n.methodList.patch {\n    border: 1px solid var(--color-bg-blue);\n    color: var(--color-bg-blue);\n}\n\n.methodList.head {\n    border: 1px solid var(--color-bg-orange);\n    color: var(--color-bg-orange);\n}\n\n.methodList.options {\n    border: 1px solid var(--color-bg-pink);\n    color: var(--color-bg-pink);\n}\n\n.methodList.purge {\n    border: 1px solid var(--color-bg-lightGreen);\n    color: var(--color-bg-lightGreen);\n}\n\n.methodList.link {\n    border: 1px solid var(--color-bg-lightblue);\n    color: var(--color-bg-lightblue);\n}\n\n.methodList.unlink {\n    border: 1px solid var(--color-bg-lightorange);\n    color: var(--color-bg-lightorange);\n}\n\n/* node dashboard */\n.nodeManageOperation{\n\n}\n\n@media (max-width:1379px){\n    .menuShortCut:nth-last-child(4){\n        border-bottom: 1px solid var(--color-gray-200);\n    }\n}\n/* app tag */\n.application-NODE_EXPRESS{\n    background-color: rgba(var(--color-node-app),25%);\n    color: rgba(var(--color-node-app),100%);\n    border: none;\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/notification.css",
    "content": "/* notification */\n.react-toast-notifications__container {\n    z-index: 1000000 !important;\n}\n\n.react-toast-notifications__toast.react-toast-notifications__toast--error .react-toast-notifications__toast__icon-wrapper {\n    background-color: transparent;\n    color: var(--color-bg-deactive);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.react-toast-notifications__toast.react-toast-notifications__toast--error {\n    background: var(--color-bg-redlight);\n    border-left: 3px solid var(--color-bg-deactive);\n    color: var(--color-message);\n    box-shadow: none;\n    align-items: center;\n    border-radius: var(--border-radius);\n}\n\n.react-toast-notifications__toast.react-toast-notifications__toast--error .react-toast-notifications__toast__content {\n    line-height: normal;\n    min-height: max-content;\n    font-weight: 600;\n}\n\n.react-toast-notifications__toast__dismiss-button {\n    display: flex;\n}\n\n.react-toast-notifications__toast__dismiss-button svg {\n    fill: var(--color-message) !important;\n}"
  },
  {
    "path": "packages/client/src/assets/css/popover.css",
    "content": ".popupCustom {\n    z-index: 100000000;\n}\n.popupCustom .Popover-body{\n    /* background-color: var(--color-bg-popover); */\n    background: var(--color-bg-white) !important;\n    border: 1px solid var(--color-gray-90);\n    border-radius: 0 0 5px 5px;\n    box-shadow: rgb(0 0 0 / 6%) 0px 8px 16px 0px !important;\n    padding: 20px;\n}\n\n.Popover-tip {\n    fill: var(--color-bg-white);\n}\n\n.popoverArrow:before {\n    content: \"\";\n    width: 0;\n    height: 0;\n    border-left: 10px solid transparent;\n    border-right: 10px solid transparent;\n    border-top: 10px solid #0061ff;\n    position: absolute;\n    bottom: -11px;\n    left: 0;\n    right: 0;\n    margin: auto;\n}\n\n.popoverArrow-top {\n    /* content: \"\"; */\n    width: 0;\n    height: 0;\n    border-left: 10px solid transparent;\n    border-right: 10px solid transparent;\n    border-bottom: 10px solid #0061ff;\n    position: absolute;\n    bottom: -11px;\n    left: 0;\n    right: 0;\n    margin: auto;\n}"
  },
  {
    "path": "packages/client/src/assets/css/popoverCss.js",
    "content": "export const PopoverCss = {\n  popoverWrap: ' relative p-3 bg-popover shadows-dw rounded z-1000000',\n};\n"
  },
  {
    "path": "packages/client/src/assets/css/scroll.css",
    "content": "\n\n/* scroll */\n::-webkit-scrollbar {\n    width: 4px;\n    height: 4px;\n    background: transparent;\n}\n\n/* Track */\n::-webkit-scrollbar-track {\n    background: transparent;\n}\n\n/* Handle */\n::-webkit-scrollbar-thumb {\n    background: var(--color-gray-20);\n    border-radius: 10px;\n}\n\n.contatinerBox {\n    max-width: 1300px;\n}\n\n.scrollbar-container.vertical,\n.scrollbar-container.horizontal {\n    background: transparent !important;\n    opacity: 1 !important;\n}\n\n.scrollarea .scrollbar-container.vertical .scrollbar,\n.scrollarea .scrollbar-container.horizontal .scrollbar {\n    background-color: var(--color-gray-0) !important;\n    opacity: 0.3;\n}\n\n.scrollbar-container.vertical .scrollbar,\n.scrollbar-container.vertical {\n    width: 4px !important;\n    margin-left: 0 !important;\n    border-radius: 10px;\n}\n\n.scrollbar-container.horizontal .scrollbar,\n.scrollbar-container.horizontal {\n    height: 4px !important;\n    margin-top: 0 !important;\n    border-radius: 10px;\n}\n"
  },
  {
    "path": "packages/client/src/assets/css/sidebar.css",
    "content": "@import \"./tailwind.css\";\n.pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu > .pro-inner-item > .pro-arrow-wrapper .pro-arrow{\n    border-color: var(--color-bg-black) !important;\n}\n.pro-sidebar{\n    width: 100% !important;\n    min-width: 100% !important;\n}\n.pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item:hover,\n.pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item:focus{\n    color:var(--color-text-primary)\n}\n.pro-sidebar .pro-menu a:before{\n    content: none !important;\n}\n.sidebar-dropdown{\n    position: fixed !important; \n    left: auto !important;\n}\n.theme-sidenav .pro-sidebar{\n    width: var(--sidebar-width);\n    min-width: var(--sidebar-width);\n    z-index: 0;\n}\n.theme-sidenav{\n    width: var(--sidebar-width);\n}\n.theme-sidenav .pro-sidebar .pro-menu{\n    padding: 0;\n}\n.theme-sidenav .pro-sidebar {\n    height: var(--sidebar-height);\n    position: sticky;\n    top: 49px;\n    z-index: 10000;\n}\n.theme-sidenav .pro-sidebar .pro-sidebar-inner{\n    /* border-right: 1px solid var(--color-gray-100); */\n    background-color: var(--color-gray-200);\n}\n.theme-sidenav .pro-item-content{\n    color:var(--color-text-primary);\n    font-weight: 600;\n}\n.theme-sidenav .pro-inner-item{\n    font-size: 14px;\n    display: flex;\n    align-items: center;\n    padding:12px 2px !important;\n    /* margin-bottom: 5px; */\n}\n.theme-sidenav .pro-inner-item:hover .pro-item-content{\n    color: var(--color-text-primary);\n}\n.theme-sidenav .pro-sidebar .pro-menu.shaped .pro-menu-item > .pro-inner-item > .pro-icon-wrapper{\n    background-color: transparent;\n    width: auto;\n    height: auto;\n    min-width: min-content;\n    /* position: absolute;\n    left: 8px; */\n    display: block !important;\n}\n.theme-sidenav .pro-sidebar .pro-menu.shaped .pro-menu-item.open > .pro-inner-item > .pro-icon-wrapper{\n    transform: rotate(90deg);\n    -webkit-transform: rotate(90deg);\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu > .pro-inner-item > .pro-arrow-wrapper{\n    display: none;\n}\n.theme-sidenav .pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item{\n    background-color: transparent;\n}\n.theme-sidenav .pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item ul{\n    padding:0 !important;\n}\n.theme-sidenav .pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item ul li{\n    list-style: none;\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item{\n    padding: 5px;\n    padding-left: 35px;\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .react-slidedown .pro-inner-item{\n    padding-left: 45px;\n} \n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .react-slidedown .pro-menu-item \n.react-slidedown .pro-inner-item{\n    padding-left: 60px;\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item:before{\n    content: none;\n    width: auto;\n    border: none;\n    box-shadow: none;\n    height: auto;\n    margin-right: 6px;\n    color: #111827;\n    background-color: transparent;\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item{\n    padding: 0;\n    overflow: hidden;\n}\n.theme-sidenav .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-menu-item{\n    padding-left:0;\n}\n.theme-sidenav .pro-icon-wrapper{\n    margin-right:8px;\n}\n.theme-sidenav .pro-sidebar > .pro-sidebar-inner > .pro-sidebar-layout,\n.theme-sidenav .pro-sidebar .scrollarea-content{\n    overflow: visible;\n}\n\n.sidebar-Box{\n    width: var(--sidebar-width);\n    min-width: var(--sidebar-width);\n    height: 100%;\n    /* height: var(--sidebar-height) !important; */\n}\n\n\n/* permission list */\n\n.permission-list .pro-sidebar{\n    width: 100% !important;\n}\n.permission-list .pro-arrow-wrapper{\n    /* left: 0;right: auto !important; */\n    display: none;\n}\n.permission-list .pro-sidebar-inner{\n    background-color: var(--color-bg-light);\n}\n.permission-list .pro-inner-item{\n    color: var(--color-text-primary);\n}\n.permission-list .pro-sidebar .pro-menu,\n.permission-list .pro-sidebar > .pro-sidebar-inner > .pro-sidebar-layout ul{\n    padding: 0 !important;\n}\n.permission-list .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item:before{\n    content: none;\n}\n.permission-list .pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item{\n    background-color: transparent;\n}\n.permission-list .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item > .pro-icon-wrapper{\n    display: block;\n    width: auto;\n    height: auto;\n    min-width: 16px;\n}\n.permission-list .pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item{\n    padding: 0 !important;\n}\n.permission-list .pro-menu-item.open > .pro-inner-item > .pro-icon-wrapper{\n    transform: rotate(90deg);\n}\n.permissionSub:last-child{\n    border-bottom: none;\n}\n.permission-list .pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item:hover{\n    color: var(--color-text-primary);\n}\n\n\n/* constant */\n.sidebar-list.pro-sidebar{\n    width: 100%;\n    min-width: 100%;\n    height: 100%;\n}\n.sidebar-list .pro-sidebar-inner{\n    background-color: var(--color-gray-300) !important; \n    border-right:1px solid var(--color-gray-100);\n    height: 100%;\n}\n.sidebar-list.pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item{\n    background-color: transparent;\n}\n.sidebar-list.pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item ul{\n    padding: 0;\n}\n/* .sidebar-list.pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item:before{\n    content: none;\n} */\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item.sidebarDropdown > .pro-inner-item{\n    padding: 8px 20px 8px 35px;\n}\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item .pro-inner-item:before{\n    display: none;\n}\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu .pro-inner-list-item{\n    padding: 0;\n}\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item.pro-sub-menu > .pro-inner-item > .pro-arrow-wrapper{\n    left: 10px;\n    right: auto;\n}\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item > .pro-item-content{\n    display: block;\n}\n.sidebar-list.pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item{\n    padding:4px 8px;\n}\n.screenFeature.pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item{\n    padding:0;\n}\n.screenFeature.sidebar-list .pro-sidebar-inner{\n    border-right: 1px solid var(--color-gray-200);\n}\n/* Project */\n.project-sidebar .pro-icon-wrapper{display: none !important;}\n.project-sidebar .pro-arrow-wrapper{\n    position: absolute;\n    left: 11px;\n    top: 4px !important;\n    bottom: 0;\n    margin: auto;\n    right: auto !important;\n    transform: translate(0,0) !important;\n}\n.project-sidebar .pro-item-content{\n    color:var(--color-text-primary);\n    font-size: 16px;\n}\n.project-sidebar .pro-menu-item .pro-inner-item{\n    padding: 8px 30px !important;\n}\n.project-sidebar .pro-inner-list-item{\n    padding: 0 !important;\n}\n.project-sidebar .pro-inner-list-item ul{\n    padding: 0 !important;\n}\n.project-sidebar.pro-sidebar .pro-menu > ul > .pro-sub-menu > .pro-inner-list-item{\n    background-color: transparent !important;\n}\n.project-sidebar.pro-sidebar > .pro-sidebar-inner{   \n    background-color: var(--color-gray-300);\n    border-right: 1px solid var(--color-gray-100);\n}\n/* profile */\n.profile-sidebar{\n    width: var(--profile-sidebar-width);\n}\n.profile-sidebar .pro-sidebar-inner{\n    border-right: 1px solid var(--color-gray-200) !important;\n    background-color: var(--color-bg-light) !important; \n}\n\n/* } */\n.layoutStep .pro-sidebar > .pro-sidebar-inner{\n    background-color: transparent;\n}\n.layoutStep .pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item > .pro-item-content{\n    white-space: normal;\n}\n.layoutStep .pro-sidebar .pro-menu .pro-menu-item > .pro-inner-item{\n    padding: 8px 10px 8px 10px;\n}\n/* model */\n.modelList .pro-sidebar > .pro-sidebar-inner > .pro-sidebar-layout{\n    overflow: visible;\n}\n/* suToggle */\n.smallToggle{\n    width: calc(100%  - 3rem);\n}"
  },
  {
    "path": "packages/client/src/assets/css/tab.js",
    "content": "export const TabCSs = {\n  tabHead: 'border-b border-gray-100 bg-transparent flex',\n  tabHeadBody: 'bg-gray-300',\n  tabTitle: 'border-0 text-gray-600 pt-3 pb-2 pl-4 pr-4 cursor-pointer focus:outline-none text-primary-text text-sm',\n  tabSmallTitle: 'border-0 text-gray-600 pt-2 pb-2 pl-4 pr-4 text-xs cursor-pointer focus:outline-none text-primary-text',\n  selectTab: 'font-bold text-primary-text border-b-2 border-primary-dark',\n  tabVerList: '',\n  tabVerHead: 'h-full border-r border-gray-100 bg-gray-300',\n  tabVerTitle: 'border-b border-gray-100 text-gray-600 px-3 py-2.5 text-xs cursor-pointer focus:outline-none text-primary-text flex items-center',\n  tabVerTitle1: 'text-gray-600 px-3 py-2.5 text-xs cursor-pointer focus:outline-none text-primary-text flex items-center',\n  tabVerTitleSmall: 'border-b border-gray-100 text-gray-600 px-1 py-1 text-xxs  cursor-pointer focus:outline-none text-primary-text flex items-center',\n  tabVerselectTab: 'font-bold text-defaultWhite bg-primary-dark',\n  tabVerSelectTab1: 'border-l-2 border-primary-dark bg-gray-100',\n  tabverTitleName: 'truncate block font-normal',\n\n  TabStepSelect: 'bg-primary-dark',\n  TabStepList: '',\n  TabStepListItem: 'w-8 h-8 rounded-full flex items-center justify-center bg-gray-200 cursor-pointer m-auto relative',\n};\n"
  },
  {
    "path": "packages/client/src/assets/css/tableViewCss.js",
    "content": "export const TableViewCss = {\n  // grid grid-cols-10\n  // grid grid-cols-10 gap-4\n  tableHead: 'pl-10 text-sm items-center py-1.5 px-0 sticky top-0 z-10 bg-gray-200 px-3',\n  tableRow: 'pl-10',\n  tableSequence: 'absolute w-3 h-3 left-3 opacity-70  cursor-move top-2.5 m-auto',\n  tableCollapse: 'absolute w-3 h-3 z-1 left-14 cursor-pointer top-2.5 m-auto',\n  tableClose: 'w-3.5 h-3.5 flex items-center cursor-pointer absolute left-8 top-2.5 m-auto z-1',\n  addValue: 'text-xs ml-1 text-gray-white flex underline items-center cursor-pointer labelGroup focus:outline-none focus:text-primary-dark',\n  tableCheckBox: 'flex',\n  subTable: 'subAtt mx-5 px-2 mt-4 bg-gray-200 p-2',\n  subTableRow: 'pl-5 group relative',\n  subTableClose: 'w-4 h-4 cursor-pointer absolute left-5 top-3.5 m-auto z-10',\n  subTableCheckBox: 'flex',\n};\n"
  },
  {
    "path": "packages/client/src/assets/css/tailwind.css",
    "content": "@import \"tailwindcss/base\";\n@import \"tailwindcss/components\";\n@import \"./components/components.css\";\n@import \"tailwindcss/utilities\";\n\n.theme-black {\n  --color-bg-primary: #0061ff;\n  --color-blue-10:#d2e1fd;\n  --color-blue-100:#082452;\n  --color-bg-primary-light: #f0f6ff;\n  --color-bg-secondary: #FF800D;\n  --color-secondary-90:#803d00;\n  --color-secondary-70: #D26400;\n  --color-bg-default-light: #232323;\n  --color-bg-inverse: #0F72FE;\n  --color-blue-10: #ebf2ff;\n  --color-bg-light: #232323;\n  --color-bg-softlight: #f5f9ff;\n  --color-bg-white: #313131;\n  --color-bg-black:#fafafa;\n  --color-bg-popover:#232323;\n  --color-bg-headerSearch:#3e3e3e;\n  --color-bg-greenLight:#28462f;\n  /* --color-bg-redstatus:#7b292d; */\n  --color-bg-body:#0e0e0e;\n  --color-bg-active:#009E25;\n  --color-bg-deactive:#FF340D;\n  --color-bg-redlight:#fff1f1;\n  --color-bg-gray:#828282;\n  --color-bg-yellow:#f0bf15;\n  --color-bg-blue:#4589ff;\n  --color-bg-orange:#FF800D;\n  --color-bg-pink:#fd5bec;\n  --color-bg-lightGreen:#5cfdcd;\n  --color-bg-lightblue:#7a87ff;\n  --color-bg-lightorange:#ff9c2a;\n  --color-node-app:83,158,67;\n\n  --color-placeholder-primary: #b2b2b2;\n  --color-placeholder-gray: #818385;\n\n  --color-black-100: 0,0,0;\n  --color-notfound-bg:#262626;\n  --color-gray-black: #0e0e0e;\n  --color-gray-300:#131313;\n  --color-gray-350: #1b1b1b;\n  --color-gray-200:#232323;\n  --color-gray-100:#313131;\n  --color-gray-90: #3e3e3e;\n  --color-gray-80: #313131; /*sidebar Bottom*/\n\n  --color-gray-70: #424242;\n  --color-gray-60: #525252;\n  --color-gray-50: #646464;\n  --color-gray-40: #7e7e7e;\n  --color-gray-30: #828282;\n  --color-gray-20: #959595;\n  --color-gray-10: #b2b2b2;\n  --color-gray-0: #F1F1F1;\n  --color-gray-input:#3e3e3e;\n  --color-gray-inputSub:#131313;\n  --color-select-dropdown:#3e3e3e;\n  --color-code-button:#424242;\n\n  --color-button-outline:66,66,66;\n  --color-button-secondary:35,35,35;\n  --color-button-danger:255,52,13;\n  --color-button-ghost:190,214,255;\n  \n  --color-gray-white: #ffffff;\n\n  --color-gray-checkbox: #282828;\n  --color-border-default-light:#232323;\n\n  --color-button-text:#ffffff;\n  --color-outline-button-text:#ffffff;\n  --color-dashedbutton-text:#ffffff;\n  --color-dashedbutton-text:#ffffff;\n  --color-button-outline-border:#ffffff;\n\n  --color-text-primary: #fff;\n  --color-text-dark:#0F72FE;\n  --color-text-white: #232323;\n  --color-text-secondary:#f3f3f3;\n  --color-text-body:#bababa; \n  /* //dcdcdc */\n  --color-text-error:#FF340D;\n  --color-message:#232323;\n\n  --color--black-svg: #fafafa;\n  --color--white-svg: #232323;\n  --color--theme-svg: #fff;\n  --color--secondry-svg: #fff;\n  --color-active-text:#fff;\n  --color-deactive-text:#fff;\n\n  --box-shadow-primary:1px 0px 16px 0px rgba(0 ,97, 255 , 0.26);\n  --box-shadow:rgba(0, 0, 0, 0.06) 0px 8px 16px 0px;\n\n  --font-theme-DW1: 600;\n  --border-radius:3px;\n\n  --sidebar-width:55px;\n  --profile-sidebar-width:230px;\n  --sidebar-height:calc(100vh - 48px);\n\n  --font-famliy:'circular';\n  --font-title-famliy:'circular';\n\n}\n.theme-white {\n  --color-bg-primary: #0061ff;\n  --color-blue-10:#d2e1fd;\n  --color-blue-100:#082452;\n  --color-bg-primary-light: #f0f6ff;\n  --color-bg-secondary: #FF800D;\n  --color-secondary-90:#803d00;\n  --color-secondary-70: #D26400;\n  --color-bg-default-light: #f5f9ff;\n  --color-bg-inverse: #f0f6ff;\n  --color-blue-10: #ebf2ff;\n  --color-bg-light: #fafafa;\n  --color-bg-softlight: #f5f9ff;\n  --color-bg-white: #fff;\n  --color-bg-black:#232323;\n  --color-bg-popover:#fff;\n  --color-bg-headerSearch:#fff;\n  --color-bg-greenLight:#c7eacf;\n  /* --color-bg-redstatus:#f4bec1; */\n  --color-bg-body:#ffffff;\n  --color-bg-active:#009E25;\n  --color-bg-deactive:#FF340D;\n  --color-bg-redlight:#fff1f1;\n  --color-bg-gray:#828282;\n  --color-bg-yellow:#cca10c;\n  --color-bg-blue:#4589ff;\n  --color-bg-orange:#FF800D;\n  --color-bg-pink:#fd5bec;\n  --color-bg-lightGreen:#2fb78e;\n  --color-bg-lightblue:#999bb3;\n  --color-bg-lightorange:#ff9c2a;\n  --color-node-app:83,158,67;\n\n\n  --color-placeholder-primary: #787878;\n  --color-placeholder-gray: #a1a1a1;\n\n  --color-black-100: 211,211,211;\n  --color-notfound-bg:#fff;\n  --color-gray-black: #ffffff;\n  --color-gray-300:#f8f8f8;\n  --color-gray-350: #f7f7f7;\n  --color-gray-200:#efefef;\n  --color-gray-100:#e9e9e9;\n  --color-gray-90: #e9e9e9;\n  --color-gray-80: #dcdcdc;\n  --color-gray-70: #8D8D8D;\n  \n  --color-gray-60: #787878;\n  --color-gray-50: #646464;\n  --color-gray-40: #525252;\n  --color-gray-30: #5c5c5c;\n  --color-gray-20: #4D4D4D;\n  --color-gray-10: #282828;\n  --color-gray-0: #232323;\n  --color-gray-white: #1D1D1D;\n  --color-gray-input:#fff;\n  --color-gray-inputSub:#fff;\n  --color-select-dropdown:#fff;\n  --color-code-button:#b3b3b3;\n\n  --color-button-outline:141,141,141;\n  --color-button-secondary:239,239,239;\n  --color-button-danger:255,52,13;\n  --color-button-ghost:190,214,255;\n\n  --color-gray-checkbox: #dcdcdc;\n  --color-border-default-light:#0061ff;\n\n  --color-button-text:#ffffff;\n  --color-outline-button-text:#0061ff;\n  --color-dashedbutton-text:#0061ff;\n  --color-dashedbutton-text:#0061ff;\n  --color-button-outline-border:#0061ff;\n\n  --color-text-primary: #232323;\n  --color-text-dark:#0061ff;\n  --color-text-white: #fff;\n  --color-text-secondary:#3e3e3e;\n  --color-text-body:#000000;\n  --color-text-error:#FF340D;\n  --color-active-text:#fff;\n  --color-deactive-text:#fff;\n\n  --color--black-svg: #232323;\n  --color--white-svg: #fafafa;\n  --color--theme-svg: #0061ff;\n  --color--secondry-svg: #ff800d;\n\n  --box-shadow-primary:1px 0px 16px 0px rgba(0 ,97, 255 , 0.09);\n  --box-shadow:rgba(0, 0, 0, 0.06) 0px 8px 16px 0px;\n  \n  --font-theme-DW1: 600;\n  --border-radius:3px;\n\n  --sidebar-width:55px;\n  --profile-sidebar-width:230px;\n  --sidebar-height:calc(100vh - 48px);\n  \n  --font-famliy:'circular';\n  --font-title-famliy:'circular';\n}\n.notifyMesseg {\n  --sidebar-height:calc(100vh - 84px);\n}"
  },
  {
    "path": "packages/client/src/assets/css/tooltip.css",
    "content": ".__react_component_tooltip {\n    background-color: var(--color-bg-black) !important;\n    color: var(--color-bg-light) !important;\n    font-weight: 600;\n    z-index: 10000 !important;\n    font-size: 14px !important;\n}\n\n.__react_component_tooltip.place-right:after {\n    border-right-color: var(--color-bg-black) !important;\n}\n\n.__react_component_tooltip.place-left:after {\n    border-left-color: var(--color-bg-black) !important;\n}\n\n.__react_component_tooltip.place-bottom:after {\n    border-bottom-color: var(--color-bg-black) !important;\n}\n\n.__react_component_tooltip.place-top:after {\n    border-top-color: var(--color-bg-black) !important;\n}"
  },
  {
    "path": "packages/client/src/components/APIKeyValue/index.js",
    "content": "/* eslint-disable radix */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport { isEmpty, toLower } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { Input } from '../Input';\nimport { Select } from '../Select';\nimport { DeleteIcon } from '../IconBox/DeleteIcon';\nimport { Checkbox } from '../Checkbox';\nimport { useBoolean } from '../hooks';\nimport { ConfirmationAlert } from '../ConfirmAlert';\nimport { TYPE_OPTIONS } from '../../constant/envVariable';\nimport { nodeKeyRegex } from '../../utils/regex';\nimport { APPLICATION_CODE } from '../../constant/Project/applicationStep';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../constant/common';\n\nexport const ValueComponent = ({ type, ...other }) => {\n  // customOptions name different it issue boolean\n  const options = other.customOptions ?? [];// constant for data type\n  const dataType = toLower(type);\n  if (dataType && toLower(options?.STRING) === dataType) return <Input size=\"medium\" WrapClassName=\"\" placeholder=\"Enter value\" {...other} />;\n  if (dataType && toLower(options?.LONG) === dataType) {\n    return (\n      <Input.Number\n        size=\"medium\"\n        WrapClassName=\"\"\n        placeholder=\"Enter value\"\n        {...other}\n        value={other.value ? other.value.toString() : ''}\n        onChange={(val) => other?.onChange(parseInt(val))}\n        fixLength={10}\n      />\n    );\n  }\n  if (dataType && [toLower(options?.FLOAT), toLower(options?.DOUBLE)].includes(dataType)) {\n    return (\n      <Input.Decimal\n        size=\"medium\"\n        WrapClassName=\"\"\n        placeholder=\"Enter value\"\n        {...other}\n        value={other.value ? other.value.toString() : ''}\n        onChange={(val) => other?.onChange(Number(val))}\n        fixLength={20}\n      />\n    );\n  }\n  if (dataType && toLower(options?.INTEGER) === dataType) {\n    return (\n      <Input.Number\n        size=\"medium\"\n        WrapClassName=\"\"\n        placeholder=\"Enter value\"\n        {...other}\n        value={other.value ? other.value.toString() : ''}\n        onChange={(val) => other?.onChange(parseInt(val))}\n        fixLength={10}\n      />\n    );\n  }\n  if (dataType && toLower(options?.BOOLEAN) === dataType) {\n    return (\n      <div className=\"tableInputSelect\">\n        <Select\n          sizeMedium\n          options={[{ id: 'true', name: 'TRUE' }, { id: 'false', name: 'FALSE' }]}\n          valueKey=\"id\"\n          {...other}\n          value={other?.value?.toString()}\n          onChange={(val) => {\n            other?.onChange(val ? val === 'true' : null);\n            other?.onAutoFocus?.();\n          }}\n          placeholder=\"Select value\"\n        />\n      </div>\n    );\n  }\n  return <Input size=\"medium\" WrapClassName=\"\" placeholder=\"Enter value\" {...other} />;\n};\n\nconst TableWrap = ({ children, className, inTableView }) => (inTableView ? <td className={className}>{children}</td> : children);\nexport const APIKeyValue = ({\n  isDelete, isTypeSelect, isValue, isCheckBox, isAutoSuggest, typeProps = {}, checkboxProps = {}, APIValue, envVariable, tableView, inputProps = {}, valueProps = {}, deleteProps = {}, autoSuggestProps = {}, inTableView = true,\n}) => {\n  const applicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const [isOpenDelete, showDelete, hideDelete] = useBoolean(false);\n  const valueRef = React.useRef(null);\n  const WrapCheckbox = (otherProps) => <Checkbox wrapClass=\"absolute left-7 top-1\" {...otherProps} />;\n  return (\n    <>\n      <TableWrap inTableView={inTableView} className={`pl-10 relative ${envVariable && 'relative pl-16 pr-3'} ${APIValue && 'pr-4 pb-4'}`}>\n        {isDelete && (\n          <DeleteIcon\n            size=\"small\"\n            disabled={deleteProps?.disabled}\n            icon={<Icons.Close />}\n            tooltip=\"Delete\"\n            className={`absolute  m-auto ${tableView ? 'left-0 top-4' : 'left-0 top-2'}`}\n            onClick={showDelete}\n          />\n        )}\n\n        {isCheckBox && <WrapCheckbox {...checkboxProps} />}\n        <div className={`${APIValue ? 'w-full' : 'tableInputSelect'}`}><Input maxLength={MAX_INPUT_FIELD_LIMIT.key} size=\"medium\" WrapClassName=\"\" placeholder=\"Enter key\" customRegex={nodeKeyRegex} {...inputProps} /></div>\n\n      </TableWrap>\n      {\n        isAutoSuggest && !isEmpty(inputProps?.value)\n        && (\n          <datalist id={autoSuggestProps?.id}>\n            {autoSuggestProps?.list?.map((option) => (\n              option.startsWith(inputProps?.value) && (\n              <option key={option} value={option}>\n                {option}\n              </option>\n              )\n            ))}\n          </datalist>\n        )\n      }\n\n      { isTypeSelect && (\n        <TableWrap inTableView={inTableView} className={`${APIValue && 'pb-4'}`}>\n          <div className={`${APIValue ? 'w-full' : 'tableInputSelect'}`}>\n            <Select\n              sizeMedium\n              WrapClassName=\"\"\n              placeholder=\"Select string\"\n              {...typeProps}\n              onChange={(val) => {\n                typeProps.onChange(val);\n                if (val) valueRef?.current?.focus();\n              }}\n              options={typeProps.options ? TYPE_OPTIONS(typeProps.options) : []}\n            />\n          </div>\n        </TableWrap>\n\n      )}\n\n      { isValue && (\n        <TableWrap inTableView={inTableView} className={`${APIValue && 'pb-4'}`}>\n          <div className={`${APIValue ? 'w-full' : 'tableInputSelect'}`}>\n            <ValueComponent\n              {...valueProps}\n              type={typeProps.value}\n              customOptions={typeProps.options}\n              ref={valueRef}\n            />\n          </div>\n        </TableWrap>\n      )}\n\n      { isOpenDelete\n        ? (\n          <ConfirmationAlert\n            isOpen={isDelete}\n            // eslint-disable-next-line no-nested-ternary\n            description={envVariable && applicationCode === APPLICATION_CODE.nodeExpress ? 'Environment variable will be deleted permanently and cannot be restored in the future.Are you sure do you want to delete this environment variable?' : 'Constant attribute will be deleted permanently and cannot be restored in the future.Are you sure do you want to delete this constant attribute?'}\n            handleSubmit={() => {\n              // isLoading(true);\n              deleteProps?.onDelete();\n              hideDelete();\n            }}\n            handleClose={hideDelete}\n          />\n        )\n        : null}\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/components/BackButton/index.js",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport PropTypes from 'prop-types';\nimport { Icons } from '@dhiwise/icons';\n\nexport const BackButton = ({ title = 'Back', link, onClick }) => (\n  <>\n    {onClick\n      ? (\n        <div className=\"flex items-center cursor-pointer\" onClick={onClick}>\n          <div className=\"w-2.5 h-2.5 mr-2\">\n            <Icons.LeftDouble />\n          </div>\n          <span className=\"text-primary-text text-sm\">{title}</span>\n        </div>\n      )\n      : (\n        <Link to={link} className=\"flex items-center\" onClick={onClick}>\n          <div className=\"w-2.5 h-2.5 mr-2\">\n            <Icons.LeftDouble />\n          </div>\n          <span className=\"text-primary-text text-sm\">{title}</span>\n        </Link>\n      )}\n  </>\n);\n\nBackButton.propTypes = {\n\n  // Display text for the back button\n  title: PropTypes.string,\n\n  // Route to go to, on onClick of button\n  link: PropTypes.string,\n};\n"
  },
  {
    "path": "packages/client/src/components/BoxLayout/boxLayoutCss.js",
    "content": "export const boxLayoutCss = {\n  boxmainRight: 'w-sidebarRight',\n  boxsubSidebar: 'xxl:w-1.5/12 w-2.5/12', // h-body sticky top-49 z-1\n  boxsubRight: 'xxl:w-10.5/12 w-9.5/12  overflow-auto flex justify-between', // h-body\n  boxfullscreen: 'xxl:w-1.5/12 w-2/12 h-full',\n};\n"
  },
  {
    "path": "packages/client/src/components/BoxLayout/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { boxLayoutCss } from './boxLayoutCss';\n\nexport const BoxLayout = ({\n  children, variant, className, style,\n}) => {\n  const variantClass = `${boxLayoutCss[[`box${variant}`]]}`;\n  return (\n    <div className={`${className} ${variantClass}`} style={style}>\n      {children}\n    </div>\n  );\n};\n\nBoxLayout.propTypes = {\n  variant: PropTypes.oneOf([\n    'mainRight',\n    'subSidebar',\n    'subRight',\n    'fullscreen',\n  ]),\n};\nBoxLayout.defaultProps = {\n  variant: 'mainRight',\n};\n"
  },
  {
    "path": "packages/client/src/components/Button/buttonCss.js",
    "content": "export const ButtonCss = {\n  buttonbox: 'cursor-pointer transition-all relative',\n  boxprimary:\n    'bg-primary-dark border-1 border-primary-dark boreder-primary-dark text-buttontext hover:bg-primary-hoverdark hover:border-primary-hoverdark hover:text-buttontext focus:outline-none primaryShadow',\n  boxoutline:\n  // outlinebuttontext\n  // hover:bg-primary-buttonOutline\n    'border-1 border-gray-70 text-primary-text hover:bg-gray-200  focus:outline-none outlineShadow',\n  boxghost: 'text-primary-text focus:outline-none ghostShadow hover:bg-gray-100',\n  boxprimaryLight: 'bg-primary-100 text-primary-dark',\n  boxdashed:\n  'border-1 border-dashed border-primary-buttonOutline text-dashedbuttontext focus:outline-none',\n  boxsecondary:\n  'border-gray-200 border-1 bg-gray-200 hover:bg-gray-100 text-primary-text font-normal focus:outline-none secondaryShadow',\n  boxdanger: 'text-base text-buttontext border-gray-deactivebg border-1 bg-deactivebg text-primary-text font-semibold focus:outline-none dangerShadow',\n  boxrounded: 'rounded-3',\n  boxdisabled: 'cursor-not-allowed focus:outline-none opacity-60',\n  boxbig: 'py-3 px-8 text-lg',\n  boxnormal: 'py-1.5 px-2 md:px-4 text-sm leading-5 md:min-h-11',\n  boxmedium: 'py-1 px-2 md:px-3 text-sm leading-normal min-h-9',\n  boxsmallMedium: 'py-0.5 px-1 md:px-2 text-xs leading-normal',\n  boxsmall: 'spacing-dw1 text-xs leading-5 font-normal',\n  iconnormal: 'w-4 h-4',\n  iconmedium: 'w-3 h-3',\n  iconsmallMedium: 'w-3 h-3',\n  iconsmall: 'w-2.5 h-2.5',\n  // iconImg: 'w-4 h-4',\n};\n"
  },
  {
    "path": "packages/client/src/components/Button/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport ReactTooltip from 'react-tooltip';\nimport { ButtonCss } from './buttonCss';\nimport { Spinner } from '../Spinner';\n/**\n * Primary UI component for Button\n */\nexport const Button = React.forwardRef(({\n  variant,\n  backgroundColor,\n  shape,\n  children,\n  className,\n  disabled,\n  icon,\n  size,\n  type,\n  label,\n  tooltip,\n  loading,\n  wrapClass,\n  ...rest\n}, ref) => {\n  const variantClass = `${ButtonCss[[`box${variant}`]]}`;\n  const sizeCss = `${ButtonCss[[`box${size}`]]}`;\n  const iconSize = `${ButtonCss[[`icon${size}`]]}`;\n  const shapeClass = `${ButtonCss[[`box${shape}`]]}`;\n  const disableClass = disabled || loading ? `${ButtonCss.boxdisabled}` : '';\n\n  const styles = {};\n  if (backgroundColor) {\n    styles[variant === 'primary' ? 'backgroundColor' : 'color'] = backgroundColor;\n    styles.border = `1px solid ${backgroundColor}`;\n  }\n\n  return (\n    <button\n      ref={ref}\n      className={[\n        'spark-button',\n        icon && 'flex items-center justify-center',\n        sizeCss,\n        ButtonCss.buttonbox,\n        variantClass,\n        shapeClass,\n        disableClass,\n        className,\n      ].join(' ')}\n      style={styles}\n      type={type}\n      disabled={disabled || loading}\n      {...rest}\n      data-tip\n      data-for={tooltip}\n    >\n      {!!icon && !loading && <div className={`${ButtonCss.iconImg} ${iconSize} ${label ? 'mr-2' : ''}`}>{icon}</div>}\n      {!!tooltip && <ReactTooltip place=\"bottom\" id={tooltip} type=\"dark\"><div className=\"text-center max-w-48\">{tooltip}</div></ReactTooltip>}\n      {loading && <Spinner className={`${variant === 'outline' && 'themeSpinner'} ${size === 'medium' && 'spinnerMedium'} ${variant === 'ghost' && 'themeSpinner'}`} />}\n      <span className={`${loading && 'opacity-0'} ${wrapClass}`}>{label || children}</span>\n    </button>\n  );\n});\n\nButton.displayName = 'Button';\nButton.propTypes = {\n  /**\n   * What background color to use\n   */\n  backgroundColor: PropTypes.string,\n  /**\n   * How large should the button be?\n   */\n  variant: PropTypes.oneOf([\n    'primary',\n    'primaryLight',\n    'outline',\n    'ghost',\n    'dashed',\n    'secondary',\n    'danger',\n  ]),\n  /**\n   * Shape of button\n   */\n  shape: PropTypes.oneOf(['square', 'rounded']),\n  /**\n   * Additional Icon\n   */\n  icon: PropTypes.string,\n  /**\n   * Additional icon true false\n   */\n  size: PropTypes.oneOf(['big', 'normal', 'small', 'smallMedium', 'medium']),\n  /**\n   * is Button disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Additional classname\n   */\n  className: PropTypes.string,\n  loading: PropTypes.bool,\n  label: PropTypes.string,\n  type: PropTypes.type,\n};\n\nButton.defaultProps = {\n  variant: 'primary',\n  backgroundColor: '',\n  shape: 'square',\n  className: '',\n  disabled: false,\n  size: 'normal',\n  type: 'button',\n  label: '',\n  loading: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/CardView/ThumbnailCard.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n// import mobileScreen from '@assets/images/7.svg';\nimport ReactTooltip from 'react-tooltip';\nimport { Icons } from '@dhiwise/icons';\nimport { CardCss } from './cardCss';\nimport { IconBox } from '../IconBox';\n\nexport const ThumbnailCard = ({\n  isSelect,\n  size = 'sm',\n  image = '',\n  title = 'Screen',\n  className,\n  children,\n  imgClass,\n  imgWrapClass,\n  isClosable = false,\n  CardBoxClass,\n  onClick = () => {},\n  onIconClick = () => {},\n  isLabel,\n}) => {\n  const sizeClass = `${CardCss[[`thumb${size}`]]}`;\n  const textClass = `${CardCss[[`thumbText${size}`]]}`;\n  return (\n    <div className={`text-center cursor-pointer relative ${className}`} onClick={onClick}>\n      {isClosable && <IconBox onClick={onIconClick} className=\"absolute -right-3 -top-1 bg-gray-200\" size=\"extraSmall\" shape=\"roundedFull\" variant=\"outline\" icon={<Icons.Close />} />}\n      {isLabel\n    && <div className=\"coming-soon z-100\"><span>Splash</span></div>}\n      <div\n        className={`border-1 border-gray-100 p-2 rounded-3 hover:bg-gray-100 ${\n          isSelect && 'border-primary-dark'\n        } ${sizeClass} ${CardBoxClass} ${imgWrapClass}`}\n      >\n        <img\n          src={image}\n          className={`h-full object-contain w-full rounded-3 ${imgClass}`}\n          alt=\"\"\n        />\n      </div>\n      {!!title && (\n      <span\n        data-tip\n        data-for={`tooltip${title}`}\n        className={`text-primary-text block mt-3 truncate ${textClass}`}\n      >\n        {title}\n        <ReactTooltip id={`tooltip${title}`} type=\"dark\">\n          {title}\n        </ReactTooltip>\n      </span>\n      )}\n      {children}\n    </div>\n  );\n};\nThumbnailCard.propTypes = {\n  /**\n   * How large should the avatar be?\n   */\n  size: PropTypes.oneOf(['xl', 'lg', 'md', 'sm', 'xs', 'auto']),\n  image: PropTypes.string,\n  title: PropTypes.string,\n};\n"
  },
  {
    "path": "packages/client/src/components/CardView/card.css",
    "content": ".groupbox:hover .perviewHover{\n    opacity: 0.8;\n}"
  },
  {
    "path": "packages/client/src/components/CardView/cardCss.js",
    "content": "export const CardCss = {\n  cardBox: 'groupbox card-box border-2 border-gray-200 col-span-1 p-5 rounded-3 cursor-pointer',\n  cardhover: 'hover:bg-gray-200',\n  cardImgBlock: 'mb-6 relative',\n  cardCodeView: 'mb-4 h-48 overflow-hidden relative text-left bg-gray-100 p-4 border-gray-200',\n  cardImg: 'object-contain m-auto flex items-center justify-center',\n  cardImgBig: 'w-20 h-20',\n  cardImgSmall: 'w-12 h-12',\n  cardTitle: 'text-primary-text leading-1xl text-xl font-semibold',\n  cardDesc: 'text-body-text text-sm leading-snug mt-1 break-words descriptionDoted',\n  CardPerview: 'perviewHover opacity-0  absolute bg-gray-black top-0 left-0 w-full h-full flex items-center justify-center',\n\n  thumbxs: 'h-20',\n  thumbsm: 'h-28',\n  thumbxl: 'h-72',\n  thumbmd: 'h-32 xxl:h-40 ',\n  thumbTextsm: 'text-sm',\n  thumbTextmd: 'text-base',\n};\n"
  },
  {
    "path": "packages/client/src/components/CardView/index.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport PropTypes from 'prop-types';\nimport { CardCss } from './cardCss';\nimport './card.css';\nimport { Tag } from '../Tag';\n\nexport const CardView = ({\n  icon,\n  title,\n  dec,\n  imgClassName,\n  onClick,\n  children,\n  className,\n  leftCard,\n  isSelect,\n  svg,\n  code,\n  preview,\n  showPreview,\n  imgSmall,\n  previewClass,\n  isComingSoon,\n  cardTag,\n  svgClass,\n  imageSpace,\n  variantHover = 'hover',\n}) => {\n  const varinatHoverClass = `${CardCss[[`card${variantHover}`]]}`;\n  return (\n  // ${isSelect && 'border-primary-dark'}\n    <div className={`${CardCss.cardBox} ${varinatHoverClass} ${isComingSoon && 'cursor-not-allowed'} ${isSelect && 'border-primary-dark'} ${leftCard ? '' : 'text-center '} ${className} relative`} onClick={onClick}>\n      {!!icon && (\n      <div className={CardCss.cardImgBlock}>\n        <img className={`${CardCss.cardImg}  ${imgSmall ? CardCss.cardImgSmall : CardCss.cardImgBig} ${imgClassName}`} src={icon} alt=\"Images\" />\n      </div>\n      )}\n      {isComingSoon\n    && <div className=\"coming-soon\"><span>Coming soon</span></div>}\n      {!!preview\n        && (\n          <div className={`${CardCss.cardCodeView} ${previewClass}`} onClick={showPreview}>\n            {code}\n            <div className={`${CardCss.CardPerview}`}>\n              <div className=\"w-10 h-10\">\n                <Icons.EyeOpen />\n              </div>\n            </div>\n          </div>\n        )}\n      {!!svg\n    && (\n    <div className={`${CardCss.cardImgBlock} ${imageSpace && 'sm:mb-0'}`}>\n      <div className={`${CardCss.cardImg} ${svgClass} ${imgSmall ? CardCss.cardImgSmall : CardCss.cardImgBig}`}>\n        {svg}\n      </div>\n    </div>\n    )}\n      {!!title && (\n      <h2 className={CardCss.cardTitle}>\n        <span className={`relative ${cardTag && 'mr-9'}`}>\n          {title}\n          {!!cardTag && <Tag variant=\"primary\" className=\"absolute\" size=\"xxs\" title={cardTag} />}\n        </span>\n      </h2>\n      )}\n      {!!dec && <p className={CardCss.cardDesc}>{dec}</p>}\n      {children}\n    </div>\n  );\n};\nCardView.propTypes = {\n  variantHover: PropTypes.oneOf([\n    'hover',\n    'default',\n  ]),\n  onClick: PropTypes.func,\n  icon: PropTypes.string,\n  title: PropTypes.string,\n  dec: PropTypes.string,\n  imgClassName: PropTypes.string,\n};\nCardView.defaultProps = {\n  variantHover: 'hover',\n};\n"
  },
  {
    "path": "packages/client/src/components/Checkbox/Checkbox.js",
    "content": "export const CheckboxCss = {\n  checkboxcheckinput: 'absolute top-0 right-0 bottom-0 left-0 w-full h-full cursor-pointer opacity-0 zindex-1',\n  checkboxWrap: 'm-0 p-0 text-sm box-border inline-block cursor-pointer',\n  checkBox: 'box-border m-0 p-0 text-sm leading-none relative inline-block whitespace-nowrap align-middle cursor-pointer',\n  inputcheckBox: 'absolute top-0 right-0 bottom-0 left-0 w-full h-full cursor-pointer opacity-0 mr-1 z-1',\n  // -webkit-box-sizing: border-box;\n  // color: rgba(0, 0, 0, 0.65);\n  // font-variant: tabular-nums;\n  // list-style: none;\n  // -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  // font-feature-settings: \"tnum\", \"tnum\";\n  // top: -0.09em;\n  // outline: none;\"\n\n  // color: rgba(0, 0, 0, 0.65);\n  // font-variant: tabular-nums;\n  // line-height: unset;\n  // list-style: none;\n  // -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  // font-feature-settings: \"tnum\", \"tnum\";\"\n};\n"
  },
  {
    "path": "packages/client/src/components/Checkbox/checkbox.css",
    "content": ".spark-checkbox-wrapper,\n.spark-checkbox-wrap {\n  @apply m-0 p-0 text-sm box-border inline-block cursor-pointer relative;\n  -webkit-box-sizing: border-box;\n  color: rgba(0, 0, 0, 0.65);\n  /* font-variant: tabular-nums; */\n  line-height: unset;\n  list-style: none;\n  -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  font-feature-settings: \"tnum\", \"tnum\";\n}\nlabel {\n  @apply leading-5 font-semibold;\n}\n.spark-checkbox {\n  @apply box-border m-0 p-0 text-sm leading-none relative inline-block whitespace-nowrap align-middle cursor-pointer;\n  -webkit-box-sizing: border-box;\n  color: rgba(0, 0, 0, 0.65);\n  /* font-variant: tabular-nums; */\n  list-style: none;\n  -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  font-feature-settings: \"tnum\", \"tnum\";\n  top: -0.09em;\n  outline: none;\n}\n.spark-checkbox-input,\n.spark-checkbox-wrap input {\n  @apply absolute top-0 right-0 bottom-0 left-0 w-full h-full cursor-pointer opacity-0 !important;\n  z-index: 1;\n}\n.spark-checkbox-checked .spark-checkbox-inner,\n.spark-checkbox-wrap input:checked ~ .spark-checkbox-inner{\n  background-color: var(--color-bg-primary);\n  border-color: var(--color-bg-primary);\n}\n.spark-checkbox-wrapper input:focus ~ .spark-checkbox-inner{\n  /* border: 1px solid transparent; */\n  box-shadow: 0 0 0 2px rgb(0 97 255 / 40%);\n  /* background: var(--color-gray-70); */\n \n}\n/* .spark-checkbox-checked input:focus ~ .spark-checkbox-inner{\n  box-shadow: inset 0 0 0 1px var(--color-bg-primary), inset 0 0 0 2px var(--color-gray-black);\n  background-color: var(--color-bg-primary);\n} */\n/* .spark-checkbox-wrapper input:focus ~ .spark-checkbox-inner:before {\n  content: \"\";\n  width: 130%;\n  height: 130%;\n  position: absolute;\n  border: 1px solid var(--color-bg-primary);\n  left: -16%;\n  top: -16%;\n  border-radius: 3px;\n} */\n.spark-checkbox-inner {\n  @apply relative top-0 left-0 block w-4 h-4 rounded-sm mr-2;\n  background-color:var(--color-gray-input);\n  border:1px solid var(--color-gray-70);\n  width:18px;\n  height:18px;\n  border-collapse: initial;\n  -webkit-transition: all .3s;\n  transition: all .3s;\n}\n.spark-checkbox-input {\n  @apply absolute top-0 right-0 bottom-0 left-0 w-full h-full cursor-pointer opacity-0 mr-1;\n  z-index: 1;\n}\n.spark-checkbox-checked:after {\n  @apply absolute top-0 left-0 w-full h-full rounded-sm invisible;\n  border: 1px solid #0061ff;\n  -webkit-animation: antCheckboxEffect .36s ease-in-out;\n  animation: antCheckboxEffect .36s ease-in-out;\n  -webkit-animation-fill-mode: backwards;\n  animation-fill-mode: backwards;\n  content: \"\";\n}\n.spark-checkbox-checked .spark-checkbox-inner:after {\n  @apply absolute table opacity-100;\n  border: 2px solid #fff;\n  border-top: 0;\n  border-left: 0;\n  -webkit-transform: rotate(45deg) scale(1) translate(-50%,-50%);\n  -ms-transform: rotate(45deg) scale(1) translate(-50%,-50%);\n  transform: rotate(45deg) scale(1) translate(-50%,-50%);\n  -webkit-transition: all .2s cubic-bezier(.12,.4,.29,1.46) .1s;\n  transition: all .2s cubic-bezier(.12,.4,.29,1.46) .1s;\n  content: \" \";\n}\n.spark-checkbox-inner:after {\n  @apply absolute table w-1 h-2 opacity-0;\n  top: 45%;\n  left: 4px;\n  height: 0.65rem;\n  width: 0.30rem;\n  border: 2px solid #fff;\n  border-top: 0;\n  border-left: 0;\n  -webkit-transform: rotate(45deg) scale(0) translate(-50%,-50%);\n  -ms-transform: rotate(45deg) scale(0) translate(-50%,-50%);\n  transform: rotate(45deg) scale(0) translate(-50%,-50%);\n  -webkit-transition: all .1s cubic-bezier(.71,-.46,.88,.6),opacity .1s;\n  transition: all .1s cubic-bezier(.71,-.46,.88,.6),opacity .1s;\n  content: \" \";\n}\n.spark-checkbox-wrap input:checked ~ .spark-checkbox-inner:after{\n  left: 7px;\n  top: 5px;\n  width: 5px;\n  height: 9px;\n  border: solid white;\n  border-width: 0 2px 2px 0;\n  transform: rotate(45deg);\n  opacity: 1;\n}\n.spark-checkbox-input:disabled,\n.spark-checkbox-input:disabled+ .spark-checkbox-inner{\n  /* background-color: #0061ff7a;\n  border-color: #0061ff7a; */\n  /* opacity: 1 !important; */\n  cursor: not-allowed !important;\n}\n.spark-checkbox-disabled{\n  opacity: 0.4;\n  cursor: not-allowed !important;\n}\n.cardBoxCheck{\n  @apply absolute;\n  left: 0 !important;\n  top: 20px !important;\n  right:auto;\n  /* bottom: -4px; */\n}\n.cardBoxCheck.cardCheckbox{\n  left: 4px !important;\n  top: 0 !important;\n}\n.cardBoxCheck .spark-checkbox-inner,\n.smallCheckbox .spark-checkbox-inner{\n  width: 16px;\n  height: 16px;\n}\n.smallCheckbox .permissionPage .spark-checkbox-inner,\n.smallCheckbox .rightMargin .spark-checkbox-inner{\n  margin-right: 0;\n}\n.smallCheckbox .permissionPage .spark-checkbox-wrapper,\n.smallCheckbox .topBottomCheckbox .spark-checkbox-wrapper{\n  text-align: center;\n  margin-right: 8px;\n}\n.smallCheckbox .permissionPage .checkboxLabel,\n.smallCheckbox .topBottomCheckbox .checkboxLabel{\n  display: block;\n}\n.smallCheckbox .spark-checkbox-inner:after,\n.cardBoxCheck .spark-checkbox-inner:after{\n  left: 3.9px;\n  height: 0.5rem;\n  width: 0.2rem;\n  top: 44%;\n  border: 1px solid #fff;\n  border-top: 0;\n  border-left: 0;\n}\n\n/* .cardBoxCheck .spark-checkbox-wrapper:before{ */\n  /* content: \"\";\n  width: 100%;\n  height: 100%;\n  border-left: 1px solid #fff;\n  transform: rotate(45deg);\n  position: absolute;\n  top: 0; */\n  /* content: \"\";\n  width: 0;\n  height: 0;\n  border-left: 16px solid transparent;\n  border-right: 16px solid transparent;\n  border-top: 16px solid #3e3e3e;\n  transform: rotate(226deg);\n  display: block;\n  position: absolute;\n  right: -12px;\n  top: 1px;\n}\n.cardBoxCheck .spark-checkbox-wrapper.spark-checkbox-wrapper-checked:before{\n  border-top: 16px solid var(--color-bg-primary);\n}\n.cardBoxCheck .spark-checkbox-checked .spark-checkbox-inner:after{\n  display: none;\n}\n.cardBoxCheck .spark-checkbox-inner{\n  border-radius: 0;\n  width:24px;\n  height:24px;\n  margin-right: 0;\n  border-left: none;\n  border-top: none;\n  background-color:transparent;\n}\n.cardBoxCheck .spark-checkbox-inner:after{\n  height: 0.6rem;\n  width: 0.30rem;\n} */\n"
  },
  {
    "path": "packages/client/src/components/Checkbox/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\n/* eslint-disable no-unused-vars */\nimport React, { forwardRef, useState } from 'react';\nimport propTypes from 'prop-types';\nimport ReactTooltip from 'react-tooltip';\nimport { classNames, useCombinedRefs } from '../utils';\nimport './checkbox.css';\n\n/**\n * Primary UI component for Checkbox\n */\nexport const Checkbox = forwardRef(\n  (\n    {\n      checked,\n      disabled = false,\n      className = '',\n      WrapclassName,\n      wrapClass,\n      onChange = () => { },\n      type = 'checkbox',\n      style = {},\n      prefixCls = 'spark-checkbox',\n      prefixWrapperCls = 'spark-checkbox-wrapper',\n      wrapperClassname = '',\n      wrapperStyle = {},\n      defaultChecked = false,\n      children,\n      label,\n      labelClass,\n      name,\n      onKeyDown,\n      id = '',\n      tooltip,\n      ...otherProps\n    },\n    forwardedRef,\n  ) => {\n    const [value, setValue] = useState(defaultChecked || checked || false);\n\n    React.useEffect(() => {\n      setValue(checked);\n      // if (onChange) {\n      //   onChange(checked);\n      // }\n    }, [checked]);\n    const checkboxClass = classNames(prefixCls, className, {\n      [`${prefixCls}-checked`]: value,\n      [`${prefixCls}-disabled`]: disabled,\n    });\n    const wrapperClass = classNames(prefixWrapperCls, wrapperClassname, {\n      [`${prefixCls}-wrapper-checked`]: value,\n      [`${prefixCls}-wrapper-disabled`]: disabled,\n    });\n\n    const handleChange = (event) => {\n      if (disabled) return;\n      if (onChange) {\n        setValue(event.target.checked);\n        onChange(event.target.checked, event);\n      }\n    };\n    return (\n      <div className={wrapClass}>\n        <label\n          className={`${wrapperClass} ${WrapclassName}`}\n          style={{ ...wrapperStyle, cursor: 'pointer' }}\n        >\n          <div data-tip data-for={tooltip} className=\"inline-block\">\n            {!!tooltip && (\n            <ReactTooltip id={tooltip} type=\"dark\">\n              {tooltip}\n            </ReactTooltip>\n            )}\n            <span className={checkboxClass} style={style}>\n              <input\n                type={type}\n                disabled={disabled}\n                className={`${prefixCls}-input`}\n                checked={!!checked || value}\n                onChange={handleChange}\n                name={name}\n                onKeyDown={onKeyDown}\n                id={id}\n                {...otherProps}\n              />\n              <span className={`${prefixCls}-inner`} />\n            </span>\n          </div>\n          {(!!children || !!label) && <span className={`text-primary-text text-sm checkboxLabel ${labelClass}`}>{children || label}</span>}\n        </label>\n      </div>\n    );\n  },\n);\nCheckbox.displayName = 'Checkbox';\nCheckbox.propTypes = {\n  checked: propTypes.bool,\n  disabled: propTypes.bool,\n  className: propTypes.string,\n  onChange: propTypes.func,\n  prefixCls: propTypes.string,\n  wrapperClassname: propTypes.string,\n  defaultChecked: propTypes.bool,\n};\n\nCheckbox.defaultProps = {\n  checked: true,\n};\n"
  },
  {
    "path": "packages/client/src/components/CodeEditor/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport Editor from '@monaco-editor/react';\nimport { isEmpty } from 'lodash';\nimport { useBoolean } from '../hooks';\nimport { Error } from '../Error';\nimport { EXTENSION_TYPE } from '../../constant/fileTypeConstant';\n\nlet monacoJSXHighlighter = null;\nexport const CodeEditor = React.memo(({\n  value = '',\n  readOnly = false,\n  onChange = () => { },\n  onValidate = () => { },\n  isShowError = false, // For showing Error\n  language = 'json',\n  style = {},\n  height = '100%',\n  width,\n  defaultValue = '{}',\n  className,\n  onBlur,\n  repairedJson,\n  setRepairedJson,\n  imageShow = false,\n  imageSource = false,\n  fileType = EXTENSION_TYPE.TEXT,\n  loading,\n  scrollbar,\n}) => {\n  const [isError, setShowError, setHideError] = useBoolean(false);\n  const [jsonError, setJsonError] = React.useState(false);\n  // eslint-disable-next-line no-unused-vars\n  const [internalValue, setInternalValue] = React.useState();\n\n  React.useEffect(() => {\n    setInternalValue(value);\n  }, [value]);\n\n  React.useEffect(() => {\n    if (repairedJson && repairedJson !== '{}') {\n      setInternalValue(repairedJson);\n      setRepairedJson?.('{}');\n    }\n  }, [repairedJson]);\n\n  async function handleEditorDidMount(monacoEditor, monaco) {\n    // monaco-jsx-highlighter depends on these (and monaco)\n    const { default: traverse } = await import('@babel/traverse');\n    const { parse } = await import('@babel/parser');\n    // The star of the show =P\n    const { default: MonacoJSXHighlighter, JSXTypes } = await import(\n      'monaco-jsx-highlighter'\n    );\n    // Customize Babel directly\n    const babelParse = (code) => parse(code, { sourceType: 'module', plugins: ['jsx'] });\n    // Instantiate the highlighter\n    monacoJSXHighlighter = new MonacoJSXHighlighter(\n      monaco,\n      babelParse,\n      traverse,\n      monacoEditor,\n    );\n    // Start the JSX highlighting and get the dispose function\n    monacoJSXHighlighter.highLightOnDidChangeModelContent();\n    // Enhance monaco's editor.action.commentLine with JSX commenting and get its disposer\n    monacoJSXHighlighter.addJSXCommentCommand();\n    // You are all set.\n\n    // Optional: customize the color font in JSX texts (style class JSXElement.JSXText.tastyPizza from ./index.css)\n    JSXTypes.JSXText.options.inlineClassName = 'JSXElement.JSXText.tastyPizza';\n\n    // More of this example's boilerplate\n    monacoJSXHighlighter.highLightOnDidChangeModelContent();\n    monacoJSXHighlighter.addJSXCommentCommand();\n  }\n\n  return (\n    <div\n      onBlur={onBlur}\n      className={`overflow-hidden relative h-full ${imageShow && 'flex items-center justify-center p-4'} ${className} ${readOnly ? 'readonlyEditor' : ''}`}\n      onKeyDown={(e) => {\n        // to stop copy paste\n        if (readOnly) { e.preventDefault(); }\n      }}\n      style={style}\n    >\n      {(imageShow && imageSource && fileType === EXTENSION_TYPE.IMAGE)\n        ? <div className=\"editorImage\"><img src={imageSource} alt=\"\" /></div>\n        : fileType === EXTENSION_TYPE.DEFAULT\n          ? (\n            <div className=\"flex justify-center items-center h-full\">\n              <div className=\"p-3 text-lg xxl:text-xl w-7/12 xxl:w-5/12 text-center\">\n                <div className=\"w-24 h-24 xxl:w-28 xxl:h-28 m-auto mb-3 xxl:mb-10\">\n                  <Icons.NotSupportPreview />\n                </div>\n                The file is not displayed in the editor because it is either binary or uses an unsupported text encoding.\n              </div>\n            </div>\n          )\n          : (\n            <Editor\n              height={height}\n              width={width}\n              language={language}\n              defaultValue={defaultValue}\n              theme=\"vs-dark\"\n              lineNumbers={false}\n              glyphMargin={false}\n              folding={false}\n              onChange={isShowError ? (changeCode) => {\n                try {\n                  setJsonError(false);\n                  setHideError();\n                  setInternalValue(changeCode);\n                  onChange(changeCode);\n                } catch (error) {\n                  // To catch on Change error line by line\n                  setShowError();\n                  setJsonError(error);\n                }\n              } : (changeCode) => {\n                setInternalValue(changeCode);\n                onChange(changeCode);\n              }}\n              options={{ readOnly, contextmenu: !readOnly, scrollbar }}\n              value={internalValue}\n              onValidate={isShowError ? (errors) => {\n                if (isEmpty(errors)) {\n                  // errors contains array of error objects message\n                  setHideError();\n                  setJsonError(false);\n                }\n              } : onValidate}\n              // eslint-disable-next-line react/jsx-no-bind\n              onMount={handleEditorDidMount}\n              loading={loading}\n            />\n          )}\n      {\n        isShowError && isError\n          ? <Error isOpen={isError} error={jsonError} handleCancel={setHideError} /> : null\n      }\n    </div>\n  );\n});\n\nCodeEditor.displayName = 'CodeEditor';\n"
  },
  {
    "path": "packages/client/src/components/CodeEditor/reactTypes.js",
    "content": "export default `\nimport * as CSS from 'csstype';\nimport * as PropTypes from 'prop-types';\n\ntype NativeAnimationEvent = AnimationEvent;\ntype NativeClipboardEvent = ClipboardEvent;\ntype NativeCompositionEvent = CompositionEvent;\ntype NativeDragEvent = DragEvent;\ntype NativeFocusEvent = FocusEvent;\ntype NativeKeyboardEvent = KeyboardEvent;\ntype NativeMouseEvent = MouseEvent;\ntype NativeTouchEvent = TouchEvent;\ntype NativePointerEvent = PointerEvent;\ntype NativeTransitionEvent = TransitionEvent;\ntype NativeUIEvent = UIEvent;\ntype NativeWheelEvent = WheelEvent;\ntype Booleanish = boolean | 'true' | 'false';\n\n/**\n * defined in scheduler/tracing\n */\ninterface SchedulerInteraction {\n    id: number;\n    name: string;\n    timestamp: number;\n}\n\n// tslint:disable-next-line:export-just-namespace\nexport = React;\nexport as namespace React;\n\ndeclare namespace React {\n    //\n    // React Elements\n    // ----------------------------------------------------------------------\n\n    type ElementType<P = any> =\n        {\n            [K in keyof JSX.IntrinsicElements]: P extends JSX.IntrinsicElements[K] ? K : never\n        }[keyof JSX.IntrinsicElements] |\n        ComponentType<P>;\n \n    type ReactType<P = any> = ElementType<P>;\n    type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;\n\n    type JSXElementConstructor<P> =\n        | ((props: P) => ReactElement | null)\n        | (new (props: P) => Component<P, any>);\n\n    interface RefObject<T> {\n        readonly current: T | null;\n    }\n    type RefCallback<T> = { bivarianceHack(instance: T | null): void }[\"bivarianceHack\"];\n    type Ref<T> = RefCallback<T> | RefObject<T> | null;\n    type LegacyRef<T> = string | Ref<T>;\n    \n    type ElementRef<\n        C extends\n            | ForwardRefExoticComponent<any>\n            | { new (props: any): Component<any> }\n            | ((props: any, context?: any) => ReactElement | null)\n            | keyof JSX.IntrinsicElements\n    > =\n        \"ref\" extends keyof ComponentPropsWithRef<C>\n            ? NonNullable<ComponentPropsWithRef<C>[\"ref\"]> extends Ref<\n                infer Instance\n            >\n                ? Instance\n                : never\n            : never;\n\n    type ComponentState = any;\n\n    type Key = string | number;\n\n    /**\n     * @internal You shouldn't need to use this type since you never see these attributes\n     * inside your component or have to validate them.\n     */\n    interface Attributes {\n        key?: Key;\n    }\n    interface RefAttributes<T> extends Attributes {\n        ref?: Ref<T>;\n    }\n    interface ClassAttributes<T> extends Attributes {\n        ref?: LegacyRef<T>;\n    }\n\n    interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {\n        type: T;\n        props: P;\n        key: Key | null;\n    }\n\n    interface ReactComponentElement<\n        T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>,\n        P = Pick<ComponentProps<T>, Exclude<keyof ComponentProps<T>, 'key' | 'ref'>>\n    > extends ReactElement<P, Exclude<T, number>> { }\n\n  \n    type SFCElement<P> = FunctionComponentElement<P>;\n\n    interface FunctionComponentElement<P> extends ReactElement<P, FunctionComponent<P>> {\n        ref?: 'ref' extends keyof P ? P extends { ref?: infer R } ? R : never : never;\n    }\n\n    type CElement<P, T extends Component<P, ComponentState>> = ComponentElement<P, T>;\n    interface ComponentElement<P, T extends Component<P, ComponentState>> extends ReactElement<P, ComponentClass<P>> {\n        ref?: LegacyRef<T>;\n    }\n\n    type ClassicElement<P> = CElement<P, ClassicComponent<P, ComponentState>>;\n\n    // string fallback for custom web-components\n    interface DOMElement<P extends HTMLAttributes<T> | SVGAttributes<T>, T extends Element> extends ReactElement<P, string> {\n        ref: LegacyRef<T>;\n    }\n\n    // ReactHTML for ReactHTMLElement\n    // tslint:disable-next-line:no-empty-interface\n    interface ReactHTMLElement<T extends HTMLElement> extends DetailedReactHTMLElement<AllHTMLAttributes<T>, T> { }\n\n    interface DetailedReactHTMLElement<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMElement<P, T> {\n        type: keyof ReactHTML;\n    }\n\n    // ReactSVG for ReactSVGElement\n    interface ReactSVGElement extends DOMElement<SVGAttributes<SVGElement>, SVGElement> {\n        type: keyof ReactSVG;\n    }\n\n    interface ReactPortal extends ReactElement {\n        key: Key | null;\n        children: ReactNode;\n    }\n\n    //\n    // Factories\n    // ----------------------------------------------------------------------\n\n    type Factory<P> = (props?: Attributes & P, ...children: ReactNode[]) => ReactElement<P>;\n\n    type SFCFactory<P> = FunctionComponentFactory<P>;\n\n    type FunctionComponentFactory<P> = (props?: Attributes & P, ...children: ReactNode[]) => FunctionComponentElement<P>;\n\n    type ComponentFactory<P, T extends Component<P, ComponentState>> =\n        (props?: ClassAttributes<T> & P, ...children: ReactNode[]) => CElement<P, T>;\n\n    type CFactory<P, T extends Component<P, ComponentState>> = ComponentFactory<P, T>;\n    type ClassicFactory<P> = CFactory<P, ClassicComponent<P, ComponentState>>;\n\n    type DOMFactory<P extends DOMAttributes<T>, T extends Element> =\n        (props?: ClassAttributes<T> & P | null, ...children: ReactNode[]) => DOMElement<P, T>;\n\n    // tslint:disable-next-line:no-empty-interface\n    interface HTMLFactory<T extends HTMLElement> extends DetailedHTMLFactory<AllHTMLAttributes<T>, T> {}\n\n    interface DetailedHTMLFactory<P extends HTMLAttributes<T>, T extends HTMLElement> extends DOMFactory<P, T> {\n        (props?: ClassAttributes<T> & P | null, ...children: ReactNode[]): DetailedReactHTMLElement<P, T>;\n    }\n\n    interface SVGFactory extends DOMFactory<SVGAttributes<SVGElement>, SVGElement> {\n        (props?: ClassAttributes<SVGElement> & SVGAttributes<SVGElement> | null, ...children: ReactNode[]): ReactSVGElement;\n    }\n\n    //\n    // React Nodes\n    // http://facebook.github.io/react/docs/glossary.html\n    // ----------------------------------------------------------------------\n\n    type ReactText = string | number;\n    type ReactChild = ReactElement | ReactText;\n\n    interface ReactNodeArray extends Array<ReactNode> {}\n    type ReactFragment = {} | ReactNodeArray;\n    type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;\n\n    //\n    // Top Level API\n    // ----------------------------------------------------------------------\n\n    // DOM Elements\n    function createFactory<T extends HTMLElement>(\n        type: keyof ReactHTML): HTMLFactory<T>;\n    function createFactory(\n        type: keyof ReactSVG): SVGFactory;\n    function createFactory<P extends DOMAttributes<T>, T extends Element>(\n        type: string): DOMFactory<P, T>;\n\n    // Custom components\n    function createFactory<P>(type: FunctionComponent<P>): FunctionComponentFactory<P>;\n    function createFactory<P>(\n        type: ClassType<P, ClassicComponent<P, ComponentState>, ClassicComponentClass<P>>): CFactory<P, ClassicComponent<P, ComponentState>>;\n    function createFactory<P, T extends Component<P, ComponentState>, C extends ComponentClass<P>>(\n        type: ClassType<P, T, C>): CFactory<P, T>;\n    function createFactory<P>(type: ComponentClass<P>): Factory<P>;\n\n    // DOM Elements\n    function createElement(\n        type: \"input\",\n        props?: InputHTMLAttributes<HTMLInputElement> & ClassAttributes<HTMLInputElement> | null,\n        ...children: ReactNode[]): DetailedReactHTMLElement<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;\n    function createElement<P extends HTMLAttributes<T>, T extends HTMLElement>(\n        type: keyof ReactHTML,\n        props?: ClassAttributes<T> & P | null,\n        ...children: ReactNode[]): DetailedReactHTMLElement<P, T>;\n    function createElement<P extends SVGAttributes<T>, T extends SVGElement>(\n        type: keyof ReactSVG,\n        props?: ClassAttributes<T> & P | null,\n        ...children: ReactNode[]): ReactSVGElement;\n    function createElement<P extends DOMAttributes<T>, T extends Element>(\n        type: string,\n        props?: ClassAttributes<T> & P | null,\n        ...children: ReactNode[]): DOMElement<P, T>;\n\n    // Custom components\n\n    function createElement<P extends {}>(\n        type: FunctionComponent<P>,\n        props?: Attributes & P | null,\n        ...children: ReactNode[]): FunctionComponentElement<P>;\n    function createElement<P extends {}>(\n        type: ClassType<P, ClassicComponent<P, ComponentState>, ClassicComponentClass<P>>,\n        props?: ClassAttributes<ClassicComponent<P, ComponentState>> & P | null,\n        ...children: ReactNode[]): CElement<P, ClassicComponent<P, ComponentState>>;\n    function createElement<P extends {}, T extends Component<P, ComponentState>, C extends ComponentClass<P>>(\n        type: ClassType<P, T, C>,\n        props?: ClassAttributes<T> & P | null,\n        ...children: ReactNode[]): CElement<P, T>;\n    function createElement<P extends {}>(\n        type: FunctionComponent<P> | ComponentClass<P> | string,\n        props?: Attributes & P | null,\n        ...children: ReactNode[]): ReactElement<P>;\n\n    // DOM Elements\n    // ReactHTMLElement\n    function cloneElement<P extends HTMLAttributes<T>, T extends HTMLElement>(\n        element: DetailedReactHTMLElement<P, T>,\n        props?: P,\n        ...children: ReactNode[]): DetailedReactHTMLElement<P, T>;\n    // ReactHTMLElement, less specific\n    function cloneElement<P extends HTMLAttributes<T>, T extends HTMLElement>(\n        element: ReactHTMLElement<T>,\n        props?: P,\n        ...children: ReactNode[]): ReactHTMLElement<T>;\n    // SVGElement\n    function cloneElement<P extends SVGAttributes<T>, T extends SVGElement>(\n        element: ReactSVGElement,\n        props?: P,\n        ...children: ReactNode[]): ReactSVGElement;\n    // DOM Element (has to be the last, because type checking stops at first overload that fits)\n    function cloneElement<P extends DOMAttributes<T>, T extends Element>(\n        element: DOMElement<P, T>,\n        props?: DOMAttributes<T> & P,\n        ...children: ReactNode[]): DOMElement<P, T>;\n\n    // Custom components\n    function cloneElement<P>(\n        element: FunctionComponentElement<P>,\n        props?: Partial<P> & Attributes,\n        ...children: ReactNode[]): FunctionComponentElement<P>;\n    function cloneElement<P, T extends Component<P, ComponentState>>(\n        element: CElement<P, T>,\n        props?: Partial<P> & ClassAttributes<T>,\n        ...children: ReactNode[]): CElement<P, T>;\n    function cloneElement<P>(\n        element: ReactElement<P>,\n        props?: Partial<P> & Attributes,\n        ...children: ReactNode[]): ReactElement<P>;\n\n    // Context via RenderProps\n    interface ProviderProps<T> {\n        value: T;\n        children?: ReactNode;\n    }\n\n    interface ConsumerProps<T> {\n        children: (value: T) => ReactNode;\n    }\n\n    // TODO: similar to how Fragment is actually a symbol, the values returned from createContext,\n    // forwardRef and memo are actually objects that are treated specially by the renderer; see:\n    // https://github.com/facebook/react/blob/v16.6.0/packages/react/src/ReactContext.js#L35-L48\n    // https://github.com/facebook/react/blob/v16.6.0/packages/react/src/forwardRef.js#L42-L45\n    // https://github.com/facebook/react/blob/v16.6.0/packages/react/src/memo.js#L27-L31\n    // However, we have no way of telling the JSX parser that it's a JSX element type or its props other than\n    // by pretending to be a normal component.\n    //\n    // We don't just use ComponentType or SFC types because you are not supposed to attach statics to this\n    // object, but rather to the original function.\n    interface ExoticComponent<P = {}> {\n        /**\n         * **NOTE**: Exotic components are not callable.\n         */\n        (props: P): (ReactElement|null);\n        readonly $$typeof: symbol;\n    }\n\n    interface NamedExoticComponent<P = {}> extends ExoticComponent<P> {\n        displayName?: string;\n    }\n\n    interface ProviderExoticComponent<P> extends ExoticComponent<P> {\n        propTypes?: WeakValidationMap<P>;\n    }\n\n    type ContextType<C extends Context<any>> = C extends Context<infer T> ? T : never;\n\n    // NOTE: only the Context object itself can get a displayName\n    // https://github.com/facebook/react-devtools/blob/e0b854e4c/backend/attachRendererFiber.js#L310-L325\n    type Provider<T> = ProviderExoticComponent<ProviderProps<T>>;\n    type Consumer<T> = ExoticComponent<ConsumerProps<T>>;\n    interface Context<T> {\n        Provider: Provider<T>;\n        Consumer: Consumer<T>;\n        displayName?: string;\n    }\n    function createContext<T>(\n        // If you thought this should be optional, see\n        // https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24509#issuecomment-382213106\n        defaultValue: T,\n    ): Context<T>;\n\n    function isValidElement<P>(object: {} | null | undefined): object is ReactElement<P>;\n\n    const Children: ReactChildren;\n    const Fragment: ExoticComponent<{ children?: ReactNode }>;\n    const StrictMode: ExoticComponent<{ children?: ReactNode }>;\n\n    interface SuspenseProps {\n        children?: ReactNode;\n\n        /** A fallback react tree to show when a Suspense child (like React.lazy) suspends */\n        fallback: NonNullable<ReactNode>|null;\n    }\n    /**\n     * This feature is not yet available for server-side rendering.\n     * Suspense support will be added in a later release.\n     */\n    const Suspense: ExoticComponent<SuspenseProps>;\n    const version: string;\n\n    /**\n     * {@link https://github.com/bvaughn/rfcs/blob/profiler/text/0000-profiler.md#detailed-design | API}\n     */\n    type ProfilerOnRenderCallback = (\n        id: string,\n        phase: \"mount\" | \"update\",\n        actualDuration: number,\n        baseDuration: number,\n        startTime: number,\n        commitTime: number,\n        interactions: Set<SchedulerInteraction>,\n    ) => void;\n    interface ProfilerProps {\n        children?: ReactNode;\n        id: string;\n        onRender: ProfilerOnRenderCallback;\n    }\n\n    const Profiler: ExoticComponent<ProfilerProps>;\n\n    //\n    // Component API\n    // ----------------------------------------------------------------------\n\n    type ReactInstance = Component<any> | Element;\n\n    // Base component for plain JS classes\n    // tslint:disable-next-line:no-empty-interface\n    interface Component<P = {}, S = {}, SS = any> extends ComponentLifecycle<P, S, SS> { }\n    class Component<P, S> {\n        \n        static contextType?: Context<any>;\n\n        context: any;\n\n        constructor(props: Readonly<P>);\n        /**\n         * @deprecated\n         * @see https://reactjs.org/docs/legacy-context.html\n         */\n        constructor(props: P, context?: any);\n\n        setState<K extends keyof S>(\n            state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),\n            callback?: () => void\n        ): void;\n\n        forceUpdate(callback?: () => void): void;\n        render(): ReactNode;\n\n        readonly props: Readonly<P> & Readonly<{ children?: ReactNode }>;\n        state: Readonly<S>;\n        /**\n         * @deprecated\n         * https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs\n         */\n        refs: {\n            [key: string]: ReactInstance\n        };\n    }\n\n    class PureComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> { }\n\n    interface ClassicComponent<P = {}, S = {}> extends Component<P, S> {\n        replaceState(nextState: S, callback?: () => void): void;\n        isMounted(): boolean;\n        getInitialState?(): S;\n    }\n\n    interface ChildContextProvider<CC> {\n        getChildContext(): CC;\n    }\n\n    //\n    // Class Interfaces\n    // ----------------------------------------------------------------------\n\n   \n    type SFC<P = {}> = FunctionComponent<P>;\n\n    type StatelessComponent<P = {}> = FunctionComponent<P>;\n\n    type FC<P = {}> = FunctionComponent<P>;\n\n    interface FunctionComponent<P = {}> {\n        (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;\n        propTypes?: WeakValidationMap<P>;\n        contextTypes?: ValidationMap<any>;\n        defaultProps?: Partial<P>;\n        displayName?: string;\n    }\n\n    interface ForwardRefRenderFunction<T, P = {}> {\n        (props: PropsWithChildren<P>, ref: ((instance: T | null) => void) | MutableRefObject<T | null> | null): ReactElement | null;\n        displayName?: string;\n        /**\n         * defaultProps are not supported on render functions\n         */\n        defaultProps?: never;\n        /**\n         * propTypes are not supported on render functions\n         */\n        propTypes?: never;\n    }\n\n    /**\n     * @deprecated Use ForwardRefRenderFunction. forwardRef doesn't accept a\n     *             \"real\" component.\n     */\n    interface RefForwardingComponent <T, P = {}> extends ForwardRefRenderFunction<T, P> {}\n\n    interface ComponentClass<P = {}, S = ComponentState> extends StaticLifecycle<P, S> {\n        new (props: P, context?: any): Component<P, S>;\n        propTypes?: WeakValidationMap<P>;\n        contextType?: Context<any>;\n        contextTypes?: ValidationMap<any>;\n        childContextTypes?: ValidationMap<any>;\n        defaultProps?: Partial<P>;\n        displayName?: string;\n    }\n\n    interface ClassicComponentClass<P = {}> extends ComponentClass<P> {\n        new (props: P, context?: any): ClassicComponent<P, ComponentState>;\n        getDefaultProps?(): P;\n    }\n\n    /**\n     * We use an intersection type to infer multiple type parameters from\n     * a single argument, which is useful for many top-level API defs.\n     * See https://github.com/Microsoft/TypeScript/issues/7234 for more info.\n     */\n    type ClassType<P, T extends Component<P, ComponentState>, C extends ComponentClass<P>> =\n        C &\n        (new (props: P, context?: any) => T);\n\n    //\n    // Component Specs and Lifecycle\n    // ----------------------------------------------------------------------\n\n    interface ComponentLifecycle<P, S, SS = any> extends NewLifecycle<P, S, SS>, DeprecatedLifecycle<P, S> {\n        /**\n         * Called immediately after a component is mounted. Setting state here will trigger re-rendering.\n         */\n        componentDidMount?(): void;\n       \n        shouldComponentUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): boolean;\n       \n        componentWillUnmount?(): void;\n        /**\n         * Catches exceptions generated in descendant components. Unhandled exceptions will cause\n         * the entire component tree to unmount.\n         */\n        componentDidCatch?(error: Error, errorInfo: ErrorInfo): void;\n    }\n\n    // Unfortunately, we have no way of declaring that the component constructor must implement this\n    interface StaticLifecycle<P, S> {\n        getDerivedStateFromProps?: GetDerivedStateFromProps<P, S>;\n        getDerivedStateFromError?: GetDerivedStateFromError<P, S>;\n    }\n\n    type GetDerivedStateFromProps<P, S> =\n        /**\n         * Returns an update to a component's state based on its new props and old state.\n         *\n         * Note: its presence prevents any of the deprecated lifecycle methods from being invoked\n         */\n        (nextProps: Readonly<P>, prevState: S) => Partial<S> | null;\n\n    type GetDerivedStateFromError<P, S> =\n        /**\n         * This lifecycle is invoked after an error has been thrown by a descendant component.\n         * It receives the error that was thrown as a parameter and should return a value to update state.\n         *\n         * Note: its presence prevents any of the deprecated lifecycle methods from being invoked\n         */\n        (error: any) => Partial<S> | null;\n\n    // This should be \"infer SS\" but can't use it yet\n    interface NewLifecycle<P, S, SS> {\n        \n        getSnapshotBeforeUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>): SS | null;\n        /**\n         * Called immediately after updating occurs. Not called for the initial render.\n         *\n         * The snapshot is only present if getSnapshotBeforeUpdate is present and returns non-null.\n         */\n        componentDidUpdate?(prevProps: Readonly<P>, prevState: Readonly<S>, snapshot?: SS): void;\n    }\n\n    interface DeprecatedLifecycle<P, S> {\n        \n        componentWillMount?(): void;\n       \n        UNSAFE_componentWillMount?(): void;\n        \n        componentWillReceiveProps?(nextProps: Readonly<P>, nextContext: any): void;\n        \n        UNSAFE_componentWillReceiveProps?(nextProps: Readonly<P>, nextContext: any): void;\n        \n        componentWillUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): void;\n        \n        UNSAFE_componentWillUpdate?(nextProps: Readonly<P>, nextState: Readonly<S>, nextContext: any): void;\n    }\n\n    interface Mixin<P, S> extends ComponentLifecycle<P, S> {\n        mixins?: Array<Mixin<P, S>>;\n        statics?: {\n            [key: string]: any;\n        };\n\n        displayName?: string;\n        propTypes?: ValidationMap<any>;\n        contextTypes?: ValidationMap<any>;\n        childContextTypes?: ValidationMap<any>;\n\n        getDefaultProps?(): P;\n        getInitialState?(): S;\n    }\n\n    interface ComponentSpec<P, S> extends Mixin<P, S> {\n        render(): ReactNode;\n\n        [propertyName: string]: any;\n    }\n\n    function createRef<T>(): RefObject<T>;\n\n    interface ForwardRefExoticComponent<P> extends NamedExoticComponent<P> {\n        defaultProps?: Partial<P>;\n        propTypes?: WeakValidationMap<P>;\n    }\n\n    function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;\n\n    /** Ensures that the props do not include ref at all */\n    type PropsWithoutRef<P> =\n        // Just Pick would be sufficient for this, but I'm trying to avoid unnecessary mapping over union types\n        // https://github.com/Microsoft/TypeScript/issues/28339\n        'ref' extends keyof P\n            ? Pick<P, Exclude<keyof P, 'ref'>>\n            : P;\n    /** Ensures that the props do not include string ref, which cannot be forwarded */\n    type PropsWithRef<P> =\n        // Just \"P extends { ref?: infer R }\" looks sufficient, but R will infer as {} if P is {}.\n        'ref' extends keyof P\n            ? P extends { ref?: infer R }\n                ? string extends R\n                    ? PropsWithoutRef<P> & { ref?: Exclude<R, string> }\n                    : P\n                : P\n            : P;\n\n    type PropsWithChildren<P> = P & { children?: ReactNode };\n\n    /**\n     * NOTE: prefer ComponentPropsWithRef, if the ref is forwarded,\n     * or ComponentPropsWithoutRef when refs are not supported.\n     */\n    type ComponentProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> =\n        T extends JSXElementConstructor<infer P>\n            ? P\n            : T extends keyof JSX.IntrinsicElements\n                ? JSX.IntrinsicElements[T]\n                : {};\n    type ComponentPropsWithRef<T extends ElementType> =\n        T extends ComponentClass<infer P>\n            ? PropsWithoutRef<P> & RefAttributes<InstanceType<T>>\n            : PropsWithRef<ComponentProps<T>>;\n    type ComponentPropsWithoutRef<T extends ElementType> =\n        PropsWithoutRef<ComponentProps<T>>;\n\n    type MemoExoticComponent<T extends ComponentType<any>> = NamedExoticComponent<ComponentPropsWithRef<T>> & {\n        readonly type: T;\n    };\n\n    function memo<P extends object>(\n        Component: SFC<P>,\n        propsAreEqual?: (prevProps: Readonly<PropsWithChildren<P>>, nextProps: Readonly<PropsWithChildren<P>>) => boolean\n    ): NamedExoticComponent<P>;\n    function memo<T extends ComponentType<any>>(\n        Component: T,\n        propsAreEqual?: (prevProps: Readonly<ComponentProps<T>>, nextProps: Readonly<ComponentProps<T>>) => boolean\n    ): MemoExoticComponent<T>;\n\n    type LazyExoticComponent<T extends ComponentType<any>> = ExoticComponent<ComponentPropsWithRef<T>> & {\n        readonly _result: T;\n    };\n\n    function lazy<T extends ComponentType<any>>(\n        factory: () => Promise<{ default: T }>\n    ): LazyExoticComponent<T>;\n\n    //\n    // React Hooks\n    // ----------------------------------------------------------------------\n\n    // based on the code in https://github.com/facebook/react/pull/13968\n\n    // Unlike the class component setState, the updates are not allowed to be partial\n    type SetStateAction<S> = S | ((prevState: S) => S);\n    // this technically does accept a second argument, but it's already under a deprecation warning\n    // and it's not even released so probably better to not define it.\n    type Dispatch<A> = (value: A) => void;\n    // Since action _can_ be undefined, dispatch may be called without any parameters.\n    type DispatchWithoutAction = () => void;\n    // Unlike redux, the actions _can_ be anything\n    type Reducer<S, A> = (prevState: S, action: A) => S;\n    // If useReducer accepts a reducer without action, dispatch may be called without any parameters.\n    type ReducerWithoutAction<S> = (prevState: S) => S;\n    // types used to try and prevent the compiler from reducing S\n    // to a supertype common with the second argument to useReducer()\n    type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never;\n    type ReducerAction<R extends Reducer<any, any>> = R extends Reducer<any, infer A> ? A : never;\n    // The identity check is done with the SameValue algorithm (Object.is), which is stricter than ===\n    type ReducerStateWithoutAction<R extends ReducerWithoutAction<any>> =\n        R extends ReducerWithoutAction<infer S> ? S : never;\n    // TODO (TypeScript 3.0): ReadonlyArray<unknown>\n    type DependencyList = ReadonlyArray<any>;\n\n    // NOTE: callbacks are _only_ allowed to return either void, or a destructor.\n    // The destructor is itself only allowed to return void.\n    type EffectCallback = () => (void | (() => void | undefined));\n\n    interface MutableRefObject<T> {\n        current: T;\n    }\n\n    // This will technically work if you give a Consumer<T> or Provider<T> but it's deprecated and warns\n    \n    function useContext<T>(context: Context<T>/*, (not public API) observedBits?: number|boolean */): T;\n    /**\n     * Returns a stateful value, and a function to update it.\n     *\n     * @version 16.8.0\n     * @see https://reactjs.org/docs/hooks-reference.html#usestate\n     */\n    function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];\n    // convenience overload when first argument is ommitted\n    /**\n     * Returns a stateful value, and a function to update it.\n     *\n     * @version 16.8.0\n     * @see https://reactjs.org/docs/hooks-reference.html#usestate\n     */\n    function useState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>];\n\n    // overload where dispatch could accept 0 arguments.\n    function useReducer<R extends ReducerWithoutAction<any>, I>(\n        reducer: R,\n        initializerArg: I,\n        initializer: (arg: I) => ReducerStateWithoutAction<R>\n    ): [ReducerStateWithoutAction<R>, DispatchWithoutAction];\n \n    // overload where dispatch could accept 0 arguments.\n    function useReducer<R extends ReducerWithoutAction<any>>(\n        reducer: R,\n        initializerArg: ReducerStateWithoutAction<R>,\n        initializer?: undefined\n    ): [ReducerStateWithoutAction<R>, DispatchWithoutAction];\n  \n    // overload where \"I\" may be a subset of ReducerState<R>; used to provide autocompletion.\n    // If \"I\" matches ReducerState<R> exactly then the last overload will allow initializer to be ommitted.\n    // the last overload effectively behaves as if the identity function (x => x) is the initializer.\n    function useReducer<R extends Reducer<any, any>, I>(\n        reducer: R,\n        initializerArg: I & ReducerState<R>,\n        initializer: (arg: I & ReducerState<R>) => ReducerState<R>\n    ): [ReducerState<R>, Dispatch<ReducerAction<R>>];\n   \n    // overload for free \"I\"; all goes as long as initializer converts it into \"ReducerState<R>\".\n    function useReducer<R extends Reducer<any, any>, I>(\n        reducer: R,\n        initializerArg: I,\n        initializer: (arg: I) => ReducerState<R>\n    ): [ReducerState<R>, Dispatch<ReducerAction<R>>];\n   \n\n    // I'm not sure if I keep this 2-ary or if I make it (2,3)-ary; it's currently (2,3)-ary.\n    // The Flow types do have an overload for 3-ary invocation with undefined initializer.\n\n    // NOTE: without the ReducerState indirection, TypeScript would reduce S to be the most common\n    // supertype between the reducer's return type and the initialState (or the initializer's return type),\n    // which would prevent autocompletion from ever working.\n\n    // TODO: double-check if this weird overload logic is necessary. It is possible it's either a bug\n    // in older versions, or a regression in newer versions of the typescript completion service.\n    function useReducer<R extends Reducer<any, any>>(\n        reducer: R,\n        initialState: ReducerState<R>,\n        initializer?: undefined\n    ): [ReducerState<R>, Dispatch<ReducerAction<R>>];\n    \n    // TODO (TypeScript 3.0): <T extends unknown>\n    function useRef<T>(initialValue: T): MutableRefObject<T>;\n    // convenience overload for refs given as a ref prop as they typically start with a null value\n    \n    // TODO (TypeScript 3.0): <T extends unknown>\n    function useRef<T>(initialValue: T|null): RefObject<T>;\n    // convenience overload for potentially undefined initialValue / call with 0 arguments\n    // has a default to stop it from defaulting to {} instead\n    \n    // TODO (TypeScript 3.0): <T extends unknown>\n    function useRef<T = undefined>(): MutableRefObject<T | undefined>;\n    \n    function useLayoutEffect(effect: EffectCallback, deps?: DependencyList): void;\n    /**\n     * Accepts a function that contains imperative, possibly effectful code.\n     *\n     * @param effect Imperative function that can return a cleanup function\n     * @param deps If present, effect will only activate if the values in the list change.\n     *\n     * @version 16.8.0\n     * @see https://reactjs.org/docs/hooks-reference.html#useeffect\n     */\n    function useEffect(effect: EffectCallback, deps?: DependencyList): void;\n    // NOTE: this does not accept strings, but this will have to be fixed by removing strings from type Ref<T>\n    \n    function useImperativeHandle<T, R extends T>(ref: Ref<T>|undefined, init: () => R, deps?: DependencyList): void;\n    // I made 'inputs' required here and in useMemo as there's no point to memoizing without the memoization key\n    // useCallback(X) is identical to just using X, useMemo(() => Y) is identical to just using Y.\n    \n    // TODO (TypeScript 3.0): <T extends (...args: never[]) => unknown>\n    function useCallback<T extends (...args: any[]) => any>(callback: T, deps: DependencyList): T;\n    \n    // allow undefined, but don't make it optional as that is very likely a mistake\n    function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T;\n   \n    // the name of the custom hook is itself derived from the function name at runtime:\n    // it's just the function name without the \"use\" prefix.\n    function useDebugValue<T>(value: T, format?: (value: T) => any): void;\n\n    //\n    // Event System\n    // ----------------------------------------------------------------------\n    // TODO: change any to unknown when moving to TS v3\n    interface BaseSyntheticEvent<E = object, C = any, T = any> {\n        nativeEvent: E;\n        currentTarget: C;\n        target: T;\n        bubbles: boolean;\n        cancelable: boolean;\n        defaultPrevented: boolean;\n        eventPhase: number;\n        isTrusted: boolean;\n        preventDefault(): void;\n        isDefaultPrevented(): boolean;\n        stopPropagation(): void;\n        isPropagationStopped(): boolean;\n        persist(): void;\n        timeStamp: number;\n        type: string;\n    }\n\n    interface SyntheticEvent<T = Element, E = Event> extends BaseSyntheticEvent<E, EventTarget & T, EventTarget> {}\n\n    interface ClipboardEvent<T = Element> extends SyntheticEvent<T, NativeClipboardEvent> {\n        clipboardData: DataTransfer;\n    }\n\n    interface CompositionEvent<T = Element> extends SyntheticEvent<T, NativeCompositionEvent> {\n        data: string;\n    }\n\n    interface DragEvent<T = Element> extends MouseEvent<T, NativeDragEvent> {\n        dataTransfer: DataTransfer;\n    }\n\n    interface PointerEvent<T = Element> extends MouseEvent<T, NativePointerEvent> {\n        pointerId: number;\n        pressure: number;\n        tangentialPressure: number;\n        tiltX: number;\n        tiltY: number;\n        twist: number;\n        width: number;\n        height: number;\n        pointerType: 'mouse' | 'pen' | 'touch';\n        isPrimary: boolean;\n    }\n\n    interface FocusEvent<T = Element> extends SyntheticEvent<T, NativeFocusEvent> {\n        relatedTarget: EventTarget | null;\n        target: EventTarget & T;\n    }\n\n    // tslint:disable-next-line:no-empty-interface\n    interface FormEvent<T = Element> extends SyntheticEvent<T> {\n    }\n\n    interface InvalidEvent<T = Element> extends SyntheticEvent<T> {\n        target: EventTarget & T;\n    }\n\n    interface ChangeEvent<T = Element> extends SyntheticEvent<T> {\n        target: EventTarget & T;\n    }\n\n    interface KeyboardEvent<T = Element> extends SyntheticEvent<T, NativeKeyboardEvent> {\n        altKey: boolean;\n        charCode: number;\n        ctrlKey: boolean;\n        /**\n         * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.\n         */\n        getModifierState(key: string): boolean;\n        /**\n         * See the [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#named-key-attribute-values). for possible values\n         */\n        key: string;\n        keyCode: number;\n        locale: string;\n        location: number;\n        metaKey: boolean;\n        repeat: boolean;\n        shiftKey: boolean;\n        /** @deprecated */\n        which: number;\n    }\n\n    interface MouseEvent<T = Element, E = NativeMouseEvent> extends UIEvent<T, E> {\n        altKey: boolean;\n        button: number;\n        buttons: number;\n        clientX: number;\n        clientY: number;\n        ctrlKey: boolean;\n        /**\n         * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.\n         */\n        getModifierState(key: string): boolean;\n        metaKey: boolean;\n        movementX: number;\n        movementY: number;\n        pageX: number;\n        pageY: number;\n        relatedTarget: EventTarget | null;\n        screenX: number;\n        screenY: number;\n        shiftKey: boolean;\n    }\n\n    interface TouchEvent<T = Element> extends UIEvent<T, NativeTouchEvent> {\n        altKey: boolean;\n        changedTouches: TouchList;\n        ctrlKey: boolean;\n        /**\n         * See [DOM Level 3 Events spec](https://www.w3.org/TR/uievents-key/#keys-modifier). for a list of valid (case-sensitive) arguments to this method.\n         */\n        getModifierState(key: string): boolean;\n        metaKey: boolean;\n        shiftKey: boolean;\n        targetTouches: TouchList;\n        touches: TouchList;\n    }\n\n    interface UIEvent<T = Element, E = NativeUIEvent> extends SyntheticEvent<T, E> {\n        detail: number;\n        view: AbstractView;\n    }\n\n    interface WheelEvent<T = Element> extends MouseEvent<T, NativeWheelEvent> {\n        deltaMode: number;\n        deltaX: number;\n        deltaY: number;\n        deltaZ: number;\n    }\n\n    interface AnimationEvent<T = Element> extends SyntheticEvent<T, NativeAnimationEvent> {\n        animationName: string;\n        elapsedTime: number;\n        pseudoElement: string;\n    }\n\n    interface TransitionEvent<T = Element> extends SyntheticEvent<T, NativeTransitionEvent> {\n        elapsedTime: number;\n        propertyName: string;\n        pseudoElement: string;\n    }\n\n    //\n    // Event Handler Types\n    // ----------------------------------------------------------------------\n\n    type EventHandler<E extends SyntheticEvent<any>> = { bivarianceHack(event: E): void }[\"bivarianceHack\"];\n\n    type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\n    type ClipboardEventHandler<T = Element> = EventHandler<ClipboardEvent<T>>;\n    type CompositionEventHandler<T = Element> = EventHandler<CompositionEvent<T>>;\n    type DragEventHandler<T = Element> = EventHandler<DragEvent<T>>;\n    type FocusEventHandler<T = Element> = EventHandler<FocusEvent<T>>;\n    type FormEventHandler<T = Element> = EventHandler<FormEvent<T>>;\n    type ChangeEventHandler<T = Element> = EventHandler<ChangeEvent<T>>;\n    type KeyboardEventHandler<T = Element> = EventHandler<KeyboardEvent<T>>;\n    type MouseEventHandler<T = Element> = EventHandler<MouseEvent<T>>;\n    type TouchEventHandler<T = Element> = EventHandler<TouchEvent<T>>;\n    type PointerEventHandler<T = Element> = EventHandler<PointerEvent<T>>;\n    type UIEventHandler<T = Element> = EventHandler<UIEvent<T>>;\n    type WheelEventHandler<T = Element> = EventHandler<WheelEvent<T>>;\n    type AnimationEventHandler<T = Element> = EventHandler<AnimationEvent<T>>;\n    type TransitionEventHandler<T = Element> = EventHandler<TransitionEvent<T>>;\n\n    //\n    // Props / DOM Attributes\n    // ----------------------------------------------------------------------\n\n \n    interface Props<T> {\n        children?: ReactNode;\n        key?: Key;\n        ref?: LegacyRef<T>;\n    }\n\n    interface HTMLProps<T> extends AllHTMLAttributes<T>, ClassAttributes<T> {\n    }\n\n    type DetailedHTMLProps<E extends HTMLAttributes<T>, T> = ClassAttributes<T> & E;\n\n    interface SVGProps<T> extends SVGAttributes<T>, ClassAttributes<T> {\n    }\n\n    interface DOMAttributes<T> {\n        children?: ReactNode;\n        dangerouslySetInnerHTML?: {\n            __html: string;\n        };\n\n        // Clipboard Events\n        onCopy?: ClipboardEventHandler<T>;\n        onCopyCapture?: ClipboardEventHandler<T>;\n        onCut?: ClipboardEventHandler<T>;\n        onCutCapture?: ClipboardEventHandler<T>;\n        onPaste?: ClipboardEventHandler<T>;\n        onPasteCapture?: ClipboardEventHandler<T>;\n\n        // Composition Events\n        onCompositionEnd?: CompositionEventHandler<T>;\n        onCompositionEndCapture?: CompositionEventHandler<T>;\n        onCompositionStart?: CompositionEventHandler<T>;\n        onCompositionStartCapture?: CompositionEventHandler<T>;\n        onCompositionUpdate?: CompositionEventHandler<T>;\n        onCompositionUpdateCapture?: CompositionEventHandler<T>;\n\n        // Focus Events\n        onFocus?: FocusEventHandler<T>;\n        onFocusCapture?: FocusEventHandler<T>;\n        onBlur?: FocusEventHandler<T>;\n        onBlurCapture?: FocusEventHandler<T>;\n\n        // Form Events\n        onChange?: FormEventHandler<T>;\n        onChangeCapture?: FormEventHandler<T>;\n        onBeforeInput?: FormEventHandler<T>;\n        onBeforeInputCapture?: FormEventHandler<T>;\n        onInput?: FormEventHandler<T>;\n        onInputCapture?: FormEventHandler<T>;\n        onReset?: FormEventHandler<T>;\n        onResetCapture?: FormEventHandler<T>;\n        onSubmit?: FormEventHandler<T>;\n        onSubmitCapture?: FormEventHandler<T>;\n        onInvalid?: FormEventHandler<T>;\n        onInvalidCapture?: FormEventHandler<T>;\n\n        // Image Events\n        onLoad?: ReactEventHandler<T>;\n        onLoadCapture?: ReactEventHandler<T>;\n        onError?: ReactEventHandler<T>; // also a Media Event\n        onErrorCapture?: ReactEventHandler<T>; // also a Media Event\n\n        // Keyboard Events\n        onKeyDown?: KeyboardEventHandler<T>;\n        onKeyDownCapture?: KeyboardEventHandler<T>;\n        onKeyPress?: KeyboardEventHandler<T>;\n        onKeyPressCapture?: KeyboardEventHandler<T>;\n        onKeyUp?: KeyboardEventHandler<T>;\n        onKeyUpCapture?: KeyboardEventHandler<T>;\n\n        // Media Events\n        onAbort?: ReactEventHandler<T>;\n        onAbortCapture?: ReactEventHandler<T>;\n        onCanPlay?: ReactEventHandler<T>;\n        onCanPlayCapture?: ReactEventHandler<T>;\n        onCanPlayThrough?: ReactEventHandler<T>;\n        onCanPlayThroughCapture?: ReactEventHandler<T>;\n        onDurationChange?: ReactEventHandler<T>;\n        onDurationChangeCapture?: ReactEventHandler<T>;\n        onEmptied?: ReactEventHandler<T>;\n        onEmptiedCapture?: ReactEventHandler<T>;\n        onEncrypted?: ReactEventHandler<T>;\n        onEncryptedCapture?: ReactEventHandler<T>;\n        onEnded?: ReactEventHandler<T>;\n        onEndedCapture?: ReactEventHandler<T>;\n        onLoadedData?: ReactEventHandler<T>;\n        onLoadedDataCapture?: ReactEventHandler<T>;\n        onLoadedMetadata?: ReactEventHandler<T>;\n        onLoadedMetadataCapture?: ReactEventHandler<T>;\n        onLoadStart?: ReactEventHandler<T>;\n        onLoadStartCapture?: ReactEventHandler<T>;\n        onPause?: ReactEventHandler<T>;\n        onPauseCapture?: ReactEventHandler<T>;\n        onPlay?: ReactEventHandler<T>;\n        onPlayCapture?: ReactEventHandler<T>;\n        onPlaying?: ReactEventHandler<T>;\n        onPlayingCapture?: ReactEventHandler<T>;\n        onProgress?: ReactEventHandler<T>;\n        onProgressCapture?: ReactEventHandler<T>;\n        onRateChange?: ReactEventHandler<T>;\n        onRateChangeCapture?: ReactEventHandler<T>;\n        onSeeked?: ReactEventHandler<T>;\n        onSeekedCapture?: ReactEventHandler<T>;\n        onSeeking?: ReactEventHandler<T>;\n        onSeekingCapture?: ReactEventHandler<T>;\n        onStalled?: ReactEventHandler<T>;\n        onStalledCapture?: ReactEventHandler<T>;\n        onSuspend?: ReactEventHandler<T>;\n        onSuspendCapture?: ReactEventHandler<T>;\n        onTimeUpdate?: ReactEventHandler<T>;\n        onTimeUpdateCapture?: ReactEventHandler<T>;\n        onVolumeChange?: ReactEventHandler<T>;\n        onVolumeChangeCapture?: ReactEventHandler<T>;\n        onWaiting?: ReactEventHandler<T>;\n        onWaitingCapture?: ReactEventHandler<T>;\n\n        // MouseEvents\n        onAuxClick?: MouseEventHandler<T>;\n        onAuxClickCapture?: MouseEventHandler<T>;\n        onClick?: MouseEventHandler<T>;\n        onClickCapture?: MouseEventHandler<T>;\n        onContextMenu?: MouseEventHandler<T>;\n        onContextMenuCapture?: MouseEventHandler<T>;\n        onDoubleClick?: MouseEventHandler<T>;\n        onDoubleClickCapture?: MouseEventHandler<T>;\n        onDrag?: DragEventHandler<T>;\n        onDragCapture?: DragEventHandler<T>;\n        onDragEnd?: DragEventHandler<T>;\n        onDragEndCapture?: DragEventHandler<T>;\n        onDragEnter?: DragEventHandler<T>;\n        onDragEnterCapture?: DragEventHandler<T>;\n        onDragExit?: DragEventHandler<T>;\n        onDragExitCapture?: DragEventHandler<T>;\n        onDragLeave?: DragEventHandler<T>;\n        onDragLeaveCapture?: DragEventHandler<T>;\n        onDragOver?: DragEventHandler<T>;\n        onDragOverCapture?: DragEventHandler<T>;\n        onDragStart?: DragEventHandler<T>;\n        onDragStartCapture?: DragEventHandler<T>;\n        onDrop?: DragEventHandler<T>;\n        onDropCapture?: DragEventHandler<T>;\n        onMouseDown?: MouseEventHandler<T>;\n        onMouseDownCapture?: MouseEventHandler<T>;\n        onMouseEnter?: MouseEventHandler<T>;\n        onMouseLeave?: MouseEventHandler<T>;\n        onMouseMove?: MouseEventHandler<T>;\n        onMouseMoveCapture?: MouseEventHandler<T>;\n        onMouseOut?: MouseEventHandler<T>;\n        onMouseOutCapture?: MouseEventHandler<T>;\n        onMouseOver?: MouseEventHandler<T>;\n        onMouseOverCapture?: MouseEventHandler<T>;\n        onMouseUp?: MouseEventHandler<T>;\n        onMouseUpCapture?: MouseEventHandler<T>;\n\n        // Selection Events\n        onSelect?: ReactEventHandler<T>;\n        onSelectCapture?: ReactEventHandler<T>;\n\n        // Touch Events\n        onTouchCancel?: TouchEventHandler<T>;\n        onTouchCancelCapture?: TouchEventHandler<T>;\n        onTouchEnd?: TouchEventHandler<T>;\n        onTouchEndCapture?: TouchEventHandler<T>;\n        onTouchMove?: TouchEventHandler<T>;\n        onTouchMoveCapture?: TouchEventHandler<T>;\n        onTouchStart?: TouchEventHandler<T>;\n        onTouchStartCapture?: TouchEventHandler<T>;\n\n        // Pointer Events\n        onPointerDown?: PointerEventHandler<T>;\n        onPointerDownCapture?: PointerEventHandler<T>;\n        onPointerMove?: PointerEventHandler<T>;\n        onPointerMoveCapture?: PointerEventHandler<T>;\n        onPointerUp?: PointerEventHandler<T>;\n        onPointerUpCapture?: PointerEventHandler<T>;\n        onPointerCancel?: PointerEventHandler<T>;\n        onPointerCancelCapture?: PointerEventHandler<T>;\n        onPointerEnter?: PointerEventHandler<T>;\n        onPointerEnterCapture?: PointerEventHandler<T>;\n        onPointerLeave?: PointerEventHandler<T>;\n        onPointerLeaveCapture?: PointerEventHandler<T>;\n        onPointerOver?: PointerEventHandler<T>;\n        onPointerOverCapture?: PointerEventHandler<T>;\n        onPointerOut?: PointerEventHandler<T>;\n        onPointerOutCapture?: PointerEventHandler<T>;\n        onGotPointerCapture?: PointerEventHandler<T>;\n        onGotPointerCaptureCapture?: PointerEventHandler<T>;\n        onLostPointerCapture?: PointerEventHandler<T>;\n        onLostPointerCaptureCapture?: PointerEventHandler<T>;\n\n        // UI Events\n        onScroll?: UIEventHandler<T>;\n        onScrollCapture?: UIEventHandler<T>;\n\n        // Wheel Events\n        onWheel?: WheelEventHandler<T>;\n        onWheelCapture?: WheelEventHandler<T>;\n\n        // Animation Events\n        onAnimationStart?: AnimationEventHandler<T>;\n        onAnimationStartCapture?: AnimationEventHandler<T>;\n        onAnimationEnd?: AnimationEventHandler<T>;\n        onAnimationEndCapture?: AnimationEventHandler<T>;\n        onAnimationIteration?: AnimationEventHandler<T>;\n        onAnimationIterationCapture?: AnimationEventHandler<T>;\n\n        // Transition Events\n        onTransitionEnd?: TransitionEventHandler<T>;\n        onTransitionEndCapture?: TransitionEventHandler<T>;\n    }\n\n    export interface CSSProperties extends CSS.Properties<string | number> {\n        /**\n         * The index signature was removed to enable closed typing for style\n         * using CSSType. You're able to use type assertion or module augmentation\n         * to add properties or an index signature of your own.\n         *\n         * For examples and more information, visit:\n         * https://github.com/frenic/csstype#what-should-i-do-when-i-get-type-errors\n         */\n    }\n\n    // All the WAI-ARIA 1.1 attributes from https://www.w3.org/TR/wai-aria-1.1/\n    interface AriaAttributes {\n        /** Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. */\n        'aria-activedescendant'?: string;\n        /** Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. */\n        'aria-atomic'?: boolean | 'false' | 'true';\n        /**\n         * Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\n         * presented if they are made.\n         */\n        'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both';\n        /** Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user. */\n        'aria-busy'?: boolean | 'false' | 'true';\n        /**\n         * Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets.\n         * @see aria-pressed @see aria-selected.\n         */\n        'aria-checked'?: boolean | 'false' | 'mixed' | 'true';\n        /**\n         * Defines the total number of columns in a table, grid, or treegrid.\n         * @see aria-colindex.\n         */\n        'aria-colcount'?: number;\n        /**\n         * Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid.\n         * @see aria-colcount @see aria-colspan.\n         */\n        'aria-colindex'?: number;\n        /**\n         * Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.\n         * @see aria-colindex @see aria-rowspan.\n         */\n        'aria-colspan'?: number;\n        /**\n         * Identifies the element (or elements) whose contents or presence are controlled by the current element.\n         * @see aria-owns.\n         */\n        'aria-controls'?: string;\n        /** Indicates the element that represents the current item within a container or set of related elements. */\n        'aria-current'?: boolean | 'false' | 'true' | 'page' | 'step' | 'location' | 'date' | 'time';\n        /**\n         * Identifies the element (or elements) that describes the object.\n         * @see aria-labelledby\n         */\n        'aria-describedby'?: string;\n        /**\n         * Identifies the element that provides a detailed, extended description for the object.\n         * @see aria-describedby.\n         */\n        'aria-details'?: string;\n        /**\n         * Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.\n         * @see aria-hidden @see aria-readonly.\n         */\n        'aria-disabled'?: boolean | 'false' | 'true';\n        /**\n         * Indicates what functions can be performed when a dragged object is released on the drop target.\n         * @deprecated in ARIA 1.1\n         */\n        'aria-dropeffect'?: 'none' | 'copy' | 'execute' | 'link' | 'move' | 'popup';\n        /**\n         * Identifies the element that provides an error message for the object.\n         * @see aria-invalid @see aria-describedby.\n         */\n        'aria-errormessage'?: string;\n        /** Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. */\n        'aria-expanded'?: boolean | 'false' | 'true';\n        /**\n         * Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion,\n         * allows assistive technology to override the general default of reading in document source order.\n         */\n        'aria-flowto'?: string;\n        /**\n         * Indicates an element's \"grabbed\" state in a drag-and-drop operation.\n         * @deprecated in ARIA 1.1\n         */\n        'aria-grabbed'?: boolean | 'false' | 'true';\n        /** Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. */\n        'aria-haspopup'?: boolean | 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';\n        /**\n         * Indicates whether the element is exposed to an accessibility API.\n         * @see aria-disabled.\n         */\n        'aria-hidden'?: boolean | 'false' | 'true';\n        /**\n         * Indicates the entered value does not conform to the format expected by the application.\n         * @see aria-errormessage.\n         */\n        'aria-invalid'?: boolean | 'false' | 'true' | 'grammar' | 'spelling';\n        /** Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. */\n        'aria-keyshortcuts'?: string;\n        /**\n         * Defines a string value that labels the current element.\n         * @see aria-labelledby.\n         */\n        'aria-label'?: string;\n        /**\n         * Identifies the element (or elements) that labels the current element.\n         * @see aria-describedby.\n         */\n        'aria-labelledby'?: string;\n        /** Defines the hierarchical level of an element within a structure. */\n        'aria-level'?: number;\n        /** Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. */\n        'aria-live'?: 'off' | 'assertive' | 'polite';\n        /** Indicates whether an element is modal when displayed. */\n        'aria-modal'?: boolean | 'false' | 'true';\n        /** Indicates whether a text box accepts multiple lines of input or only a single line. */\n        'aria-multiline'?: boolean | 'false' | 'true';\n        /** Indicates that the user may select more than one item from the current selectable descendants. */\n        'aria-multiselectable'?: boolean | 'false' | 'true';\n        /** Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous. */\n        'aria-orientation'?: 'horizontal' | 'vertical';\n        /**\n         * Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship\n         * between DOM elements where the DOM hierarchy cannot be used to represent the relationship.\n         * @see aria-controls.\n         */\n        'aria-owns'?: string;\n        /**\n         * Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value.\n         * A hint could be a sample value or a brief description of the expected format.\n         */\n        'aria-placeholder'?: string;\n        /**\n         * Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n         * @see aria-setsize.\n         */\n        'aria-posinset'?: number;\n        /**\n         * Indicates the current \"pressed\" state of toggle buttons.\n         * @see aria-checked @see aria-selected.\n         */\n        'aria-pressed'?: boolean | 'false' | 'mixed' | 'true';\n        /**\n         * Indicates that the element is not editable, but is otherwise operable.\n         * @see aria-disabled.\n         */\n        'aria-readonly'?: boolean | 'false' | 'true';\n        /**\n         * Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.\n         * @see aria-atomic.\n         */\n        'aria-relevant'?: 'additions' | 'additions text' | 'all' | 'removals' | 'text';\n        /** Indicates that user input is required on the element before a form may be submitted. */\n        'aria-required'?: boolean | 'false' | 'true';\n        /** Defines a human-readable, author-localized description for the role of an element. */\n        'aria-roledescription'?: string;\n        /**\n         * Defines the total number of rows in a table, grid, or treegrid.\n         * @see aria-rowindex.\n         */\n        'aria-rowcount'?: number;\n        /**\n         * Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid.\n         * @see aria-rowcount @see aria-rowspan.\n         */\n        'aria-rowindex'?: number;\n        /**\n         * Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.\n         * @see aria-rowindex @see aria-colspan.\n         */\n        'aria-rowspan'?: number;\n        /**\n         * Indicates the current \"selected\" state of various widgets.\n         * @see aria-checked @see aria-pressed.\n         */\n        'aria-selected'?: boolean | 'false' | 'true';\n        /**\n         * Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n         * @see aria-posinset.\n         */\n        'aria-setsize'?: number;\n        /** Indicates if items in a table or grid are sorted in ascending or descending order. */\n        'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other';\n        /** Defines the maximum allowed value for a range widget. */\n        'aria-valuemax'?: number;\n        /** Defines the minimum allowed value for a range widget. */\n        'aria-valuemin'?: number;\n        /**\n         * Defines the current value for a range widget.\n         * @see aria-valuetext.\n         */\n        'aria-valuenow'?: number;\n        /** Defines the human readable text alternative of aria-valuenow for a range widget. */\n        'aria-valuetext'?: string;\n    }\n\n    interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {\n        // React-specific Attributes\n        defaultChecked?: boolean;\n        defaultValue?: string | number | ReadonlyArray<string>;\n        suppressContentEditableWarning?: boolean;\n        suppressHydrationWarning?: boolean;\n\n        // Standard HTML Attributes\n        accessKey?: string;\n        className?: string;\n        contentEditable?: Booleanish | \"inherit\";\n        contextMenu?: string;\n        dir?: string;\n        draggable?: Booleanish;\n        hidden?: boolean;\n        id?: string;\n        lang?: string;\n        placeholder?: string;\n        slot?: string;\n        spellCheck?: Booleanish;\n        style?: CSSProperties;\n        tabIndex?: number;\n        title?: string;\n        translate?: 'yes' | 'no';\n\n        // Unknown\n        radioGroup?: string; // <command>, <menuitem>\n\n        // WAI-ARIA\n        role?: string;\n\n        // RDFa Attributes\n        about?: string;\n        datatype?: string;\n        inlist?: any;\n        prefix?: string;\n        property?: string;\n        resource?: string;\n        typeof?: string;\n        vocab?: string;\n\n        // Non-standard Attributes\n        autoCapitalize?: string;\n        autoCorrect?: string;\n        autoSave?: string;\n        color?: string;\n        itemProp?: string;\n        itemScope?: boolean;\n        itemType?: string;\n        itemID?: string;\n        itemRef?: string;\n        results?: number;\n        security?: string;\n        unselectable?: 'on' | 'off';\n\n        // Living Standard\n        /**\n         * Hints at the type of data that might be entered by the user while editing the element or its contents\n         * @see https://html.spec.whatwg.org/multipage/interaction.html#input-modalities:-the-inputmode-attribute\n         */\n        inputMode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';\n        /**\n         * Specify that a standard HTML element should behave like a defined custom built-in element\n         * @see https://html.spec.whatwg.org/multipage/custom-elements.html#attr-is\n         */\n        is?: string;\n    }\n\n    interface AllHTMLAttributes<T> extends HTMLAttributes<T> {\n        // Standard HTML Attributes\n        accept?: string;\n        acceptCharset?: string;\n        action?: string;\n        allowFullScreen?: boolean;\n        allowTransparency?: boolean;\n        alt?: string;\n        as?: string;\n        async?: boolean;\n        autoComplete?: string;\n        autoFocus?: boolean;\n        autoPlay?: boolean;\n        capture?: boolean | string;\n        cellPadding?: number | string;\n        cellSpacing?: number | string;\n        charSet?: string;\n        challenge?: string;\n        checked?: boolean;\n        cite?: string;\n        classID?: string;\n        cols?: number;\n        colSpan?: number;\n        content?: string;\n        controls?: boolean;\n        coords?: string;\n        crossOrigin?: string;\n        data?: string;\n        dateTime?: string;\n        default?: boolean;\n        defer?: boolean;\n        disabled?: boolean;\n        download?: any;\n        encType?: string;\n        form?: string;\n        formAction?: string;\n        formEncType?: string;\n        formMethod?: string;\n        formNoValidate?: boolean;\n        formTarget?: string;\n        frameBorder?: number | string;\n        headers?: string;\n        height?: number | string;\n        high?: number;\n        href?: string;\n        hrefLang?: string;\n        htmlFor?: string;\n        httpEquiv?: string;\n        integrity?: string;\n        keyParams?: string;\n        keyType?: string;\n        kind?: string;\n        label?: string;\n        list?: string;\n        loop?: boolean;\n        low?: number;\n        manifest?: string;\n        marginHeight?: number;\n        marginWidth?: number;\n        max?: number | string;\n        maxLength?: number;\n        media?: string;\n        mediaGroup?: string;\n        method?: string;\n        min?: number | string;\n        minLength?: number;\n        multiple?: boolean;\n        muted?: boolean;\n        name?: string;\n        nonce?: string;\n        noValidate?: boolean;\n        open?: boolean;\n        optimum?: number;\n        pattern?: string;\n        placeholder?: string;\n        playsInline?: boolean;\n        poster?: string;\n        preload?: string;\n        readOnly?: boolean;\n        rel?: string;\n        required?: boolean;\n        reversed?: boolean;\n        rows?: number;\n        rowSpan?: number;\n        sandbox?: string;\n        scope?: string;\n        scoped?: boolean;\n        scrolling?: string;\n        seamless?: boolean;\n        selected?: boolean;\n        shape?: string;\n        size?: number;\n        sizes?: string;\n        span?: number;\n        src?: string;\n        srcDoc?: string;\n        srcLang?: string;\n        srcSet?: string;\n        start?: number;\n        step?: number | string;\n        summary?: string;\n        target?: string;\n        type?: string;\n        useMap?: string;\n        value?: string | ReadonlyArray<string> | number;\n        width?: number | string;\n        wmode?: string;\n        wrap?: string;\n    }\n\n    interface AnchorHTMLAttributes<T> extends HTMLAttributes<T> {\n        download?: any;\n        href?: string;\n        hrefLang?: string;\n        media?: string;\n        ping?: string;\n        rel?: string;\n        target?: string;\n        type?: string;\n        referrerPolicy?: string;\n    }\n\n    // tslint:disable-next-line:no-empty-interface\n    interface AudioHTMLAttributes<T> extends MediaHTMLAttributes<T> {}\n\n    interface AreaHTMLAttributes<T> extends HTMLAttributes<T> {\n        alt?: string;\n        coords?: string;\n        download?: any;\n        href?: string;\n        hrefLang?: string;\n        media?: string;\n        rel?: string;\n        shape?: string;\n        target?: string;\n    }\n\n    interface BaseHTMLAttributes<T> extends HTMLAttributes<T> {\n        href?: string;\n        target?: string;\n    }\n\n    interface BlockquoteHTMLAttributes<T> extends HTMLAttributes<T> {\n        cite?: string;\n    }\n\n    interface ButtonHTMLAttributes<T> extends HTMLAttributes<T> {\n        autoFocus?: boolean;\n        disabled?: boolean;\n        form?: string;\n        formAction?: string;\n        formEncType?: string;\n        formMethod?: string;\n        formNoValidate?: boolean;\n        formTarget?: string;\n        name?: string;\n        type?: 'submit' | 'reset' | 'button';\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface CanvasHTMLAttributes<T> extends HTMLAttributes<T> {\n        height?: number | string;\n        width?: number | string;\n    }\n\n    interface ColHTMLAttributes<T> extends HTMLAttributes<T> {\n        span?: number;\n        width?: number | string;\n    }\n\n    interface ColgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n        span?: number;\n    }\n\n    interface DataHTMLAttributes<T> extends HTMLAttributes<T> {\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface DetailsHTMLAttributes<T> extends HTMLAttributes<T> {\n        open?: boolean;\n    }\n\n    interface DelHTMLAttributes<T> extends HTMLAttributes<T> {\n        cite?: string;\n        dateTime?: string;\n    }\n\n    interface DialogHTMLAttributes<T> extends HTMLAttributes<T> {\n        open?: boolean;\n    }\n\n    interface EmbedHTMLAttributes<T> extends HTMLAttributes<T> {\n        height?: number | string;\n        src?: string;\n        type?: string;\n        width?: number | string;\n    }\n\n    interface FieldsetHTMLAttributes<T> extends HTMLAttributes<T> {\n        disabled?: boolean;\n        form?: string;\n        name?: string;\n    }\n\n    interface FormHTMLAttributes<T> extends HTMLAttributes<T> {\n        acceptCharset?: string;\n        action?: string;\n        autoComplete?: string;\n        encType?: string;\n        method?: string;\n        name?: string;\n        noValidate?: boolean;\n        target?: string;\n    }\n\n    interface HtmlHTMLAttributes<T> extends HTMLAttributes<T> {\n        manifest?: string;\n    }\n\n    interface IframeHTMLAttributes<T> extends HTMLAttributes<T> {\n        allow?: string;\n        allowFullScreen?: boolean;\n        allowTransparency?: boolean;\n        frameBorder?: number | string;\n        height?: number | string;\n        marginHeight?: number;\n        marginWidth?: number;\n        name?: string;\n        referrerPolicy?: string;\n        sandbox?: string;\n        scrolling?: string;\n        seamless?: boolean;\n        src?: string;\n        srcDoc?: string;\n        width?: number | string;\n    }\n\n    interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {\n        alt?: string;\n        crossOrigin?: \"anonymous\" | \"use-credentials\" | \"\";\n        decoding?: \"async\" | \"auto\" | \"sync\";\n        height?: number | string;\n        loading?: \"eager\" | \"lazy\";\n        referrerPolicy?: \"no-referrer\" | \"origin\" | \"unsafe-url\";\n        sizes?: string;\n        src?: string;\n        srcSet?: string;\n        useMap?: string;\n        width?: number | string;\n    }\n\n    interface InsHTMLAttributes<T> extends HTMLAttributes<T> {\n        cite?: string;\n        dateTime?: string;\n    }\n\n    interface InputHTMLAttributes<T> extends HTMLAttributes<T> {\n        accept?: string;\n        alt?: string;\n        autoComplete?: string;\n        autoFocus?: boolean;\n        capture?: boolean | string; // https://www.w3.org/TR/html-media-capture/#the-capture-attribute\n        checked?: boolean;\n        crossOrigin?: string;\n        disabled?: boolean;\n        form?: string;\n        formAction?: string;\n        formEncType?: string;\n        formMethod?: string;\n        formNoValidate?: boolean;\n        formTarget?: string;\n        height?: number | string;\n        list?: string;\n        max?: number | string;\n        maxLength?: number;\n        min?: number | string;\n        minLength?: number;\n        multiple?: boolean;\n        name?: string;\n        pattern?: string;\n        placeholder?: string;\n        readOnly?: boolean;\n        required?: boolean;\n        size?: number;\n        src?: string;\n        step?: number | string;\n        type?: string;\n        value?: string | ReadonlyArray<string> | number;\n        width?: number | string;\n\n        onChange?: ChangeEventHandler<T>;\n    }\n\n    interface KeygenHTMLAttributes<T> extends HTMLAttributes<T> {\n        autoFocus?: boolean;\n        challenge?: string;\n        disabled?: boolean;\n        form?: string;\n        keyType?: string;\n        keyParams?: string;\n        name?: string;\n    }\n\n    interface LabelHTMLAttributes<T> extends HTMLAttributes<T> {\n        form?: string;\n        htmlFor?: string;\n    }\n\n    interface LiHTMLAttributes<T> extends HTMLAttributes<T> {\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface LinkHTMLAttributes<T> extends HTMLAttributes<T> {\n        as?: string;\n        crossOrigin?: string;\n        href?: string;\n        hrefLang?: string;\n        integrity?: string;\n        media?: string;\n        rel?: string;\n        sizes?: string;\n        type?: string;\n        charSet?: string;\n    }\n\n    interface MapHTMLAttributes<T> extends HTMLAttributes<T> {\n        name?: string;\n    }\n\n    interface MenuHTMLAttributes<T> extends HTMLAttributes<T> {\n        type?: string;\n    }\n\n    interface MediaHTMLAttributes<T> extends HTMLAttributes<T> {\n        autoPlay?: boolean;\n        controls?: boolean;\n        controlsList?: string;\n        crossOrigin?: string;\n        loop?: boolean;\n        mediaGroup?: string;\n        muted?: boolean;\n        playsInline?: boolean;\n        preload?: string;\n        src?: string;\n    }\n\n    interface MetaHTMLAttributes<T> extends HTMLAttributes<T> {\n        charSet?: string;\n        content?: string;\n        httpEquiv?: string;\n        name?: string;\n    }\n\n    interface MeterHTMLAttributes<T> extends HTMLAttributes<T> {\n        form?: string;\n        high?: number;\n        low?: number;\n        max?: number | string;\n        min?: number | string;\n        optimum?: number;\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface QuoteHTMLAttributes<T> extends HTMLAttributes<T> {\n        cite?: string;\n    }\n\n    interface ObjectHTMLAttributes<T> extends HTMLAttributes<T> {\n        classID?: string;\n        data?: string;\n        form?: string;\n        height?: number | string;\n        name?: string;\n        type?: string;\n        useMap?: string;\n        width?: number | string;\n        wmode?: string;\n    }\n\n    interface OlHTMLAttributes<T> extends HTMLAttributes<T> {\n        reversed?: boolean;\n        start?: number;\n        type?: '1' | 'a' | 'A' | 'i' | 'I';\n    }\n\n    interface OptgroupHTMLAttributes<T> extends HTMLAttributes<T> {\n        disabled?: boolean;\n        label?: string;\n    }\n\n    interface OptionHTMLAttributes<T> extends HTMLAttributes<T> {\n        disabled?: boolean;\n        label?: string;\n        selected?: boolean;\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface OutputHTMLAttributes<T> extends HTMLAttributes<T> {\n        form?: string;\n        htmlFor?: string;\n        name?: string;\n    }\n\n    interface ParamHTMLAttributes<T> extends HTMLAttributes<T> {\n        name?: string;\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface ProgressHTMLAttributes<T> extends HTMLAttributes<T> {\n        max?: number | string;\n        value?: string | ReadonlyArray<string> | number;\n    }\n\n    interface SlotHTMLAttributes<T> extends HTMLAttributes<T> {\n        name?: string;\n    }\n\n    interface ScriptHTMLAttributes<T> extends HTMLAttributes<T> {\n        async?: boolean;\n        charSet?: string;\n        crossOrigin?: string;\n        defer?: boolean;\n        integrity?: string;\n        noModule?: boolean;\n        nonce?: string;\n        src?: string;\n        type?: string;\n    }\n\n    interface SelectHTMLAttributes<T> extends HTMLAttributes<T> {\n        autoComplete?: string;\n        autoFocus?: boolean;\n        disabled?: boolean;\n        form?: string;\n        multiple?: boolean;\n        name?: string;\n        required?: boolean;\n        size?: number;\n        value?: string | ReadonlyArray<string> | number;\n        onChange?: ChangeEventHandler<T>;\n    }\n\n    interface SourceHTMLAttributes<T> extends HTMLAttributes<T> {\n        media?: string;\n        sizes?: string;\n        src?: string;\n        srcSet?: string;\n        type?: string;\n    }\n\n    interface StyleHTMLAttributes<T> extends HTMLAttributes<T> {\n        media?: string;\n        nonce?: string;\n        scoped?: boolean;\n        type?: string;\n    }\n\n    interface TableHTMLAttributes<T> extends HTMLAttributes<T> {\n        cellPadding?: number | string;\n        cellSpacing?: number | string;\n        summary?: string;\n        width?: number | string;\n    }\n\n    interface TextareaHTMLAttributes<T> extends HTMLAttributes<T> {\n        autoComplete?: string;\n        autoFocus?: boolean;\n        cols?: number;\n        dirName?: string;\n        disabled?: boolean;\n        form?: string;\n        maxLength?: number;\n        minLength?: number;\n        name?: string;\n        placeholder?: string;\n        readOnly?: boolean;\n        required?: boolean;\n        rows?: number;\n        value?: string | ReadonlyArray<string> | number;\n        wrap?: string;\n\n        onChange?: ChangeEventHandler<T>;\n    }\n\n    interface TdHTMLAttributes<T> extends HTMLAttributes<T> {\n        align?: \"left\" | \"center\" | \"right\" | \"justify\" | \"char\";\n        colSpan?: number;\n        headers?: string;\n        rowSpan?: number;\n        scope?: string;\n        abbr?: string;\n        height?: number | string;\n        width?: number | string;\n        valign?: \"top\" | \"middle\" | \"bottom\" | \"baseline\";\n    }\n\n    interface ThHTMLAttributes<T> extends HTMLAttributes<T> {\n        align?: \"left\" | \"center\" | \"right\" | \"justify\" | \"char\";\n        colSpan?: number;\n        headers?: string;\n        rowSpan?: number;\n        scope?: string;\n        abbr?: string;\n    }\n\n    interface TimeHTMLAttributes<T> extends HTMLAttributes<T> {\n        dateTime?: string;\n    }\n\n    interface TrackHTMLAttributes<T> extends HTMLAttributes<T> {\n        default?: boolean;\n        kind?: string;\n        label?: string;\n        src?: string;\n        srcLang?: string;\n    }\n\n    interface VideoHTMLAttributes<T> extends MediaHTMLAttributes<T> {\n        height?: number | string;\n        playsInline?: boolean;\n        poster?: string;\n        width?: number | string;\n        disablePictureInPicture?: boolean;\n    }\n\n    // this list is \"complete\" in that it contains every SVG attribute\n    // that React supports, but the types can be improved.\n    // Full list here: https://facebook.github.io/react/docs/dom-elements.html\n    //\n    // The three broad type categories are (in order of restrictiveness):\n    //   - \"number | string\"\n    //   - \"string\"\n    //   - union of string literals\n    interface SVGAttributes<T> extends AriaAttributes, DOMAttributes<T> {\n        // Attributes which also defined in HTMLAttributes\n        // See comment in SVGDOMPropertyConfig.js\n        className?: string;\n        color?: string;\n        height?: number | string;\n        id?: string;\n        lang?: string;\n        max?: number | string;\n        media?: string;\n        method?: string;\n        min?: number | string;\n        name?: string;\n        style?: CSSProperties;\n        target?: string;\n        type?: string;\n        width?: number | string;\n\n        // Other HTML properties supported by SVG elements in browsers\n        role?: string;\n        tabIndex?: number;\n        crossOrigin?: \"anonymous\" | \"use-credentials\" | \"\";\n\n        // SVG Specific attributes\n        accentHeight?: number | string;\n        accumulate?: \"none\" | \"sum\";\n        additive?: \"replace\" | \"sum\";\n        alignmentBaseline?: \"auto\" | \"baseline\" | \"before-edge\" | \"text-before-edge\" | \"middle\" | \"central\" | \"after-edge\" |\n        \"text-after-edge\" | \"ideographic\" | \"alphabetic\" | \"hanging\" | \"mathematical\" | \"inherit\";\n        allowReorder?: \"no\" | \"yes\";\n        alphabetic?: number | string;\n        amplitude?: number | string;\n        arabicForm?: \"initial\" | \"medial\" | \"terminal\" | \"isolated\";\n        ascent?: number | string;\n        attributeName?: string;\n        attributeType?: string;\n        autoReverse?: Booleanish;\n        azimuth?: number | string;\n        baseFrequency?: number | string;\n        baselineShift?: number | string;\n        baseProfile?: number | string;\n        bbox?: number | string;\n        begin?: number | string;\n        bias?: number | string;\n        by?: number | string;\n        calcMode?: number | string;\n        capHeight?: number | string;\n        clip?: number | string;\n        clipPath?: string;\n        clipPathUnits?: number | string;\n        clipRule?: number | string;\n        colorInterpolation?: number | string;\n        colorInterpolationFilters?: \"auto\" | \"sRGB\" | \"linearRGB\" | \"inherit\";\n        colorProfile?: number | string;\n        colorRendering?: number | string;\n        contentScriptType?: number | string;\n        contentStyleType?: number | string;\n        cursor?: number | string;\n        cx?: number | string;\n        cy?: number | string;\n        d?: string;\n        decelerate?: number | string;\n        descent?: number | string;\n        diffuseConstant?: number | string;\n        direction?: number | string;\n        display?: number | string;\n        divisor?: number | string;\n        dominantBaseline?: number | string;\n        dur?: number | string;\n        dx?: number | string;\n        dy?: number | string;\n        edgeMode?: number | string;\n        elevation?: number | string;\n        enableBackground?: number | string;\n        end?: number | string;\n        exponent?: number | string;\n        externalResourcesRequired?: Booleanish;\n        fill?: string;\n        fillOpacity?: number | string;\n        fillRule?: \"nonzero\" | \"evenodd\" | \"inherit\";\n        filter?: string;\n        filterRes?: number | string;\n        filterUnits?: number | string;\n        floodColor?: number | string;\n        floodOpacity?: number | string;\n        focusable?: Booleanish | \"auto\";\n        fontFamily?: string;\n        fontSize?: number | string;\n        fontSizeAdjust?: number | string;\n        fontStretch?: number | string;\n        fontStyle?: number | string;\n        fontVariant?: number | string;\n        fontWeight?: number | string;\n        format?: number | string;\n        from?: number | string;\n        fx?: number | string;\n        fy?: number | string;\n        g1?: number | string;\n        g2?: number | string;\n        glyphName?: number | string;\n        glyphOrientationHorizontal?: number | string;\n        glyphOrientationVertical?: number | string;\n        glyphRef?: number | string;\n        gradientTransform?: string;\n        gradientUnits?: string;\n        hanging?: number | string;\n        horizAdvX?: number | string;\n        horizOriginX?: number | string;\n        href?: string;\n        ideographic?: number | string;\n        imageRendering?: number | string;\n        in2?: number | string;\n        in?: string;\n        intercept?: number | string;\n        k1?: number | string;\n        k2?: number | string;\n        k3?: number | string;\n        k4?: number | string;\n        k?: number | string;\n        kernelMatrix?: number | string;\n        kernelUnitLength?: number | string;\n        kerning?: number | string;\n        keyPoints?: number | string;\n        keySplines?: number | string;\n        keyTimes?: number | string;\n        lengthAdjust?: number | string;\n        letterSpacing?: number | string;\n        lightingColor?: number | string;\n        limitingConeAngle?: number | string;\n        local?: number | string;\n        markerEnd?: string;\n        markerHeight?: number | string;\n        markerMid?: string;\n        markerStart?: string;\n        markerUnits?: number | string;\n        markerWidth?: number | string;\n        mask?: string;\n        maskContentUnits?: number | string;\n        maskUnits?: number | string;\n        mathematical?: number | string;\n        mode?: number | string;\n        numOctaves?: number | string;\n        offset?: number | string;\n        opacity?: number | string;\n        operator?: number | string;\n        order?: number | string;\n        orient?: number | string;\n        orientation?: number | string;\n        origin?: number | string;\n        overflow?: number | string;\n        overlinePosition?: number | string;\n        overlineThickness?: number | string;\n        paintOrder?: number | string;\n        panose1?: number | string;\n        path?: string;\n        pathLength?: number | string;\n        patternContentUnits?: string;\n        patternTransform?: number | string;\n        patternUnits?: string;\n        pointerEvents?: number | string;\n        points?: string;\n        pointsAtX?: number | string;\n        pointsAtY?: number | string;\n        pointsAtZ?: number | string;\n        preserveAlpha?: Booleanish;\n        preserveAspectRatio?: string;\n        primitiveUnits?: number | string;\n        r?: number | string;\n        radius?: number | string;\n        refX?: number | string;\n        refY?: number | string;\n        renderingIntent?: number | string;\n        repeatCount?: number | string;\n        repeatDur?: number | string;\n        requiredExtensions?: number | string;\n        requiredFeatures?: number | string;\n        restart?: number | string;\n        result?: string;\n        rotate?: number | string;\n        rx?: number | string;\n        ry?: number | string;\n        scale?: number | string;\n        seed?: number | string;\n        shapeRendering?: number | string;\n        slope?: number | string;\n        spacing?: number | string;\n        specularConstant?: number | string;\n        specularExponent?: number | string;\n        speed?: number | string;\n        spreadMethod?: string;\n        startOffset?: number | string;\n        stdDeviation?: number | string;\n        stemh?: number | string;\n        stemv?: number | string;\n        stitchTiles?: number | string;\n        stopColor?: string;\n        stopOpacity?: number | string;\n        strikethroughPosition?: number | string;\n        strikethroughThickness?: number | string;\n        string?: number | string;\n        stroke?: string;\n        strokeDasharray?: string | number;\n        strokeDashoffset?: string | number;\n        strokeLinecap?: \"butt\" | \"round\" | \"square\" | \"inherit\";\n        strokeLinejoin?: \"miter\" | \"round\" | \"bevel\" | \"inherit\";\n        strokeMiterlimit?: number | string;\n        strokeOpacity?: number | string;\n        strokeWidth?: number | string;\n        surfaceScale?: number | string;\n        systemLanguage?: number | string;\n        tableValues?: number | string;\n        targetX?: number | string;\n        targetY?: number | string;\n        textAnchor?: string;\n        textDecoration?: number | string;\n        textLength?: number | string;\n        textRendering?: number | string;\n        to?: number | string;\n        transform?: string;\n        u1?: number | string;\n        u2?: number | string;\n        underlinePosition?: number | string;\n        underlineThickness?: number | string;\n        unicode?: number | string;\n        unicodeBidi?: number | string;\n        unicodeRange?: number | string;\n        unitsPerEm?: number | string;\n        vAlphabetic?: number | string;\n        values?: string;\n        vectorEffect?: number | string;\n        version?: string;\n        vertAdvY?: number | string;\n        vertOriginX?: number | string;\n        vertOriginY?: number | string;\n        vHanging?: number | string;\n        vIdeographic?: number | string;\n        viewBox?: string;\n        viewTarget?: number | string;\n        visibility?: number | string;\n        vMathematical?: number | string;\n        widths?: number | string;\n        wordSpacing?: number | string;\n        writingMode?: number | string;\n        x1?: number | string;\n        x2?: number | string;\n        x?: number | string;\n        xChannelSelector?: string;\n        xHeight?: number | string;\n        xlinkActuate?: string;\n        xlinkArcrole?: string;\n        xlinkHref?: string;\n        xlinkRole?: string;\n        xlinkShow?: string;\n        xlinkTitle?: string;\n        xlinkType?: string;\n        xmlBase?: string;\n        xmlLang?: string;\n        xmlns?: string;\n        xmlnsXlink?: string;\n        xmlSpace?: string;\n        y1?: number | string;\n        y2?: number | string;\n        y?: number | string;\n        yChannelSelector?: string;\n        z?: number | string;\n        zoomAndPan?: string;\n    }\n\n    interface WebViewHTMLAttributes<T> extends HTMLAttributes<T> {\n        allowFullScreen?: boolean;\n        allowpopups?: boolean;\n        autoFocus?: boolean;\n        autosize?: boolean;\n        blinkfeatures?: string;\n        disableblinkfeatures?: string;\n        disableguestresize?: boolean;\n        disablewebsecurity?: boolean;\n        guestinstance?: string;\n        httpreferrer?: string;\n        nodeintegration?: boolean;\n        partition?: string;\n        plugins?: boolean;\n        preload?: string;\n        src?: string;\n        useragent?: string;\n        webpreferences?: string;\n    }\n\n    //\n    // React.DOM\n    // ----------------------------------------------------------------------\n\n    interface ReactHTML {\n        a: DetailedHTMLFactory<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;\n        abbr: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        address: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        area: DetailedHTMLFactory<AreaHTMLAttributes<HTMLAreaElement>, HTMLAreaElement>;\n        article: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        aside: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        audio: DetailedHTMLFactory<AudioHTMLAttributes<HTMLAudioElement>, HTMLAudioElement>;\n        b: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        base: DetailedHTMLFactory<BaseHTMLAttributes<HTMLBaseElement>, HTMLBaseElement>;\n        bdi: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        bdo: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        big: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        blockquote: DetailedHTMLFactory<BlockquoteHTMLAttributes<HTMLElement>, HTMLElement>;\n        body: DetailedHTMLFactory<HTMLAttributes<HTMLBodyElement>, HTMLBodyElement>;\n        br: DetailedHTMLFactory<HTMLAttributes<HTMLBRElement>, HTMLBRElement>;\n        button: DetailedHTMLFactory<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;\n        canvas: DetailedHTMLFactory<CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement>;\n        caption: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        cite: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        code: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        col: DetailedHTMLFactory<ColHTMLAttributes<HTMLTableColElement>, HTMLTableColElement>;\n        colgroup: DetailedHTMLFactory<ColgroupHTMLAttributes<HTMLTableColElement>, HTMLTableColElement>;\n        data: DetailedHTMLFactory<DataHTMLAttributes<HTMLDataElement>, HTMLDataElement>;\n        datalist: DetailedHTMLFactory<HTMLAttributes<HTMLDataListElement>, HTMLDataListElement>;\n        dd: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        del: DetailedHTMLFactory<DelHTMLAttributes<HTMLElement>, HTMLElement>;\n        details: DetailedHTMLFactory<DetailsHTMLAttributes<HTMLElement>, HTMLElement>;\n        dfn: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        dialog: DetailedHTMLFactory<DialogHTMLAttributes<HTMLDialogElement>, HTMLDialogElement>;\n        div: DetailedHTMLFactory<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;\n        dl: DetailedHTMLFactory<HTMLAttributes<HTMLDListElement>, HTMLDListElement>;\n        dt: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        em: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        embed: DetailedHTMLFactory<EmbedHTMLAttributes<HTMLEmbedElement>, HTMLEmbedElement>;\n        fieldset: DetailedHTMLFactory<FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>;\n        figcaption: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        figure: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        footer: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        form: DetailedHTMLFactory<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>;\n        h1: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        h2: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        h3: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        h4: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        h5: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        h6: DetailedHTMLFactory<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n        head: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLHeadElement>;\n        header: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        hgroup: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        hr: DetailedHTMLFactory<HTMLAttributes<HTMLHRElement>, HTMLHRElement>;\n        html: DetailedHTMLFactory<HtmlHTMLAttributes<HTMLHtmlElement>, HTMLHtmlElement>;\n        i: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        iframe: DetailedHTMLFactory<IframeHTMLAttributes<HTMLIFrameElement>, HTMLIFrameElement>;\n        img: DetailedHTMLFactory<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>;\n        input: DetailedHTMLFactory<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;\n        ins: DetailedHTMLFactory<InsHTMLAttributes<HTMLModElement>, HTMLModElement>;\n        kbd: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        keygen: DetailedHTMLFactory<KeygenHTMLAttributes<HTMLElement>, HTMLElement>;\n        label: DetailedHTMLFactory<LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>;\n        legend: DetailedHTMLFactory<HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>;\n        li: DetailedHTMLFactory<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>;\n        link: DetailedHTMLFactory<LinkHTMLAttributes<HTMLLinkElement>, HTMLLinkElement>;\n        main: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        map: DetailedHTMLFactory<MapHTMLAttributes<HTMLMapElement>, HTMLMapElement>;\n        mark: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        menu: DetailedHTMLFactory<MenuHTMLAttributes<HTMLElement>, HTMLElement>;\n        menuitem: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        meta: DetailedHTMLFactory<MetaHTMLAttributes<HTMLMetaElement>, HTMLMetaElement>;\n        meter: DetailedHTMLFactory<MeterHTMLAttributes<HTMLElement>, HTMLElement>;\n        nav: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        noscript: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        object: DetailedHTMLFactory<ObjectHTMLAttributes<HTMLObjectElement>, HTMLObjectElement>;\n        ol: DetailedHTMLFactory<OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>;\n        optgroup: DetailedHTMLFactory<OptgroupHTMLAttributes<HTMLOptGroupElement>, HTMLOptGroupElement>;\n        option: DetailedHTMLFactory<OptionHTMLAttributes<HTMLOptionElement>, HTMLOptionElement>;\n        output: DetailedHTMLFactory<OutputHTMLAttributes<HTMLElement>, HTMLElement>;\n        p: DetailedHTMLFactory<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>;\n        param: DetailedHTMLFactory<ParamHTMLAttributes<HTMLParamElement>, HTMLParamElement>;\n        picture: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        pre: DetailedHTMLFactory<HTMLAttributes<HTMLPreElement>, HTMLPreElement>;\n        progress: DetailedHTMLFactory<ProgressHTMLAttributes<HTMLProgressElement>, HTMLProgressElement>;\n        q: DetailedHTMLFactory<QuoteHTMLAttributes<HTMLQuoteElement>, HTMLQuoteElement>;\n        rp: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        rt: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        ruby: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        s: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        samp: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        slot: DetailedHTMLFactory<SlotHTMLAttributes<HTMLSlotElement>, HTMLSlotElement>;\n        script: DetailedHTMLFactory<ScriptHTMLAttributes<HTMLScriptElement>, HTMLScriptElement>;\n        section: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        select: DetailedHTMLFactory<SelectHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>;\n        small: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        source: DetailedHTMLFactory<SourceHTMLAttributes<HTMLSourceElement>, HTMLSourceElement>;\n        span: DetailedHTMLFactory<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>;\n        strong: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        style: DetailedHTMLFactory<StyleHTMLAttributes<HTMLStyleElement>, HTMLStyleElement>;\n        sub: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        summary: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        sup: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        table: DetailedHTMLFactory<TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>;\n        template: DetailedHTMLFactory<HTMLAttributes<HTMLTemplateElement>, HTMLTemplateElement>;\n        tbody: DetailedHTMLFactory<HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n        td: DetailedHTMLFactory<TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>;\n        textarea: DetailedHTMLFactory<TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;\n        tfoot: DetailedHTMLFactory<HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n        th: DetailedHTMLFactory<ThHTMLAttributes<HTMLTableHeaderCellElement>, HTMLTableHeaderCellElement>;\n        thead: DetailedHTMLFactory<HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n        time: DetailedHTMLFactory<TimeHTMLAttributes<HTMLElement>, HTMLElement>;\n        title: DetailedHTMLFactory<HTMLAttributes<HTMLTitleElement>, HTMLTitleElement>;\n        tr: DetailedHTMLFactory<HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>;\n        track: DetailedHTMLFactory<TrackHTMLAttributes<HTMLTrackElement>, HTMLTrackElement>;\n        u: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        ul: DetailedHTMLFactory<HTMLAttributes<HTMLUListElement>, HTMLUListElement>;\n        \"var\": DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        video: DetailedHTMLFactory<VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>;\n        wbr: DetailedHTMLFactory<HTMLAttributes<HTMLElement>, HTMLElement>;\n        webview: DetailedHTMLFactory<WebViewHTMLAttributes<HTMLWebViewElement>, HTMLWebViewElement>;\n    }\n\n    interface ReactSVG {\n        animate: SVGFactory;\n        circle: SVGFactory;\n        clipPath: SVGFactory;\n        defs: SVGFactory;\n        desc: SVGFactory;\n        ellipse: SVGFactory;\n        feBlend: SVGFactory;\n        feColorMatrix: SVGFactory;\n        feComponentTransfer: SVGFactory;\n        feComposite: SVGFactory;\n        feConvolveMatrix: SVGFactory;\n        feDiffuseLighting: SVGFactory;\n        feDisplacementMap: SVGFactory;\n        feDistantLight: SVGFactory;\n        feDropShadow: SVGFactory;\n        feFlood: SVGFactory;\n        feFuncA: SVGFactory;\n        feFuncB: SVGFactory;\n        feFuncG: SVGFactory;\n        feFuncR: SVGFactory;\n        feGaussianBlur: SVGFactory;\n        feImage: SVGFactory;\n        feMerge: SVGFactory;\n        feMergeNode: SVGFactory;\n        feMorphology: SVGFactory;\n        feOffset: SVGFactory;\n        fePointLight: SVGFactory;\n        feSpecularLighting: SVGFactory;\n        feSpotLight: SVGFactory;\n        feTile: SVGFactory;\n        feTurbulence: SVGFactory;\n        filter: SVGFactory;\n        foreignObject: SVGFactory;\n        g: SVGFactory;\n        image: SVGFactory;\n        line: SVGFactory;\n        linearGradient: SVGFactory;\n        marker: SVGFactory;\n        mask: SVGFactory;\n        metadata: SVGFactory;\n        path: SVGFactory;\n        pattern: SVGFactory;\n        polygon: SVGFactory;\n        polyline: SVGFactory;\n        radialGradient: SVGFactory;\n        rect: SVGFactory;\n        stop: SVGFactory;\n        svg: SVGFactory;\n        switch: SVGFactory;\n        symbol: SVGFactory;\n        text: SVGFactory;\n        textPath: SVGFactory;\n        tspan: SVGFactory;\n        use: SVGFactory;\n        view: SVGFactory;\n    }\n\n    interface ReactDOM extends ReactHTML, ReactSVG { }\n\n    //\n    // React.PropTypes\n    // ----------------------------------------------------------------------\n\n    type Validator<T> = PropTypes.Validator<T>;\n\n    type Requireable<T> = PropTypes.Requireable<T>;\n\n    type ValidationMap<T> = PropTypes.ValidationMap<T>;\n\n    type WeakValidationMap<T> = {\n        [K in keyof T]?: null extends T[K]\n            ? Validator<T[K] | null | undefined>\n            : undefined extends T[K]\n            ? Validator<T[K] | null | undefined>\n            : Validator<T[K]>\n    };\n\n    interface ReactPropTypes {\n        any: typeof PropTypes.any;\n        array: typeof PropTypes.array;\n        bool: typeof PropTypes.bool;\n        func: typeof PropTypes.func;\n        number: typeof PropTypes.number;\n        object: typeof PropTypes.object;\n        string: typeof PropTypes.string;\n        node: typeof PropTypes.node;\n        element: typeof PropTypes.element;\n        instanceOf: typeof PropTypes.instanceOf;\n        oneOf: typeof PropTypes.oneOf;\n        oneOfType: typeof PropTypes.oneOfType;\n        arrayOf: typeof PropTypes.arrayOf;\n        objectOf: typeof PropTypes.objectOf;\n        shape: typeof PropTypes.shape;\n        exact: typeof PropTypes.exact;\n    }\n\n    //\n    // React.Children\n    // ----------------------------------------------------------------------\n\n    interface ReactChildren {\n        map<T, C>(children: C | C[], fn: (child: C, index: number) => T):\n            C extends null | undefined ? C : Array<Exclude<T, boolean | null | undefined>>;\n        forEach<C>(children: C | C[], fn: (child: C, index: number) => void): void;\n        count(children: any): number;\n        only<C>(children: C): C extends any[] ? never : C;\n        toArray(children: ReactNode | ReactNode[]): Array<Exclude<ReactNode, boolean | null | undefined>>;\n    }\n\n    //\n    // Browser Interfaces\n    // https://github.com/nikeee/2048-typescript/blob/master/2048/js/touch.d.ts\n    // ----------------------------------------------------------------------\n\n    interface AbstractView {\n        styleMedia: StyleMedia;\n        document: Document;\n    }\n\n    interface Touch {\n        identifier: number;\n        target: EventTarget;\n        screenX: number;\n        screenY: number;\n        clientX: number;\n        clientY: number;\n        pageX: number;\n        pageY: number;\n    }\n\n    interface TouchList {\n        [index: number]: Touch;\n        length: number;\n        item(index: number): Touch;\n        identifiedTouch(identifier: number): Touch;\n    }\n\n    //\n    // Error Interfaces\n    // ----------------------------------------------------------------------\n    interface ErrorInfo {\n        /**\n         * Captures which component contained the exception, and its ancestors.\n         */\n        componentStack: string;\n    }\n}\n\n// naked 'any' type in a conditional type will short circuit and union both the then/else branches\n// so boolean is only resolved for T = any\ntype IsExactlyAny<T> = boolean extends (T extends never ? true : false) ? true : false;\n\ntype ExactlyAnyPropertyKeys<T> = { [K in keyof T]: IsExactlyAny<T[K]> extends true ? K : never }[keyof T];\ntype NotExactlyAnyPropertyKeys<T> = Exclude<keyof T, ExactlyAnyPropertyKeys<T>>;\n\n// Try to resolve ill-defined props like for JS users: props can be any, or sometimes objects with properties of type any\ntype MergePropTypes<P, T> =\n    // Distribute over P in case it is a union type\n    P extends any\n        // If props is type any, use propTypes definitions\n        ? IsExactlyAny<P> extends true ? T :\n            // If declared props have indexed properties, ignore inferred props entirely as keyof gets widened\n            string extends keyof P ? P :\n                // Prefer declared types which are not exactly any\n                & Pick<P, NotExactlyAnyPropertyKeys<P>>\n                // For props which are exactly any, use the type inferred from propTypes if present\n                & Pick<T, Exclude<keyof T, NotExactlyAnyPropertyKeys<P>>>\n                // Keep leftover props not specified in propTypes\n                & Pick<P, Exclude<keyof P, keyof T>>\n        : never;\n\n// Any prop that has a default prop becomes optional, but its type is unchanged\n// Undeclared default props are augmented into the resulting allowable attributes\n// If declared props have indexed properties, ignore default props entirely as keyof gets widened\n// Wrap in an outer-level conditional type to allow distribution over props that are unions\ntype Defaultize<P, D> = P extends any\n    ? string extends keyof P ? P :\n        & Pick<P, Exclude<keyof P, keyof D>>\n        & Partial<Pick<P, Extract<keyof P, keyof D>>>\n        & Partial<Pick<D, Exclude<keyof D, keyof P>>>\n    : never;\n\ntype ReactManagedAttributes<C, P> = C extends { propTypes: infer T; defaultProps: infer D; }\n    ? Defaultize<MergePropTypes<P, PropTypes.InferProps<T>>, D>\n    : C extends { propTypes: infer T; }\n        ? MergePropTypes<P, PropTypes.InferProps<T>>\n        : C extends { defaultProps: infer D; }\n            ? Defaultize<P, D>\n            : P;\n\ndeclare global {\n    namespace JSX {\n        // tslint:disable-next-line:no-empty-interface\n        interface Element extends React.ReactElement<any, any> { }\n        interface ElementClass extends React.Component<any> {\n            render(): React.ReactNode;\n        }\n        interface ElementAttributesProperty { props: {}; }\n        interface ElementChildrenAttribute { children: {}; }\n\n        type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>\n            ? T extends React.MemoExoticComponent<infer U> | React.LazyExoticComponent<infer U>\n                ? ReactManagedAttributes<U, P>\n                : ReactManagedAttributes<T, P>\n            : ReactManagedAttributes<C, P>;\n\n        // tslint:disable-next-line:no-empty-interface\n        interface IntrinsicAttributes extends React.Attributes { }\n        // tslint:disable-next-line:no-empty-interface\n        interface IntrinsicClassAttributes<T> extends React.ClassAttributes<T> { }\n\n        interface IntrinsicElements {\n            // HTML\n            a: React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;\n            abbr: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            address: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            area: React.DetailedHTMLProps<React.AreaHTMLAttributes<HTMLAreaElement>, HTMLAreaElement>;\n            article: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            aside: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            audio: React.DetailedHTMLProps<React.AudioHTMLAttributes<HTMLAudioElement>, HTMLAudioElement>;\n            b: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            base: React.DetailedHTMLProps<React.BaseHTMLAttributes<HTMLBaseElement>, HTMLBaseElement>;\n            bdi: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            bdo: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            big: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            blockquote: React.DetailedHTMLProps<React.BlockquoteHTMLAttributes<HTMLElement>, HTMLElement>;\n            body: React.DetailedHTMLProps<React.HTMLAttributes<HTMLBodyElement>, HTMLBodyElement>;\n            br: React.DetailedHTMLProps<React.HTMLAttributes<HTMLBRElement>, HTMLBRElement>;\n            button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;\n            canvas: React.DetailedHTMLProps<React.CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement>;\n            caption: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            cite: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            code: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            col: React.DetailedHTMLProps<React.ColHTMLAttributes<HTMLTableColElement>, HTMLTableColElement>;\n            colgroup: React.DetailedHTMLProps<React.ColgroupHTMLAttributes<HTMLTableColElement>, HTMLTableColElement>;\n            data: React.DetailedHTMLProps<React.DataHTMLAttributes<HTMLDataElement>, HTMLDataElement>;\n            datalist: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDataListElement>, HTMLDataListElement>;\n            dd: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            del: React.DetailedHTMLProps<React.DelHTMLAttributes<HTMLElement>, HTMLElement>;\n            details: React.DetailedHTMLProps<React.DetailsHTMLAttributes<HTMLElement>, HTMLElement>;\n            dfn: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            dialog: React.DetailedHTMLProps<React.DialogHTMLAttributes<HTMLDialogElement>, HTMLDialogElement>;\n            div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;\n            dl: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDListElement>, HTMLDListElement>;\n            dt: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            em: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            embed: React.DetailedHTMLProps<React.EmbedHTMLAttributes<HTMLEmbedElement>, HTMLEmbedElement>;\n            fieldset: React.DetailedHTMLProps<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>;\n            figcaption: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            figure: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            footer: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            form: React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>;\n            h1: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            h2: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            h3: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            h4: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            h5: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            h6: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>;\n            head: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadElement>, HTMLHeadElement>;\n            header: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            hgroup: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            hr: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHRElement>, HTMLHRElement>;\n            html: React.DetailedHTMLProps<React.HtmlHTMLAttributes<HTMLHtmlElement>, HTMLHtmlElement>;\n            i: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            iframe: React.DetailedHTMLProps<React.IframeHTMLAttributes<HTMLIFrameElement>, HTMLIFrameElement>;\n            img: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>;\n            input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;\n            ins: React.DetailedHTMLProps<React.InsHTMLAttributes<HTMLModElement>, HTMLModElement>;\n            kbd: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            keygen: React.DetailedHTMLProps<React.KeygenHTMLAttributes<HTMLElement>, HTMLElement>;\n            label: React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>;\n            legend: React.DetailedHTMLProps<React.HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>;\n            li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>;\n            link: React.DetailedHTMLProps<React.LinkHTMLAttributes<HTMLLinkElement>, HTMLLinkElement>;\n            main: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            map: React.DetailedHTMLProps<React.MapHTMLAttributes<HTMLMapElement>, HTMLMapElement>;\n            mark: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            menu: React.DetailedHTMLProps<React.MenuHTMLAttributes<HTMLElement>, HTMLElement>;\n            menuitem: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            meta: React.DetailedHTMLProps<React.MetaHTMLAttributes<HTMLMetaElement>, HTMLMetaElement>;\n            meter: React.DetailedHTMLProps<React.MeterHTMLAttributes<HTMLElement>, HTMLElement>;\n            nav: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            noindex: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            noscript: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            object: React.DetailedHTMLProps<React.ObjectHTMLAttributes<HTMLObjectElement>, HTMLObjectElement>;\n            ol: React.DetailedHTMLProps<React.OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>;\n            optgroup: React.DetailedHTMLProps<React.OptgroupHTMLAttributes<HTMLOptGroupElement>, HTMLOptGroupElement>;\n            option: React.DetailedHTMLProps<React.OptionHTMLAttributes<HTMLOptionElement>, HTMLOptionElement>;\n            output: React.DetailedHTMLProps<React.OutputHTMLAttributes<HTMLElement>, HTMLElement>;\n            p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>;\n            param: React.DetailedHTMLProps<React.ParamHTMLAttributes<HTMLParamElement>, HTMLParamElement>;\n            picture: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            pre: React.DetailedHTMLProps<React.HTMLAttributes<HTMLPreElement>, HTMLPreElement>;\n            progress: React.DetailedHTMLProps<React.ProgressHTMLAttributes<HTMLProgressElement>, HTMLProgressElement>;\n            q: React.DetailedHTMLProps<React.QuoteHTMLAttributes<HTMLQuoteElement>, HTMLQuoteElement>;\n            rp: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            rt: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            ruby: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            s: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            samp: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            slot: React.DetailedHTMLProps<React.SlotHTMLAttributes<HTMLSlotElement>, HTMLSlotElement>;\n            script: React.DetailedHTMLProps<React.ScriptHTMLAttributes<HTMLScriptElement>, HTMLScriptElement>;\n            section: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            select: React.DetailedHTMLProps<React.SelectHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>;\n            small: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            source: React.DetailedHTMLProps<React.SourceHTMLAttributes<HTMLSourceElement>, HTMLSourceElement>;\n            span: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>;\n            strong: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            style: React.DetailedHTMLProps<React.StyleHTMLAttributes<HTMLStyleElement>, HTMLStyleElement>;\n            sub: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            summary: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            sup: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            table: React.DetailedHTMLProps<React.TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>;\n            template: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTemplateElement>, HTMLTemplateElement>;\n            tbody: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n            td: React.DetailedHTMLProps<React.TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>;\n            textarea: React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;\n            tfoot: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n            th: React.DetailedHTMLProps<React.ThHTMLAttributes<HTMLTableHeaderCellElement>, HTMLTableHeaderCellElement>;\n            thead: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>;\n            time: React.DetailedHTMLProps<React.TimeHTMLAttributes<HTMLElement>, HTMLElement>;\n            title: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTitleElement>, HTMLTitleElement>;\n            tr: React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>;\n            track: React.DetailedHTMLProps<React.TrackHTMLAttributes<HTMLTrackElement>, HTMLTrackElement>;\n            u: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>;\n            \"var\": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            video: React.DetailedHTMLProps<React.VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>;\n            wbr: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;\n            webview: React.DetailedHTMLProps<React.WebViewHTMLAttributes<HTMLWebViewElement>, HTMLWebViewElement>;\n\n            // SVG\n            svg: React.SVGProps<SVGSVGElement>;\n\n            animate: React.SVGProps<SVGElement>; // TODO: It is SVGAnimateElement but is not in TypeScript's lib.dom.d.ts for now.\n            animateMotion: React.SVGProps<SVGElement>;\n            animateTransform: React.SVGProps<SVGElement>; // TODO: It is SVGAnimateTransformElement but is not in TypeScript's lib.dom.d.ts for now.\n            circle: React.SVGProps<SVGCircleElement>;\n            clipPath: React.SVGProps<SVGClipPathElement>;\n            defs: React.SVGProps<SVGDefsElement>;\n            desc: React.SVGProps<SVGDescElement>;\n            ellipse: React.SVGProps<SVGEllipseElement>;\n            feBlend: React.SVGProps<SVGFEBlendElement>;\n            feColorMatrix: React.SVGProps<SVGFEColorMatrixElement>;\n            feComponentTransfer: React.SVGProps<SVGFEComponentTransferElement>;\n            feComposite: React.SVGProps<SVGFECompositeElement>;\n            feConvolveMatrix: React.SVGProps<SVGFEConvolveMatrixElement>;\n            feDiffuseLighting: React.SVGProps<SVGFEDiffuseLightingElement>;\n            feDisplacementMap: React.SVGProps<SVGFEDisplacementMapElement>;\n            feDistantLight: React.SVGProps<SVGFEDistantLightElement>;\n            feDropShadow: React.SVGProps<SVGFEDropShadowElement>;\n            feFlood: React.SVGProps<SVGFEFloodElement>;\n            feFuncA: React.SVGProps<SVGFEFuncAElement>;\n            feFuncB: React.SVGProps<SVGFEFuncBElement>;\n            feFuncG: React.SVGProps<SVGFEFuncGElement>;\n            feFuncR: React.SVGProps<SVGFEFuncRElement>;\n            feGaussianBlur: React.SVGProps<SVGFEGaussianBlurElement>;\n            feImage: React.SVGProps<SVGFEImageElement>;\n            feMerge: React.SVGProps<SVGFEMergeElement>;\n            feMergeNode: React.SVGProps<SVGFEMergeNodeElement>;\n            feMorphology: React.SVGProps<SVGFEMorphologyElement>;\n            feOffset: React.SVGProps<SVGFEOffsetElement>;\n            fePointLight: React.SVGProps<SVGFEPointLightElement>;\n            feSpecularLighting: React.SVGProps<SVGFESpecularLightingElement>;\n            feSpotLight: React.SVGProps<SVGFESpotLightElement>;\n            feTile: React.SVGProps<SVGFETileElement>;\n            feTurbulence: React.SVGProps<SVGFETurbulenceElement>;\n            filter: React.SVGProps<SVGFilterElement>;\n            foreignObject: React.SVGProps<SVGForeignObjectElement>;\n            g: React.SVGProps<SVGGElement>;\n            image: React.SVGProps<SVGImageElement>;\n            line: React.SVGProps<SVGLineElement>;\n            linearGradient: React.SVGProps<SVGLinearGradientElement>;\n            marker: React.SVGProps<SVGMarkerElement>;\n            mask: React.SVGProps<SVGMaskElement>;\n            metadata: React.SVGProps<SVGMetadataElement>;\n            mpath: React.SVGProps<SVGElement>;\n            path: React.SVGProps<SVGPathElement>;\n            pattern: React.SVGProps<SVGPatternElement>;\n            polygon: React.SVGProps<SVGPolygonElement>;\n            polyline: React.SVGProps<SVGPolylineElement>;\n            radialGradient: React.SVGProps<SVGRadialGradientElement>;\n            rect: React.SVGProps<SVGRectElement>;\n            stop: React.SVGProps<SVGStopElement>;\n            switch: React.SVGProps<SVGSwitchElement>;\n            symbol: React.SVGProps<SVGSymbolElement>;\n            text: React.SVGProps<SVGTextElement>;\n            textPath: React.SVGProps<SVGTextPathElement>;\n            tspan: React.SVGProps<SVGTSpanElement>;\n            use: React.SVGProps<SVGUseElement>;\n            view: React.SVGProps<SVGViewElement>;\n        }\n    }\n}`;\n"
  },
  {
    "path": "packages/client/src/components/ConfirmAlert/index.js",
    "content": "import React from 'react';\nimport Modal from 'react-modal';\nimport { Icons } from '@dhiwise/icons';\nimport { Button } from '../Button';\nimport { Description } from '../Description';\nimport { Heading } from '../Heading';\n\nconst PopupCss = {\n  closebutton: 'absolute right-6 top-6 focus:outline-none',\n  closebuttonimg: 'w-5',\n  popupwrap: 'w-full bg-gray-black border-1 border-gray-100 rounded-lg',\n  overlay: 'fixed top-0 bottom-0 w-full h-full z-10',\n  popupbody: 'py-10 px-5 text-center',\n};\nconst customStyles = {\n  content: {\n    top: '50%',\n    left: '50%',\n    right: 'auto',\n    bottom: 'auto',\n    marign: 'auto',\n    transform: 'translate(-50%, -50%)',\n    border: 'none',\n    background: 'transparent',\n    overflow: 'visible',\n  },\n};\nexport const ConfirmationAlert = ({\n  handleSubmit,\n  children,\n  shortDesc,\n  closeModal,\n  isOpen,\n  title = 'Are you sure?',\n  description = '',\n  okText = 'Delete',\n  variant = 'danger',\n  handleClose,\n  descVarint,\n  isLoading = false,\n  overlayClass,\n  size,\n  titleVariant,\n}) => (\n  <Modal\n    isOpen={isOpen}\n    // onAfterOpen={handleSubmit}\n    onRequestClose={handleClose}\n    style={customStyles}\n    contentLabel=\"Example Modal\"\n    className={`w-11/12 md:w-100 absolute m-auto bg-white focus:outline-none ${size}`}\n    overlayClassName={`${PopupCss.overlay} ${overlayClass}`}\n    appElement={document.getElementById('root')}\n  >\n    <div className={PopupCss.popupwrap}>\n      {closeModal && (\n        <button onClick={closeModal} className={PopupCss.closebutton}>\n          <div className={PopupCss.closebuttonimg}>\n            <Icons.Close />\n          </div>\n        </button>\n      )}\n      <div className={PopupCss.popupbody}>\n        <Heading variant={titleVariant || 'h3'}>{title}</Heading>\n        {!!description && <Description variant={descVarint} className=\"mt-3 w-10/12 m-auto\">{description}</Description>}\n        {children}\n        {!!(okText || handleClose || handleSubmit)\n          && (\n          <div className=\"mt-8\">\n            {!!handleClose && <Button onClick={handleClose} variant=\"outline\" shape=\"rounded\">Cancel</Button>}\n            {!!handleSubmit && <Button autoFocus onClick={handleSubmit} variant={variant} shape=\"rounded\" className=\"ml-2\" style={{ minWidth: '5rem' }} loading={isLoading}>{okText}</Button>}\n          </div>\n          )}\n        {shortDesc && <Description className=\"mt-3 w-10/12 m-auto\">{shortDesc}</Description>}\n      </div>\n    </div>\n  </Modal>\n);\n"
  },
  {
    "path": "packages/client/src/components/ContainerBox/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport const ContainerBox = ({\n  className,\n  children,\n}) => (\n  <div className={`contatinerBox sm:w-full mx-auto p-5 ${className}`}>\n    {children}\n  </div>\n);\n\nContainerBox.propTypes = {\n  /**\n     * Additional classname\n     */\n  className: PropTypes.string,\n};\n\nContainerBox.defaultProps = {\n  className: '',\n};\n"
  },
  {
    "path": "packages/client/src/components/Count/index.js",
    "content": "import React from 'react';\n\nexport const Count = ({ total, className }) => (\n  <div className={`bg-gray-100 flex items-center justify-center px-1.5 py-1 ml-2 text-xxs rounded-full ${className}`}>\n    {total}\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/DatePicker/datepicker.css",
    "content": ".datepickerBox.react-datepicker{\n  background-color: var(--color-bg-white);\n  border: 1px solid var(--color-gray-90);\n  box-shadow: rgb(0 0 0 / 6%) 0px 8px 16px 0px;\n  display: flex;\n  font-family: var(--font-famliy);\n}\n.datepickerBox .react-datepicker__header{\n  background-color: var(--color-bg-white);\n  border-bottom: 1px solid var(--color-gray-90);\n}\n.react-datepicker__navigation--previous{\n  border-right-color: var(--color-bg-black) !important;\n}\n.react-datepicker__navigation--next{\n  border-left-color: var(--color-bg-black) !important;\n}\n.datepickerBox .react-datepicker__current-month, \n.datepickerBox .react-datepicker-time__header, \n.datepickerBox .react-datepicker-year-header,\n.datepickerBox .react-datepicker__day-name, \n.datepickerBox .react-datepicker__day, \n.datepickerBox .react-datepicker__time-name,\n.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item{\n  color: var(--color-text-primary);\n  font-size: 0.75rem;\n}\n.datepickerBox .react-datepicker__current-month,\n.datepickerBox .react-datepicker-time__header{\n  font-size: 1rem;\n}\n.datepickerBox .react-datepicker__day-name, .react-datepicker__day, .react-datepicker__time-name{\n  width: 1.75rem !important;\n  line-height: 1.75rem !important;\n  margin: 3px !important;\n}\n.react-datepicker__month {\n  margin: 4px !important;\n}\n.react-datepicker-popper[data-placement^=\"bottom\"] .datepickerBox .react-datepicker__triangle, \n.react-datepicker-popper[data-placement^=\"bottom\"] .datepickerBox .react-datepicker__triangle::before{\n  border-bottom-color:var(--color-bg-white);\n}\n.react-datepicker-popper[data-placement^=\"top-start\"] .datepickerBox .react-datepicker__triangle::before{\n  border-top-color:var(--color-gray-90);\n}\n.react-datepicker-popper[data-placement^=\"bottom\"] .datepickerBox .react-datepicker__triangle,\n.react-datepicker-popper[data-placement^=\"top-start\"] .datepickerBox .react-datepicker__triangle{\n  left: 0 !important;\n  right: 0 !important;\n  margin-left: auto;\n  margin-right: auto;\n}\n.react-datepicker-popper[data-placement^=\"top-start\"] .datepickerBox .react-datepicker__triangle{\n  border-top-color: var(--color-gray-200);\n}\n.react-datepicker-popper[data-placement^=\"bottom\"] .datepickerBox .react-datepicker__triangle::before{\n  border-bottom-color: var(--color-gray-90);\n}\n.react-datepicker-popper{\n  z-index: 100 !important; \n}\n.datepickerBox button:focus{\n outline: none;\n}\n.datepickerBox .react-datepicker__day--selected, \n.datepickerBox .react-datepicker__day--selected:hover, \n.datepickerBox .react-datepicker__day--in-selecting-range:hover, \n.datepickerBox .react-datepicker__day--in-range:hover, \n.datepickerBox .react-datepicker__month-text--selected:hover, \n.datepickerBox .react-datepicker__month-text--in-selecting-range:hover, \n.datepickerBox .react-datepicker__month-text--in-range:hover, \n.datepickerBox .react-datepicker__quarter-text--selected:hover, \n.datepickerBox .react-datepicker__quarter-text--in-selecting-range:hover, \n.datepickerBox .react-datepicker__quarter-text--in-range:hover, \n.datepickerBox .react-datepicker__year-text--selected:hover, \n.datepickerBox .react-datepicker__year-text--in-selecting-range:hover, \n.datepickerBox .react-datepicker__year-text--in-range:hover,\n.datepickerBox .react-datepicker__day:hover, \n.datepickerBox .react-datepicker__month-text:hover, \n.datepickerBox .react-datepicker__quarter-text:hover, \n.datepickerBox .react-datepicker__year-text:hover,\n.datepickerBox .react-datepicker__day--keyboard-selected, \n.datepickerBox .react-datepicker__month-text--keyboard-selected, \n.datepickerBox .react-datepicker__quarter-text--keyboard-selected, \n.datepickerBox .react-datepicker__year-text--keyboard-selected{\n  background-color: var(--color-bg-primary);\n  color: #fff;\n}\n.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box{\n  padding-right: 1px;\n}\n\n/* timepicker */\n.react-datepicker__time-container{\n  border-left: 1px solid var(--color-gray-90) !important;\n}\n.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list{\n  background: var(--color-bg-white);\n  color: var(--color-text-primary);\n}\n.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover,\n.react-datepicker__time-list-item--selected{ \n   background-color: var(--color-bg-primary) !important;\n   color: #fff;\n}\n.react-datepicker__input-container input{\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n  padding-right: 28px;\n}\n.react-datepicker-wrapper .react-datepicker__close-icon::after{\n  background-color: transparent !important;\n  height: 18px;\n  width: 18px;\n  font-size: 20px;\n}\n.react-datepicker__close-icon{\n  background-color: var(--color-gray-input) !important;\n  z-index: 1;\n  right: 4px !important;\n  padding: 3px 4px !important;\n}\n\n.react-datepicker__day--disabled,\n.react-datepicker__time-list-item--disabled{\n  cursor: not-allowed !important;\n  opacity: 0.6 !important;\n  color: var(--color-text-primary) !important; \n}\n\n.react-datepicker__day--disabled:hover,\n.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item.react-datepicker__time-list-item--disabled:hover{\n  background-color: transparent !important;\n}\n\n.react-datepicker__day--keyboard-selected {\n  background-color: transparent !important;  \n}\n.react-datepicker__day--keyboard-selected:hover {\n  background-color:  var(--color-bg-primary) !important\n}"
  },
  {
    "path": "packages/client/src/components/DatePicker/datepickerCss.js",
    "content": "export const datepickerCss = {\n  datepickerWrap: '',\n  datepickerLabel: 'mb-1.5 text-primary-text text-sm block w-full font-semibold leading-5',\n  desc: 'mt-1',\n  errorClass: 'text-error text-sm mt-1 block',\n  datepickerWrapClass: 'relative',\n  datePickerInput: 'font-body text-primary-text bg-gray-input border-1 border-gray-70 placeholder-primary font-normal w-full focus:border-primary-dark focus:outline-none leading-normal rounded-3',\n  datepickernormal: 'py-2 px-2.5 text-sm',\n  datepickersmall: 'py-1 px-2 text-xs',\n  datepickermedium: 'py-1.5 px-2 text-xs',\n};\n"
  },
  {
    "path": "packages/client/src/components/DatePicker/index.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport DatePicker from 'react-datepicker';\nimport PropTypes from 'prop-types';\nimport { datepickerCss } from './datepickerCss';\nimport { Description } from '../Description';\nimport 'react-datepicker/dist/react-datepicker.css';\nimport './datepicker.css';\n\nexport const Datepicker = ({\n  label, desc, placeholder, labelClassName, error, size = 'normal', onChange, WrapClassName, dateTimeFormat = 'MM-dd-yyyy hh:mm:ss a', ...otherProps\n}) => {\n  // eslint-disable-next-line no-unused-vars\n  // const [startDate, setStartDate] = useState(otherProps.value ? new Date(otherProps.value) : new Date());\n  const datepickerRef = React.useRef(null);\n\n  function handleClickDatepickerIcon() {\n    // OPENS UP THE DATEPICKER WHEN THE CALENDAR ICON IS CLICKED FOR THE INPUT FIELD\n    const datepickerElement = datepickerRef?.current;\n    datepickerElement?.setFocus();\n  }\n\n  const sizeCss = `${datepickerCss[[`datepicker${size}`]]}`;\n  return (\n    <div className={`${datepickerCss.datepickerWrap} ${WrapClassName}`}>\n      {!!label && (\n      <div className={labelClassName}>\n        {\n          !!label && <label className={`${datepickerCss.datepickerLabel}`}>{label}</label>\n        }\n      </div>\n      )}\n      <div className={datepickerCss.datepickerWrapClass}>\n        <DatePicker\n          ref={datepickerRef} // attach the ref\n          placeholderText={placeholder || 'Select date'}\n          wrapperClassName=\"w-full\"\n          calendarClassName=\"datepickerBox\"\n          className={`${datepickerCss.datePickerInput} ${sizeCss}`}\n          selected={otherProps.value ? new Date(otherProps.value) : null}\n          dateFormat={otherProps.showTimeSelect ? dateTimeFormat : 'MM-dd-yyyy'}\n          onChange={(date) => {\n            // setStartDate(date);\n            onChange?.(date);\n          }}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...otherProps}\n        />\n        <div\n          className=\"max-w-min h-4 absolute right-3 cursor-pointer flex top-0 bottom-0 m-auto opacity-50\"\n          onClick={() => handleClickDatepickerIcon()}\n        >\n          <span className=\"w-4 block\"><Icons.Calender /></span>\n        </div>\n      </div>\n      {!!desc\n        && <Description className={datepickerCss.desc}>{desc}</Description>}\n      {!!error && <span className={datepickerCss.errorClass}>{error}</span>}\n    </div>\n  );\n};\n\nDatepicker.propTypes = {\n  size: PropTypes.oneOf(['normal', 'small', 'medium']),\n};\n"
  },
  {
    "path": "packages/client/src/components/Description/descriptionCss.js",
    "content": "export const DescriptionCss = {\n  // decWrap: 'text-body-text text-sm leading-snug',\n  descnormal: 'text-body-text text-xs leading-5 xxl:leading-5 xxl:text-sm',\n  desclight: 'text-primary-text text-sm md:text-base leading-5 sm:leading-6 font-normal',\n  descsubTitle: 'text-primary-text text-sm md:text-lg leading-5 md:leading-6 font-normal',\n};\n"
  },
  {
    "path": "packages/client/src/components/Description/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { DescriptionCss } from './descriptionCss';\n\nexport const Description = ({\n  children, className, variant, style,\n}) => {\n  const variantClass = `${DescriptionCss[[`desc${variant}`]]}`;\n  return (\n    <p className={`word-break ${DescriptionCss.decWrap} ${variantClass} ${className}`} style={style}>{children}</p>\n  );\n};\nDescription.propTypes = {\n  className: PropTypes.string,\n  variant: PropTypes.oneOf(['normal', 'subTitle', 'light']),\n};\n\nDescription.defaultProps = {\n  className: '',\n  variant: 'normal',\n};\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/Css.js",
    "content": "const Css = {\n  pointer: {\n    cursor: 'pointer',\n  },\n  menuList: {\n    margin: '2px',\n  },\n  disabledItem: {\n    pointerEvents: 'none',\n    cursor: 'default',\n    color: 'grey',\n  },\n  gear: {\n    fontSize: '1.7em',\n    cursor: 'pointer',\n    color: 'black',\n    padding: '14px',\n    border: 'none',\n  },\n  triangle: {\n    fontSize: '0.9em',\n    cursor: 'pointer',\n    color: '#000000',\n    padding: '14px',\n    border: 'none',\n  },\n  imageTrigger: {\n    height: '50px',\n    width: '50px',\n    cursor: 'pointer',\n    padding: '3px',\n    border: 'none',\n  },\n  textTrigger: {\n    cursor: 'pointer',\n    padding: '14px',\n    border: 'none',\n    fontWeight: 'bold',\n  },\n  menu: {\n    position: 'relative',\n    // display: 'inline-block',\n  },\n  menuItem: {\n    float: 'left',\n  },\n  menuContent: {\n    display: 'none',\n    position: 'absolute',\n    left: '0px',\n    zIndex: '9999',\n    backgroundColor: '#f9f9f9',\n    minWidth: '300px',\n    // minwidth: '300px',\n    padding: '12px',\n    overflow: 'auto',\n    boxShadow: '0px 8px 16px 0px rgba(0,0,0,0.2)',\n  },\n  show: {\n    display: 'block',\n  },\n};\n\nexport default Css;\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/DropdownMenu.js",
    "content": "import * as React from 'react';\nimport useOnClickOutside from 'use-onclickoutside';\n// import { useOutsideClick } from '../../hooks';\nimport { useBoolean } from '../hooks';\nimport DefaultCss from './Css';\n\nconst DropdownMenu = React.forwardRef((props, ref) => {\n  const [open, , setFalse, setToggle] = useBoolean(false);\n\n  const clickRef = React.useRef();\n\n  useOnClickOutside(clickRef, setFalse);\n\n  React.useEffect(() => { if (open) setToggle(); }, [props.closeOnSelect]);\n\n  React.useImperativeHandle(ref, () => ({ hideDropDown: setFalse }));\n\n  const getCss = React.useCallback(() => {\n    const propsCss = { ...props.css };\n    const css = { ...DefaultCss };\n\n    if (propsCss) {\n      Object.keys(propsCss).forEach((key) => {\n        css[key] = { ...DefaultCss[key], ...propsCss[key] };\n      });\n    }\n\n    return css;\n  }, [props.css]);\n\n  const menuStyles = React.useMemo(() => {\n    const css = getCss();\n    const menuStyle = JSON.parse(JSON.stringify(css.menuContent)); // Clone the current style\n    const position = props.position === undefined ? 'right' : props.position;\n    const supportedPositions = ['left', 'center', 'right'];\n\n    if (supportedPositions.indexOf(position.toLowerCase()) === -1) {\n      throw new Error(\"The value for 'position' prop is not supported for DropdownMenu. Try 'left', 'center' or 'right'.\");\n    }\n\n    if (position) {\n      let baseWidth = parseInt(\n        DefaultCss.menuContent.minWidth.replace('px', ''), 10,\n      );\n      let offset = 0;\n      baseWidth -= 40;\n\n      // We need to use negative numbers as we are offsetting menu to the left\n      if (position === 'center') {\n        offset = (baseWidth / 2) * -1;\n      }\n      if (position === 'left') {\n        offset = baseWidth * -1;\n      }\n\n      menuStyle.left = `${offset.toString()}px`;\n      menuStyle.display = open ? 'block' : 'none';\n    }\n\n    return menuStyle;\n  }, [open, props.position]);\n\n  return (\n    <div ref={clickRef} style={DefaultCss.menu} className={`${props.dropdownMenu} inline-block`}>\n      {React.cloneElement(props.placeholder(), { onClick: setToggle })}\n      <div className={`position-div ${props.position} ${props.wrapClass}`} style={{ ...menuStyles, ...props.style }}>\n        {open && props.children}\n      </div>\n    </div>\n  );\n});\nDropdownMenu.displayName = 'DropdownMenu';\nexport default DropdownMenu;\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/Dropdown_bkp.js",
    "content": "import React from 'react';\nimport DefaultCss from './Css';\n// import { MenuBox } from '../MenuList';\n\nlet instances = 0;\n\nclass DropdownMenu extends React.Component {\n  constructor(props) {\n    super(props);\n    this.toggleMenu = this.toggleMenu.bind(this);\n    instances += 1;\n\n    this.MENUITEMS_DIV = `__react_bs_dd_menuItems_${instances}`;\n    this.CARAT_CLASS = `__react_bs_dd_carat_${instances}`;\n    this.TRIGGER_CLASS = `__react_bs_dd_trigger_${instances}`;\n  }\n\n  // eslint-disable-next-line camelcase\n  UNSAFE_componentWillMount(nextProps) {\n    const { TRIGGER_CLASS } = this;\n    const { MENUITEMS_DIV } = this;\n    const { CARAT_CLASS } = this;\n\n    // eslint-disable-next-line func-names\n    window.addEventListener('click', function (e) {\n      if (nextProps !== this.props) {\n        const klass = e.target.className;\n        const carat = document.getElementById(CARAT_CLASS);\n        const menuItemDiv = document.getElementById(MENUITEMS_DIV);\n        if (menuItemDiv && menuItemDiv.dataset.reactbsdditems === MENUITEMS_DIV) {\n          if (\n            klass !== `${MENUITEMS_DIV} show`\n            && klass !== TRIGGER_CLASS\n            && !klass.lastIndexOf('glyphicon', 0) === 0\n          ) {\n            menuItemDiv.classList.remove('show');\n            if (carat) {\n              carat.className = 'glyphicon glyphicon-triangle-bottom';\n            }\n          }\n        }\n      }\n    });\n  }\n\n  getTrigger() {\n    const css = this.getCss();\n    const iconCss = { ...DefaultCss.gear };\n\n    if (this.props.iconColor) {\n      iconCss.color = this.props.iconColor;\n    }\n    // Override iconColor if it is present in css prop\n    if (this.props.css && this.props.css.gear && this.props.css.gear.color) {\n      iconCss.color = this.props.css.gear.color;\n    }\n\n    if (this.props.triggerType && this.props.trigger) {\n      const triggerStyle = css.imageTrigger;\n      const caratStyle = css.triangle;\n      switch (this.props.triggerType.toLowerCase()) {\n        case 'image':\n\n          if (this.props.triggerWidth) {\n            triggerStyle.width = this.props.triggerWidth;\n          }\n          if (this.props.triggerHeight) {\n            triggerStyle.height = this.props.triggerHeight;\n          }\n          if (this.props.caratColor) {\n            caratStyle.color = this.props.caratColor;\n          }\n\n          return (\n            <div onClick={this.toggleMenu}>\n              <img\n                src={this.props.trigger}\n                style={triggerStyle}\n                className={this.TRIGGER_CLASS}\n                alt=\"trigger\"\n              />\n              <span\n                id={this.CARAT_CLASS}\n                className=\"glyphicon glyphicon-triangle-bottom\"\n                style={caratStyle}\n              />\n            </div>\n          );\n        case 'text':\n          return (\n            <div\n              className={this.TRIGGER_CLASS}\n              onClick={this.toggleMenu}\n              style={css.textTrigger}\n            >\n              {this.props.trigger}\n&nbsp;&nbsp;\n              <span\n                id={this.CARAT_CLASS}\n                className=\"glyphicon glyphicon-triangle-bottom\"\n                style={caratStyle}\n              />\n            </div>\n          );\n        case 'icon':\n          return (\n            <span\n              className={this.props.trigger}\n              style={iconCss}\n              onClick={this.toggleMenu}\n            />\n          );\n        case 'component':\n          return (\n            <div\n              className={this.props.className}\n              onClick={this.toggleMenu}\n            >\n              <this.props.displayComponent />\n            </div>\n          );\n        default:\n          throw new Error(\"The value for DropdownMenu 'triggerType' is not supported for DropdownMenu. Try 'image', 'text' or 'icon'.\");\n      }\n    } else {\n      return (\n        <span className=\"glyphicon glyphicon-cog\" onClick={this.toggleMenu}>\n          {this.props.Name}\n        </span>\n      );\n    }\n  }\n\n  getMenuStyle() {\n    const css = this.getCss();\n    const menuStyle = JSON.parse(JSON.stringify(css.menuContent)); // Clone the current style\n    const position = this.props.position === undefined ? 'right' : this.props.position;\n    const supportedPositions = ['left', 'center', 'right'];\n\n    if (supportedPositions.indexOf(position.toLowerCase()) === -1) {\n      throw new Error(\"The value for 'position' prop is not supported for DropdownMenu. Try 'left', 'center' or 'right'.\");\n    }\n\n    if (position) {\n      let baseWidth = parseInt(\n        DefaultCss.menuContent.minWidth.replace('px', ''), 10,\n      );\n      let offset = 0;\n      baseWidth -= 40;\n\n      // We need to use negative numbers as we are offsetting menu to the left\n      if (position === 'center') {\n        offset = (baseWidth / 2) * -1;\n      }\n      if (position === 'left') {\n        offset = baseWidth * -1;\n      }\n\n      menuStyle.left = `${offset.toString()}px`;\n    }\n\n    return menuStyle;\n  }\n\n  getChildren() {\n    return React.Children.map(\n      this.props.children,\n      (child) => React.cloneElement(child, { css: this.props.css }, null),\n    );\n  }\n\n  getCss() {\n    const propsCss = { ...this.props.css };\n    const css = { ...DefaultCss };\n\n    if (propsCss) {\n      Object.keys(propsCss).forEach((key) => {\n        css[key] = { ...DefaultCss[key], ...propsCss[key] };\n      });\n    }\n\n    return css;\n  }\n\n  dropdownTitle() {\n    return (\n      <div className=\"mb-2 mt-2\">\n        <h2 className=\"text-xs text-gray-500 uppercase\">{this.props.title}</h2>\n      </div>\n    );\n  }\n\n  fadeIn(element) {\n    this.element.style.opacity = 0;\n\n    const tick = function ticker() {\n      this.element.style.opacity = +element.style.opacity + 0.04;\n\n      if (+element.style.opacity < 1) {\n        if (requestAnimationFrame) {\n          requestAnimationFrame(tick);\n        } else {\n          setTimeout(tick, 16);\n        }\n      }\n    };\n\n    tick();\n  }\n\n  toggleArrow() {\n    const carat = document.getElementById(this.CARAT_CLASS);\n\n    if (carat) {\n      if (carat.className === 'glyphicon glyphicon-triangle-top') {\n        carat.className = 'glyphicon glyphicon-triangle-bottom';\n      } else {\n        carat.className = 'glyphicon glyphicon-triangle-top';\n      }\n    }\n  }\n\n  toggleMenu(e) {\n    e.stopPropagation();\n    const items = document.getElementById(this.MENUITEMS_DIV);\n    if (items) {\n      items.classList.toggle('show');\n      if (this.props.fadeIn && this.props.fadeIn === 'true') {\n        this.fadeIn(document.getElementById(this.MENUITEMS_DIV));\n      }\n    }\n  }\n\n  render() {\n    if (this.props.children.length === 0) {\n      throw new Error('DropdownMenu must have at least one MenuItem child.');\n    }\n\n    return (\n      <div\n        style={DefaultCss.menu}\n        className={this.props.dropdownMenu}\n        onFocus={this.props.onMouseover}\n        onBlur={this.props.onMouseout}\n      >\n        {this.getTrigger()}\n        <div\n          data-reactbsdditems={this.MENUITEMS_DIV}\n          id={this.MENUITEMS_DIV}\n          className={`${this.MENUITEMS_DIV} position-div ${this.props.position} ${this.props.wrapClass}`}\n          style={this.getMenuStyle()}\n        >\n          {this.props.dropdownTitle && <>{this.dropdownTitle()}</>}\n          {this.props.isChildren\n            ? <>{this.props.children}</>\n            : <>{this.getChildren()}</>}\n        </div>\n      </div>\n    );\n  }\n}\n\nexport default DropdownMenu;\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/MenuItem.js",
    "content": "import * as React from 'react';\nimport PropTypes from 'prop-types';\nimport DefaultCss from './Css';\nimport { DropdownCss } from './dropdown';\n\nconst MenuItem = (props) => {\n  const [linkStyle, setLinkStyle] = React.useState(DefaultCss.pointer);\n\n  React.useEffect(() => {\n    // Need to check disabled also, otherwise\n    // this might override the disabled useState hook\n    if (props.linkStyle && !props.disabled) {\n      setLinkStyle(props.linkStyle);\n    }\n  }, [props.linkStyle]);\n\n  React.useEffect(() => {\n    if (props.disabled) {\n      setLinkStyle(DefaultCss.disabledItem);\n    }\n  }, [props.disabled]);\n\n  const getSeparatorCss = () => {\n    const resultCss = { ...DefaultCss };\n    if (props.css) {\n      resultCss.separator = { ...DefaultCss.separator, ...props.css.separator };\n    }\n    return resultCss;\n  };\n\n  if (props.type) {\n    if (props.type.toLowerCase() === 'separator') {\n      const css = getSeparatorCss();\n      return (<hr style={css.separator} />);\n    }\n    throw new Error(\"The value for prop 'type' is not supported for MenuItem. The only supported type is 'separator'.\");\n  } else if (props.location) {\n    return (\n      <div className={`${props.className} ${DropdownCss.dropdownitemWrap}`}>\n        <a\n          href={props.location}\n          target={props.target}\n          onClick={props.onClick}\n          style={linkStyle}\n          className={DropdownCss.dropdownitem}\n        >\n          {props.text}\n        </a>\n      </div>\n    );\n  } else {\n    const selectedClass = props.selected ? 'bg-primary-dark text-defaultWhite' : '';\n    return (\n      <div className={` ${selectedClass} ${props.className} ${DropdownCss.dropdownitemWrap}`}>\n        <div\n          onClick={props.onClick}\n          style={linkStyle}\n          className={`${DropdownCss.dropdownitem}`}\n        >\n          {props.text}\n        </div>\n        {!!props.icon && <div onClick={props.iconClick} className=\"w-4 h-4 ml-2 cursor-pointer\">{props.icon}</div>}\n      </div>\n    );\n  }\n};\n\nMenuItem.propTypes = {\n  // Renders a disabled MenuItem\n  disabled: PropTypes.bool,\n  // Specifies type of MenuItem\n  type: PropTypes.string,\n  // Inner Text of MenuItem\n  text: PropTypes.string,\n  // Navigation Location\n  location: PropTypes.string,\n  onClick: PropTypes.func,\n\n};\n\nexport default MenuItem;\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/dropdown.js",
    "content": "export const DropdownCss = {\n  dropdownitemWrap: 'relative flex items-center justify-between pr-2 hover:bg-primary-dark hover:text-defaultWhite text-primary-text whitespace-nowrap',\n  // dropdown-menu\n  dropdownitem: 'px-2 py-1 block w-full text-sm',\n};\n"
  },
  {
    "path": "packages/client/src/components/DropdownMenu/index.js",
    "content": "import DropdownMenu from './DropdownMenu';\nimport MenuItem from './MenuItem';\n\nexport {\n  DropdownMenu,\n  MenuItem,\n};\n"
  },
  {
    "path": "packages/client/src/components/Error/index.js",
    "content": "import React from 'react';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport Drawer from 'rc-drawer';\nimport { Icons } from '@dhiwise/icons';\nimport { TabCSs } from '../../assets/css/tab';\nimport { Count } from '../Count';\nimport { DrawerClose } from '../ReactDrawer/DrawerClose';\nimport { MODEL_ERROR_TABS } from '../../constant/model';\n\nconst NoError = React.memo(() => (\n  <div className=\"flex items-center p-2 h-48 justify-center\">\n    <div className=\"flex-grow-0 flex items-center\">\n      <div className=\"justify-end lex text-xl text-gray-400 font-normal\">\n        No Errors found.\n      </div>\n    </div>\n  </div>\n));\nNoError.displayName = 'NoError';\n\nexport const ErrorList = React.memo(({\n  isError, isWarring, error, attribute,\n}) => {\n  if (!error) {\n    return (\n      <NoError />\n    );\n  }\n  return (\n    <div className=\"flex items-center p-2 border-b-1 border-gray-100\">\n      <div className=\"flex-grow-0 flex items-center\">\n        <div className=\"w-3 h-3 mr-2\">\n          {isError\n            && (\n              <>\n                <Icons.Alert color=\"#E24C4B\" />\n                {' '}\n              </>\n            )}\n          {isWarring\n            && <><Icons.Warring color=\"#ffbe00\" /></>}\n        </div>\n        <div className=\"text-primary-text\">{error.name}</div>\n        <hr className=\"w-px h-4 bg-gray-100 mx-2\" />\n        {!!attribute && (\n          <>\n            <div className=\"text-primary-text text-xs\">{attribute}</div>\n            <hr className=\"w-px h-4 bg-gray-100 mx-2\" />\n          </>\n        )}\n        <div className=\"justify-endlex text-xs text-gray-400 font-normal\">\n          {error.message}\n        </div>\n      </div>\n      <div className=\"flex-grow flex justify-end\">\n        {/* <div className=\"w-4 h-4 cursor-pointer\">\n          <Icons.Redirect />\n        </div> */}\n      </div>\n    </div>\n  );\n});\nErrorList.displayName = 'ErrorList';\nexport const Error = React.memo(({\n  isOpen,\n  handleCancel,\n  error,\n  modelErrors = [],\n  modelErrCount = 0,\n  isModelTab = false,\n  handletabChange,\n}) => (\n  <div>\n    <Drawer\n      open={isOpen}\n      handleSubmit={handleCancel}\n      onClose={handleCancel}\n      handleCancel={handleCancel}\n      // ease\n      level={null}\n      showMask={false}\n      handler={false}\n      placement=\"bottom\"\n      wrapperClassName=\"\"\n    >\n      {/* <ReactDrawer\n      type=\"horizontal\"\n      open={isOpen}\n      position=\"bottom\"\n      onClose={handleCancel}\n      onDrawerClose={handleCancel}\n      noOverlay\n    > */}\n      <DrawerClose onClick={handleCancel} />\n      <Tabs selectedTabClassName={TabCSs.selectTab}>\n        <TabList className={`${TabCSs.tabHead} flex justify-between items-center`}>\n          <div className=\"flex items-center\">\n            <Tab className={`${TabCSs.tabTitle} flex items-center`} onClick={() => handletabChange && handletabChange(MODEL_ERROR_TABS.JSON_ERROR)}>\n              JSON error\n              <Count total={error ? 1 : 0} />\n            </Tab>\n            {\n              isModelTab\n              && (\n                <Tab className={`${TabCSs.tabTitle} flex items-center`} onClick={() => handletabChange && handletabChange(MODEL_ERROR_TABS.MODEL_ERROR)}>\n                  Model error\n                  <Count total={modelErrCount} />\n                </Tab>\n              )\n            }\n          </div>\n        </TabList>\n        <TabPanel>\n          <div className=\"px-2 overflow-auto h-48\">\n            <ErrorList error={error} isError />\n          </div>\n        </TabPanel>\n        {\n          isModelTab\n          && (\n            <TabPanel>\n              <div className=\"px-2 overflow-auto h-48\">\n                {\n                  modelErrCount === 0\n                    ? <NoError />\n                    : modelErrors.map((x) => x.error.map((e) => (\n                      <ErrorList\n                        key={e.modelName}\n                        error={{\n                          name: x.modelName,\n                          message: e,\n                        }}\n                        isError\n                        attribute={x.attribute}\n                      />\n                    )))\n                }\n                {/* <ErrorList error={error} isError name=\"User auth\" attribute=\"Password\" />\n            <ErrorList error={error} isError name=\"User auth\" attribute=\"Password\" /> */}\n              </div>\n            </TabPanel>\n          )\n        }\n      </Tabs>\n    </Drawer>\n    {/* </ReactDrawer> */}\n  </div>\n));\nError.displayName = 'Error';\n"
  },
  {
    "path": "packages/client/src/components/ErrorMsg/errorCss.js",
    "content": "export const errorCss = {\n  errorClass: 'text-error text-sm mt-1 block',\n};\n"
  },
  {
    "path": "packages/client/src/components/ErrorMsg/index.js",
    "content": "import React from 'react';\nimport { errorCss } from './errorCss';\n\nconst ErrorMsg = ({ error, className = '' }) => (\n  <>\n    <span className={`${errorCss.errorClass} ${className}`}>{error}</span>\n  </>\n);\nexport default ErrorMsg;\n"
  },
  {
    "path": "packages/client/src/components/Heading/headingCss.js",
    "content": "export const HeadingCss = {\n  pageTitle: 'block text-primary-text font-title',\n  titleh1: 'xl:text-5xl md:text-4xl sm:text-2xl leading-tight font-semibold',\n  titleh2: 'md:text-3xl sm:text-xl font-semibold',\n  titleh2Light: 'md:text-3xl sm:text-xl font-normal',\n  titleh3: 'text-2xl leading-10 font-medium',\n  titleh3Light: 'text-2xl leading-10 font-normal',\n  titleh4: 'text-xl font-semibold leading-8',\n  titleh4Light: 'text-xl font-normal leading-8',\n  titleh5: 'text-base font-semibold',\n  titleh5Light: 'text-base font-normal',\n  titleh6: 'text-sm font-semibold',\n  titleh6Light: 'text-sm font-normal',\n  titlesmall: 'text-base font-semibold',\n  titlenormal: 'text-3xl leading-10 font-semibold',\n};\n"
  },
  {
    "path": "packages/client/src/components/Heading/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { HeadingCss } from './headingCss';\n\nexport const Heading = ({ className, children, variant }) => {\n  const variantClass = `${HeadingCss[[`title${variant}`]]}`;\n  return <h2 className={`${HeadingCss.pageTitle} ${variantClass} ${className}`}>{children}</h2>;\n};\nHeading.propTypes = {\n  className: PropTypes.string,\n  variant: PropTypes.oneOf(['small', 'normal', 'h3', 'h4', 'h1', 'h2', 'h5', 'h6', 'h2Light', 'h3Light', 'h4Light', 'h5ight', 'h6Light']),\n};\n\nHeading.defaultProps = {\n  className: '',\n  variant: 'normal',\n};\n"
  },
  {
    "path": "packages/client/src/components/IconBox/DeleteIcon.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport ReactTooltip from 'react-tooltip';\nimport { iconBoxCss } from './iconBoxCss';\n\nexport const DeleteIcon = ({\n  icon, tooltip, disabled, size, className, onClick,\n}) => {\n  const sizeCss = `${iconBoxCss[[`Icon${size}`]]}`;\n  const disableClass = disabled ? `${iconBoxCss.boxdisabled}` : '';\n  return (\n    <div\n      onClick={disabled ? null : onClick}\n      className={`${sizeCss} ${className} cursor-pointer`}\n      data-tip\n      data-for={tooltip}\n    >\n      <span className={`${disableClass} block`}>{ icon }</span>\n      {!!tooltip && <ReactTooltip place=\"bottom\" id={tooltip} type=\"dark\">{tooltip}</ReactTooltip>}\n    </div>\n  );\n};\nDeleteIcon.propTypes = {\n  /**\n     * Additional Icon\n     */\n  icon: PropTypes.string,\n  /**\n     * Additional icon true false\n     */\n  size: PropTypes.oneOf(['small', 'normal']),\n  /**\n     * is Button disabled\n     */\n  disabled: PropTypes.bool,\n  /**\n     * Additional classname\n     */\n  className: PropTypes.string,\n};\n\nDeleteIcon.defaultProps = {\n  icon: null,\n  size: 'normal',\n  // iconSize: 'normal',\n  className: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/IconBox/iconBoxCss.js",
    "content": "export const iconBoxCss = {\n  boxprimary: 'bg-primary-dark hover:bg-primary-hoverdark primaryShadow',\n  boxsucess: 'bg-activebg successShadow',\n  boxsucess_outine: 'border border-gray-activebg',\n  boxdanger: 'bg-deactivebg dangerShadow',\n  boxdanger_outine: 'border border-gray-deactivebg dangerShadow',\n  boxoutline: 'border-1 border-gray-70 hover:bg-gray-200 outlineShadow',\n  boxdashed: 'border-1 text-base border-dashed border-primary-buttonOutline ',\n  boxsecondary: 'border-gray-300 border-1 bg-gray-200 hover:bg-gray-100 secondaryShadow',\n  boxrounded: 'rounded-3',\n  boxroundedFull: 'rounded-full',\n  boxicon: 'cursor-pointer flex items-center justify-center focus:outline-none',\n  boxnormal: 'h-9 w-9',\n  boxmedium: 'w-8 h-8',\n  boxsmallmedium: 'w-7 h-7',\n  boxextraSmall: 'h-4 w-4',\n  boxsmall: 'h-6 w-6',\n\n  boxImgiconMedium: 'w-3 h-3',\n  boxImgiconExtraSmall: 'xl:w-2 xl:h-2 xxl:w-2 h-2',\n  boxImgicon: 'w-4 h-4 flex items-center',\n  boxImgiconSmall: 'w-3 h-3 flex items-center',\n  boxghost: 'h-auto',\n\n  Iconsmall: 'w-4 h-auto',\n  Iconnormal: 'w-5 h-5',\n  boxdisabled: 'cursor-not-allowed opacity-20',\n};\n"
  },
  {
    "path": "packages/client/src/components/IconBox/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport ReactTooltip from 'react-tooltip';\nimport { iconBoxCss } from './iconBoxCss';\n\nexport const IconBox = ({\n  icon, tooltip, variant, disabled, size, shape, className, onClick, iconClass, tooltipPlace,\n}) => {\n  const variantClass = `${iconBoxCss[[`box${variant}`]]}`;\n  const sizeCss = `${iconBoxCss[[`box${size}`]]}`;\n  const shapeClass = `${iconBoxCss[[`box${shape}`]]}`;\n  const disableClass = disabled ? `${iconBoxCss.boxdisabled}` : '';\n  return (\n    <button\n      onClick={!disabled ? onClick : undefined}\n      className={`${iconBoxCss.boxicon} ${variantClass} ${sizeCss} ${shapeClass} ${disableClass} ${className}\n      ${variant === 'outline' && 'iconGroup'}`}\n      data-tip\n      data-for={tooltip}\n    >\n      {!!icon && (\n        <div className={`${iconClass} ${size === 'small' ? iconBoxCss.boxImgiconSmall : iconBoxCss.boxImgicon}\n      ${size === 'medium' && iconBoxCss.boxImgiconMedium} ${size === 'extraSmall' && iconBoxCss.boxImgiconExtraSmall}`}\n        >\n          {icon}\n        </div>\n      )}\n      {!!tooltip && <ReactTooltip place={tooltipPlace || 'bottom'} id={tooltip} type=\"dark\"><div className=\"max-w-48 text-center whitespace-normal\">{tooltip}</div></ReactTooltip>}\n    </button>\n  );\n};\nIconBox.propTypes = {\n  variant: PropTypes.oneOf([\n    'primary',\n    'outline',\n    'ghost',\n    'dashed',\n    'secondary',\n    'sucess',\n    'sucess_outine',\n    'danger',\n    'danger_outinemedium',\n  ]),\n  /**\n     * Shape of button\n     */\n  shape: PropTypes.oneOf(['square', 'rounded', 'roundedFull']),\n  /**\n     * Additional Icon\n     */\n  icon: PropTypes.node,\n  /**\n     * Additional icon true false\n     */\n  size: PropTypes.oneOf(['extraSmall', 'small', 'smallmedium', 'medium', 'normal']),\n  /**\n     * is Button disabled\n     */\n  disabled: PropTypes.bool,\n  /**\n     * Additional classname\n     */\n  className: PropTypes.string,\n};\n\nIconBox.defaultProps = {\n  variant: 'primary',\n  // icon: null,\n  size: 'normal',\n  // iconSize: 'normal',\n  className: '',\n  disabled: false,\n  shape: 'rounded',\n};\n"
  },
  {
    "path": "packages/client/src/components/InlineHeader/index.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../constant/common';\nimport { DB_TYPE, pluralizeTableName } from '../../constant/model';\nimport { nodeKeyRegex } from '../../utils/regex';\nimport { Heading, Tag } from '../index';\n// import { PopOver } from '../PopOver';\nimport { variantConstant } from '../Tag';\n\nexport const InlineHeader = ({\n  defaultValue,\n  currentId,\n  isDisable = false,\n  isActiveButton = false,\n  onBlurEvent = () => {},\n  edit = false,\n  setShowEdit = () => {},\n  setHideEdit = () => {},\n  titlePlaceHolder = 'Name',\n  titleLength = MAX_INPUT_FIELD_LIMIT.title,\n  isDisableNameEdit = false,\n  titleRegex = nodeKeyRegex,\n  showTableName = false,\n  dbType = '',\n  currentApplicationCode = '',\n}) => {\n  const [internalState, setInternalState] = React.useState();\n  // const descRef = React.useRef(null);\n\n  React.useEffect(() => {\n    setInternalState(defaultValue);\n  }, [defaultValue]);\n\n  React.useEffect(() => {\n    setHideEdit();\n  }, [currentId]);\n\n  const blurEvent = (key, value, modelId) => {\n    if (!value || (defaultValue[key] === value)) {\n      setInternalState((prevData) => ({ ...prevData, [key]: defaultValue[key] }));\n      return;\n    }\n    if (key === 'description') setHideEdit();\n    onBlurEvent(key, value, modelId);\n  };\n\n  return (\n    <div className=\"w-8/12 xxl:w-6/12\">\n      {!edit && (\n        <>\n          <div className=\"\">\n            <Heading variant=\"h4\" className=\"flex items-center word-break\">\n              <span className=\"truncate block flex-grow-0\">{internalState?.name || internalState?.fileName}</span>\n              {(!isDisable && !isDisableNameEdit) && (\n              <span\n                className=\"w-4 h-4 cursor-pointer ml-2 flex-shrink-0 block\"\n                onClick={setShowEdit}\n              >\n                <Icons.Edit />\n              </span>\n              )}\n              {isActiveButton && (\n              <Tag\n                className=\"ml-2 whitespace-nowrap flex-shrink-0\"\n                variant={\n                    internalState?.isActive\n                      ? variantConstant.active\n                      : variantConstant.deactive\n                  }\n                title={internalState?.isActive ? 'Active' : 'Deactive'}\n                onClick={() => !isDisable && onBlurEvent('isActive', !internalState?.isActive)}\n              />\n              )}\n            </Heading>\n          </div>\n          {/* <Description className=\"mt-1 inline-block\">\n            {\n              (!internalState?.description || internalState.description?.length <= 60)\n                ? (internalState?.description || 'Description') : (\n                  <>\n                    {internalState?.description?.slice(0, 60)}\n                    <PopOver\n                      className=\"inline-block text-primary-dark hover:underline cursor-pointer ml-1\"\n                      data=\"Read more\"\n                      place=\"below\"\n                      popOverValue={\n                        <Description className=\"max-w-xl\">{internalState?.description}</Description>\n                    }\n                    />\n                  </>\n                )\n            }\n          </Description> */}\n        </>\n      )}\n      {edit && (\n      <>\n        <input\n          placeholder={titlePlaceHolder}\n          className=\"focus:outline-none leading-8 text-xl text-primary-text bg-transparent font-semibold font-title w-full\"\n          value={defaultValue?.name ? internalState?.name : internalState?.fileName}\n          defaultValue={defaultValue?.name ? internalState?.name : internalState?.fileName}\n          onChange={(e) => {\n            if ((!e.target.value || titleRegex.test(e.target.value)) && e.target.value?.length <= titleLength) {\n              setInternalState((prevData) => ({ ...prevData, [defaultValue?.name ? 'name' : 'fileName']: e.target.value }));\n            }\n          }}\n          onBlur={(e) => {\n            blurEvent(defaultValue?.name ? 'name' : 'fileName', e.currentTarget.value, defaultValue?._id);\n            setHideEdit();\n          }}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              // descRef.current?.focus();\n              blurEvent(defaultValue?.name ? 'name' : 'fileName', e.currentTarget.value, defaultValue?._id);\n              setHideEdit();\n            }\n          }}\n        />\n        {/* <input\n          placeholder=\"More description..\"\n          className=\"focus:outline-none text-primary-text  bg-transparent text-sm w-full mt-1\"\n          defaultValue={internalState?.description}\n          value={internalState?.description}\n          ref={descRef}\n          onChange={(e) => {\n            if (!e.target.value || e.target.value?.length <= MAX_INPUT_FIELD_LIMIT.description) {\n              setInternalState((prevData) => ({ ...prevData, description: e.target.value }));\n            }\n          }}\n          onKeyDown={(e) => {\n            if (e.key === 'Enter') {\n              blurEvent('description', e.currentTarget.value, defaultValue?._id);\n              setHideEdit();\n            }\n          }}\n          onBlur={(e) => {\n            blurEvent('description', e.currentTarget.value, defaultValue?._id);\n            setHideEdit();\n          }}\n        /> */}\n      </>\n      )}\n      {showTableName && ( // display table/collection name field in Model\n      <div className=\"mt-1 flex\">\n        <span className=\"text-body-text text-sm\">{`${(dbType === DB_TYPE.MONGODB) ? 'Collection' : 'Table'} name:`}</span>\n        <div className=\"text-primary-text text-sm ml-1\">{internalState && pluralizeTableName(internalState?.name, currentApplicationCode)}</div>\n      </div>\n      )}\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/DecimalInput.js",
    "content": "import React, { forwardRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { regex } from '../utils';\nimport { InputCss } from './inputCss';\nimport { Description } from '../Description';\n\nconst getFormattedValue = (value = '', regexToValidate) => (value.replace(regexToValidate, ''));\n\n/**\n * Primary UI component for Input\n */\n\nexport const MAX_VALUE = {\n  DOUBLE: 1.79769313486231570e+308,\n  FLOAT: 3.40282346638528860e+38,\n};\n\nexport const DecimalInput = forwardRef(({\n  wrapperClass = '',\n  label = '',\n  placeholder = '',\n  disabled = false,\n  error = '',\n  onChange = () => { },\n  value = '',\n  WrapClassName,\n  inputClassName = '',\n  fixLength,\n  size = 'normal',\n  desc,\n  dark,\n  maxValue,\n  allowPosNeg = false, // allow positive negative both value\n  ...restProps\n}, ref) => {\n  const regexToValidate = allowPosNeg ? regex.posNegDecimalFloatDouble : regex.decimalFloatDouble;\n  // const [internalValue, setInternalValue] = React.useState(getFormattedValue(value));\n  const [internalValue, setInternalValue] = React.useState();\n\n  const wrapperClasses = ['spark-input'];\n  const inputClasses = [InputCss.inputBlock];\n  const disableClass = disabled ? `${InputCss.inputdisabled}` : '';\n\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n  if (inputClassName) {\n    inputClasses.push(inputClassName);\n  }\n\n  useEffect(() => {\n    function setNumValue() {\n      if (regexToValidate.test(`${value}`)) setInternalValue(value);\n      else setInternalValue(getFormattedValue(value, regexToValidate));\n    }\n    if (maxValue) {\n      if ((value <= MAX_VALUE[maxValue])) setNumValue();\n    } else if (fixLength) {\n      if ((value?.length <= fixLength)) setNumValue();\n    } else setNumValue();\n  }, [value, fixLength, maxValue]);\n\n  const handleChange = (e) => {\n    const newValue = e.target.value;\n    if (!newValue || regexToValidate.test(`${newValue}`)) {\n      if (maxValue) {\n        if ((value <= MAX_VALUE[maxValue])) {\n          setInternalValue(newValue);\n          onChange && onChange(newValue);\n        }\n      } else if (fixLength) {\n        if (newValue.length <= fixLength) {\n          setInternalValue(newValue);\n          onChange && onChange(newValue);\n        }\n      } else {\n        setInternalValue(newValue);\n        onChange && onChange(newValue);\n      }\n    }\n  };\n  const sizeCss = `${InputCss[[`input${size}`]]}`;\n\n  return (\n    <div className={[wrapperClasses, WrapClassName].join(' ')}>\n      {\n        !!label && <label className={InputCss.inputLabel}>{label}</label>\n      }\n      {!!desc\n        && <Description className={InputCss.desc}>{desc}</Description>}\n      <div className={InputCss.inputWrapperClass}>\n        <input\n          className={`${InputCss.inputBlock} ${sizeCss} ${dark && InputCss.darkInput} ${disableClass} inputBlock`}\n          onChange={handleChange}\n          type=\"number\"\n          ref={ref}\n          disabled={disabled}\n          placeholder={placeholder}\n          value={internalValue}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...restProps}\n        />\n        {!!error && <span className={InputCss.errorClass}>{error}</span>}\n      </div>\n    </div>\n  );\n});\nDecimalInput.displayName = 'DecimalInput';\nDecimalInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  size: PropTypes.oneOf(['normal', 'small']),\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nDecimalInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/NegativeInput.js",
    "content": "import React, { forwardRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { regex } from '../utils';\nimport { InputCss } from './inputCss';\n\nconst getFormattedValue = (value) => value.replace(regex.negative, '');\n\n/**\n * Primary UI component for Input\n */\nexport const NegativeInput = forwardRef(({\n  wrapperClass = '',\n  inputWrapperClass = 'spark-input-wrapper',\n  label = '',\n  placeholder = '',\n  type = 'text',\n  disabled = false,\n  errorClass = 'spark-input-error-text',\n  error = '',\n  onChange = () => { },\n  value = '',\n  ...restProps\n}, ref) => {\n  const [internalValue, setInternalValue] = React.useState(getFormattedValue(value));\n\n  const wrapperClasses = ['spark-input'];\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n\n  useEffect(() => {\n    setInternalValue(value);\n  }, [value]);\n\n  useEffect(() => {\n    onChange && onChange(internalValue);\n  }, [internalValue]);\n\n  const handleChange = (e) => {\n    const newValue = e.target.value;\n    if (!newValue || regex.negative.test(`${newValue}`)) {\n      setInternalValue(newValue);\n    }\n  };\n\n  return (\n    <div className={wrapperClasses.join(' ')}>\n      {\n        !!label && <label className={InputCss.inputLabel}>{label}</label>\n      }\n      <div className={inputWrapperClass}>\n        <input\n          onChange={handleChange}\n          type={type}\n          ref={ref}\n          disabled={disabled}\n          placeholder={placeholder}\n          value={internalValue}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...restProps}\n        />\n        {!!error && <span className={errorClass}>{error}</span>}\n      </div>\n    </div>\n  );\n});\nNegativeInput.displayName = 'NegativeInput';\nNegativeInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nNegativeInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/NumberInput.js",
    "content": "import React, { forwardRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { regex } from '../utils';\nimport { InputCss } from './inputCss';\nimport { Description } from '../Description';\n\nconst getFormattedValue = (value = '', customRegex, regexToValidate) => (customRegex ? value.replace(customRegex, '') : value.replace(regexToValidate, ''));\n\n/**\n * Primary UI component for Input\n */\nexport const NumberInput = forwardRef(({\n  wrapperClass = '',\n  label = '',\n  placeholder = '',\n  type = 'text',\n  disabled = false,\n  error = '',\n  onChange = () => { },\n  value = '',\n  WrapClassName,\n  inputClassName = '',\n  className,\n  fixLength,\n  desc,\n  size = 'normal',\n  dark,\n  customRegex,\n  extetion,\n  allowInteger = false,\n  ...restProps\n}, ref) => {\n  const regexToValidate = allowInteger ? regex.integer : regex.positive;\n  // const [internalValue, setInternalValue] = React.useState(getFormattedValue(value, customRegex));\n  const [internalValue, setInternalValue] = React.useState();\n\n  const wrapperClasses = ['spark-input'];\n  const inputClasses = [InputCss.inputBlock];\n  const disableClass = disabled ? `${InputCss.inputdisabled}` : '';\n\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n  if (inputClassName) {\n    inputClasses.push(inputClassName);\n  }\n\n  useEffect(() => {\n    function setNumValue() {\n      if (regexToValidate.test(`${value}`)) setInternalValue(value);\n      else setInternalValue(getFormattedValue(value, customRegex, regexToValidate));\n    }\n    if (fixLength) {\n      if ((value?.length <= fixLength)) setNumValue();\n    } else setNumValue();\n  }, [value, fixLength, customRegex]);\n\n  // useEffect(() => {\n  //   onChange && onChange(internalValue);\n  // }, [internalValue]);\n\n  const handleChange = (e) => {\n    const newValue = e.target.value;\n    if (!newValue || (regexToValidate.test(`${newValue}`))) {\n      if (fixLength) {\n        if (newValue.length <= fixLength) {\n          setInternalValue(newValue);\n          onChange && onChange(newValue);\n        }\n      } else {\n        setInternalValue(newValue);\n        onChange && onChange(newValue);\n      }\n    }\n  };\n  const sizeCss = `${InputCss[[`input${size}`]]}`;\n\n  return (\n    <div className={[wrapperClasses, WrapClassName].join(' ')}>\n      {!!(label || desc) && (\n      <div className=\"\">\n        {\n        !!label && <label className={InputCss.inputLabel}>{label}</label>\n      }\n      </div>\n      )}\n      <div className={`${className} ${InputCss.inputWrapperClass}`}>\n        <div className=\"relative\">\n          <input\n            className={`${InputCss.inputBlock} ${inputClassName} ${sizeCss} ${dark && InputCss.darkInput} ${disableClass} inputBlock`}\n            onChange={handleChange}\n            type={type}\n            ref={ref}\n            disabled={disabled}\n            placeholder={placeholder}\n            value={internalValue}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n            {...restProps}\n          />\n          {!!extetion && <div className={InputCss.extenstionText}>{extetion}</div>}\n        </div>\n      </div>\n      {!!desc\n        && <Description className={InputCss.desc}>{desc}</Description>}\n      {!!error && <span className={InputCss.errorClass}>{error}</span>}\n    </div>\n  );\n});\nNumberInput.displayName = 'NumberInput';\nNumberInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  size: PropTypes.oneOf(['normal', 'small', 'medium']),\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nNumberInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/PercentageInput.js",
    "content": "import React, { forwardRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { regex } from '../utils';\nimport { InputCss } from './inputCss';\nimport { Description } from '../Description';\n\nconst getFormattedValue = (value) => value.replace(regex.percentage, '');\n\n/**\n * Primary UI component for Input\n */\nexport const PercentageInput = forwardRef(({\n  wrapperClass = '',\n  inputWrapperClass = 'spark-input-wrapper',\n  label = '',\n  placeholder = '',\n  type = 'text',\n  disabled = false,\n  errorClass = 'spark-input-error-text',\n  error = '',\n  desc,\n  onChange = () => { },\n  value = '',\n  ...restProps\n}, ref) => {\n  const [internalValue, setInternalValue] = React.useState(() => getFormattedValue(value));\n\n  const wrapperClasses = ['spark-input'];\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n\n  useEffect(() => {\n    setInternalValue(value);\n  }, [value]);\n\n  useEffect(() => {\n    onChange && onChange(internalValue);\n  }, [internalValue]);\n\n  const handleChange = (e) => {\n    let currentValue = e.target.value;\n\n    if (currentValue === '.') { currentValue = '0.'; }\n    const isDot = currentValue.indexOf('.') === (currentValue.length - 1);\n    const intValue = +currentValue;\n    if (isDot || (!Number.isNaN(intValue) && (intValue >= 0 && intValue <= 100))) {\n      const formatted = currentValue.match(/^\\d+\\.?\\d{0,2}/);\n      setInternalValue((formatted && formatted[0]) || '');\n    }\n  };\n\n  return (\n    <div className={wrapperClasses.join(' ')}>\n      {!!(label || desc) && (\n      <div className=\"\">\n        {\n        !!label && <label className={InputCss.inputLabel}>{label}</label>\n      }\n      </div>\n      )}\n      <div className={inputWrapperClass}>\n        <input\n          onChange={handleChange}\n          type={type}\n          ref={ref}\n          disabled={disabled}\n          placeholder={placeholder}\n          value={internalValue}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...restProps}\n        />\n      </div>\n      {!!desc\n    && <Description className={InputCss.desc}>{desc}</Description>}\n      {!!error && <span className={errorClass}>{error}</span>}\n    </div>\n  );\n});\nPercentageInput.displayName = 'PercentageInput';\nPercentageInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nPercentageInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/StringInput.js",
    "content": "import React, { forwardRef, useEffect } from 'react';\nimport PropTypes from 'prop-types';\nimport { regex } from '../utils';\nimport { InputCss } from './inputCss';\nimport { Description } from '../Description';\n// import './input.css';\n\n/**\n * Primary UI component for Input\n */\nexport const StringInput = forwardRef(({\n  wrapperClass = '',\n  className,\n  // inputWrapperClass = 'spark-input-wrapper',\n  label = '',\n  placeholder = '',\n  type = 'text',\n  disabled = false,\n  error = '',\n  onChange = () => { },\n  value = '',\n  minLength,\n  desc,\n  dark,\n  size = 'normal',\n  inputClassName = [],\n  customRegex,\n  ...restProps\n}, ref) => {\n  const [internalValue, setInternalValue] = React.useState(value);\n\n  const wrapperClasses = [InputCss.inputwrapper];\n  const disableClass = disabled ? `${InputCss.inputdisabled}` : '';\n  const inputClasses = [InputCss.inputBlock, disableClass];\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n  if (inputClassName) {\n    inputClasses.push(inputClassName);\n  }\n\n  useEffect(() => {\n    setInternalValue(value);\n  }, [value]);\n\n  useEffect(() => {\n    onChange && onChange(internalValue);\n  }, [internalValue]);\n\n  const handleChange = (e) => {\n    const newValue = e.target.value;\n    if (customRegex) {\n      if (!newValue || customRegex.test(newValue)) setInternalValue(newValue);\n    } else if (!newValue || (regex.string.test(newValue) && newValue[0].match(regex.firstSpace))) {\n      setInternalValue(newValue);\n    }\n  };\n  const sizeCss = `${InputCss[[`input${size}`]]}`;\n\n  return (\n    <div className={wrapperClasses.join(' ')}>\n      {!!(label || desc) && (\n      <div className={!desc && 'mb-2'}>\n        {\n        !!label && <label className={InputCss.inputLabel}>{label}</label>\n      }\n      </div>\n      )}\n      <div className={`${className} ${InputCss.inputWrapperClass}`}>\n        <input\n          onChange={handleChange}\n          type={type}\n          ref={ref}\n          className={`${InputCss.inputBlock} ${sizeCss} ${dark && InputCss.darkInput} ${disableClass} inputBlock`}\n          disabled={disabled}\n          placeholder={placeholder}\n          value={internalValue}\n          minLength={minLength}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...restProps}\n        />\n      </div>\n      {!!desc\n        && <Description className={InputCss.desc}>{desc}</Description>}\n      {!!error && <span className={InputCss.errorClass}>{error}</span>}\n    </div>\n  );\n});\nStringInput.displayName = 'StringInput';\nStringInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  size: PropTypes.oneOf(['normal', 'small', 'medium']),\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nStringInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/contryCode.css",
    "content": ".spark-input-wrapper  .react-tel-input{\n    width: 100%;\n}\n.spark-input-wrapper  .react-tel-input input{\n    width: 100%;\n    background-color: var(--color-gray-input);\n    border: 1px solid var(--color-gray-70);\n    border-radius:3px;\n    height: 43px;\n    color: var(--color-text-primary);\n}\n.spark-input-wrapper  .react-tel-input input:focus{\n    border: 1px solid var(--color-bg-primary);\n}\n.spark-input-wrapper .react-tel-input  .flag-dropdown{\n    border: none;\n    left: 2px;\n    top: 2px;\n    bottom: 2px;\n    background-color: transparent;\n}\n.spark-input-wrapper .react-tel-input .selected-flag .arrow{\n    border-top: 4px solid var(--color--black-svg);\n}\n.spark-input-wrapper  .react-tel-input .selected-flag .arrow.up{\n    border-top: none;\n    border-bottom: 4px solid var(--color--black-svg);\n}\n.spark-input-wrapper .react-tel-input .selected-flag,\n.spark-input-wrapper .react-tel-input .flag-dropdown.open .selected-flag{\n    background-color:  var(--color-gray-200);\n}\n.spark-input-wrapper .react-tel-input .country-list{\n    background-color:var(--color-select-dropdown);\n}\n.spark-input-wrapper .react-tel-input .country-list .country{\n    border-bottom:1px solid var(--color-gray-100);\n}\n.spark-input-wrapper .react-tel-input .country-list .country .dial-code{\n    color: var(--color-text-secondary);\n}\n.spark-input-wrapper .react-tel-input .country-list .country.highlight{\n    background-color: var(--color-bg-primary);\n    color: #fff;\n}\n.spark-input-wrapper .react-tel-input .country-list .country.highlight .dial-code{\n    color: #fff;\n}\n.spark-input-wrapper .react-tel-input .country-list .country:hover{\n    background-color: transparent;\n    color: var(--color-text-primary);\n}\n.spark-input-wrapper .react-tel-input .country-list .country:hover .dial-code{\n    color: var(--color-text-primary);\n}\n.react-tel-input :disabled{\n    opacity: 60%;\n}"
  },
  {
    "path": "packages/client/src/components/Input/index.js",
    "content": "import React, { forwardRef } from 'react';\nimport PropTypes from 'prop-types';\nimport { InputCss } from './inputCss';\nimport { Description } from '../Description';\nimport { removeLeadingSpace } from '../../utils/regex';\n\n/**\n * Primary UI component for Input\n */\nexport const Input = forwardRef(({\n  wrapperClass = '',\n  label = '',\n  placeholder = '',\n  type = 'text',\n  disabled = false,\n  error = '',\n  onChange = () => { },\n  WrapClassName,\n  className,\n  isDec,\n  desc,\n  dark,\n  value = '',\n  extension,\n  size = 'normal',\n  customRegex,\n  labelClassName,\n  inputClass,\n  htmlDesc,\n  isTrim = false,\n  maxLength,\n  inputClassName,\n  ...restProps\n}, ref) => {\n  const wrapperClasses = [InputCss.inputwrapper];\n  const disableClass = disabled ? `${InputCss.inputdisabled}` : '';\n  if (error) {\n    wrapperClasses.push('spark-error-wrapper');\n  }\n  if (wrapperClass) {\n    wrapperClasses.push(wrapperClass);\n  }\n\n  const handleChange = (e) => {\n    let targetVal = e.target.value.replace(removeLeadingSpace, '');\n    if (isTrim) { targetVal = targetVal.trim(); }\n    if (customRegex) {\n      if (!targetVal || customRegex.test(targetVal)) onChange && onChange(targetVal);\n    } else onChange && onChange(targetVal);\n  };\n  const sizeCss = `${InputCss[[`input${size}`]]}`;\n\n  return (\n    <div className={[wrapperClasses, WrapClassName].join(' ')}>\n      {!!(label || desc) && (\n      <div className={labelClassName}>\n        {\n          !!label && <label className={`${InputCss.inputLabel}`}>{label}</label>\n        }\n      </div>\n      )}\n      <div className={`${className} ${InputCss.inputWrapperClass}`}>\n        <div className=\"relative\">\n          <input\n            onChange={handleChange}\n            type={type}\n            className={`${InputCss.inputBlock} truncate ${inputClassName} ${inputClass} ${sizeCss} ${dark && InputCss.darkInput} ${disableClass} inputBlock`}\n            ref={ref}\n            disabled={disabled}\n            placeholder={placeholder}\n            value={value}\n            maxLength={maxLength}\n          // eslint-disable-next-line react/jsx-props-no-spreading\n            {...restProps}\n          />\n          {!!extension && <div className={InputCss.extenstionText}>{extension}</div>}\n        </div>\n        {!!desc\n          && <Description className={InputCss.desc}>{desc}</Description>}\n      </div>\n      {!!htmlDesc\n          && <Description className={InputCss.desc}><div dir=\"ltr\" dangerouslySetInnerHTML={{ __html: htmlDesc }} /></Description> }\n      {!!error && <span className={InputCss.errorClass}>{error}</span>}\n    </div>\n  );\n});\nInput.displayName = 'Input';\nInput.propTypes = {\n  /**\n   * Input label\n   */\n  label: PropTypes.string,\n  size: PropTypes.oneOf(['normal', 'small', 'medium']),\n  /**\n   * class which wraps whole component, label and input\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class which wraps input\n   */\n  inputWrapperClass: PropTypes.string,\n  /**\n   * does input have any error\n   */\n  error: PropTypes.string,\n  /**\n   * is Input disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Helper text class\n   */\n  errorClass: PropTypes.string,\n};\n\nInput.defaultProps = {\n  label: '',\n  error: '',\n  disabled: false,\n};\n"
  },
  {
    "path": "packages/client/src/components/Input/inputCss.js",
    "content": "export const InputCss = {\n  inputwrapper: 'relative',\n  inputWrapperClass: 'relative',\n  desc: 'mt-1',\n  inputBlock: 'font-body text-primary-text bg-gray-input border-1 border-gray-70 placeholder-primary font-normal w-full focus:border-primary-dark focus:outline-none rounded-3',\n  inputnormal: 'py-2 px-2.5 text-sm',\n  inputsmall: 'py-1 px-2 text-xs',\n  inputmedium: 'py-1.5 px-2 text-xs',\n  darkInput: 'bg-gray-inputSub border-gray-300',\n  inputdisabled: 'cursor-not-allowed opacity-60',\n  inputError: 'border-error focus:border-error',\n  inputLabel: 'mb-1.5 text-primary-text text-sm block w-full font-normal leading-5',\n  inputlabelbig: 'text-base',\n  errorClass: 'text-error text-sm mt-1 block',\n  InputTag: 'text-primary-text border-1 border-gray-100 rounded-3 py-0.5 px-2 mr-2 my-1 ml-0 font-semibold text-sm inline-block',\n  InputTagClose: 'ml-2 text-lg',\n  extenstionText: 'absolute text-primary-text font-semibold right-3 top-0 bottom-0 m-auto flex items-center opacity-50 text-sm',\n  // border: 1px solid #e4e4e4;\n};\n"
  },
  {
    "path": "packages/client/src/components/Label/index.js",
    "content": "import React from 'react';\n\nexport const LabelBox = ({ children, className }) => (\n  <label className={`mb-2 text-primary-text text-sm block w-full font-normal leading-5 ${className}`}>{children}</label>\n);\n"
  },
  {
    "path": "packages/client/src/components/LinkTag/index.js",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport PropTypes from 'prop-types';\n\nexport const LinkTag = ({\n  onClick, link, className, children, whiteText,\n}) => (\n  link\n    ? <Link to={link} onClick={onClick} className={`hover:underline ${whiteText ? ' text-primary-text' : 'text-primary-dark'} ${className}`}>{children}</Link>\n    : <span onClick={onClick} className={`cursor-pointer hover:underline ${whiteText ? 'text-primary-text' : 'text-primary-dark'} hover:underline ${className}`}>{children}</span>\n);\nLinkTag.propTypes = {\n  /**\n     * Additional class name\n     */\n  className: PropTypes.string,\n  link: PropTypes.string,\n  onClick: PropTypes.func,\n};\n\nLinkTag.defaultProps = {\n  className: '',\n};\n"
  },
  {
    "path": "packages/client/src/components/ListBox/LIstTitle.js",
    "content": "import React from 'react';\n\nimport { ListBoxCss } from './listboxCss';\n\nexport const ListTitle = ({\n  title, smallTitle, titleClass, onClick,\n}) => (\n  <>\n    {!!title\n    && (\n    <h4\n      onClick={onClick}\n      className={`${ListBoxCss.listTitle} ${titleClass}`}\n    >\n      {title}\n    </h4>\n    )}\n    {!!smallTitle\n    && (\n    <h5 className={`${ListBoxCss.listsmallTitle} ${titleClass}`} onClick={onClick}>\n      {smallTitle}\n    </h5>\n    )}\n  </>\n);\n"
  },
  {
    "path": "packages/client/src/components/ListBox/ListBoxWrap.js",
    "content": "import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { ListBoxCss } from './listboxCss';\n\nexport const ListBoxWrap = ({\n  children, className, onClick, isSelected, variant, popupList, key,\n}) => {\n  const variantClass = `${ListBoxCss[[`list${variant}`]]}`;\n  const [isSelect, setIsSelect] = useState(false);\n  const selectBox = () => {\n    setIsSelect(!isSelect);\n  };\n  // ${isSelect && ListBoxCss.listSelected}\n  return (\n    <div\n      key={key}\n      className={`${popupList ? ListBoxCss.listWrapPopup : ListBoxCss.listWrap} ${className} ${variantClass}`}\n      onClick={isSelected ? selectBox : onClick}\n    >\n      {children}\n    </div>\n  );\n};\n\nListBoxWrap.propTypes = {\n  /**\n     * List Variant?\n     */\n  variant: PropTypes.oneOf(['normal', 'headBox', 'flat', 'bottomOutline', 'popupBox', 'small']),\n};\nListBoxWrap.defaultProps = {\n  variant: 'normal',\n};\n"
  },
  {
    "path": "packages/client/src/components/ListBox/listboxCss.js",
    "content": "export const ListBoxCss = {\n  listWrap: 'border-t-1 border-gray-200 cursor-pointer relative',\n  listWrapPopup: 'border-t-1 border-gray-100 cursor-pointer relative',\n  listnormal: 'py-3 px-1',\n  listflat: 'xl:border-none xxl:border-none',\n  listsmall: 'py-2 px-1',\n  listpopupBox: 'border-t-1 border-gray-100',\n  listheadBox: 'p-0 border-1 rounded-3',\n  listbottomOutline: 'p-4 border-l-0 border-r-0 border-t-0 border-b-0 ml-2 mr-2',\n  listSelected: 'border-primary-dark',\n  listLink: 'primary-gray-text-color font-semibold text-sm md:text-base mr-2',\n  listHead: 'bg-gray-200 p-3 flex items-center',\n  listTitle: 'primary-gray-text-color text-sm',\n  listsmallTitle: 'primary-gray-text-color text-xs',\n  listIconBox: 'flex items-center cursor-pointer',\n  listIconWrap: 'flex items-center justify-end',\n  listIconnormal: 'mr-2 w-3.5 h-3.5',\n  listIconsmall: 'mr-1 w-3 h-3',\n  listTitleBox: 'text-gray-20',\n  listIcontitlenormal: 'text-sm',\n  listIcontitlesmall: 'text-xs',\n  listIconHr: 'mx-4 w-px h-4 my-1 bg-gray-400 block',\n};\n"
  },
  {
    "path": "packages/client/src/components/Loader/index.js",
    "content": "// import Loadable from 'react-loadable';\nimport React from 'react';\n// import Lottie from 'react-lottie';\n// import animationData from '../../config/loaderdata.json';\nimport logoLoader from '../../assets/images/gif/logo-loader.gif';\n\nexport const Loader = ({ style, className }) => (\n  <div className={`min-h-screen flex items-center justify-center ${className}`} style={style}>\n    {/* <Lottie\n        options={defaultOptions}\n        height={200}\n        width={200}\n      /> */}\n    <img width=\"200\" height=\"200\" src={logoLoader} alt=\"loader\" />\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/MenuList/index.js",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport ReactTooltip from 'react-tooltip';\nimport { MenulistCss } from './menuListCss';\n\nexport const MenuBox = ({\n  link,\n  menuClass,\n  onClick,\n  icon,\n  textCss,\n  title,\n  iconClass,\n  tooltip = false,\n}) => (\n  <div\n    data-tip\n    data-for={`tooltip${tooltip}`}\n    className={`${MenulistCss.menuItem} ${!link && MenulistCss.menuSpace} ${menuClass} ${onClick && 'cursor-pointer'}`}\n    onClick={onClick && onClick}\n  >\n    {!!icon && (\n      <div className={`w-4 h-4 ${iconClass}`}>\n        {icon}\n        {!!tooltip && (\n        <ReactTooltip id={`tooltip${tooltip}`} type=\"dark\">\n          {tooltip}\n        </ReactTooltip>\n        )}\n      </div>\n    )}\n    {link ? (\n      <Link\n        to={link}\n        className={MenulistCss.menuListLink}\n\n      >\n        {!!title && (\n        <span className={`text-primary-text text-sm whitespace-nowrap overflow-hidden overflow-ellipsis block ${icon && 'ml-2'} ${textCss}`}>\n          {title}\n        </span>\n        )}\n\n      </Link>\n    )\n      : (\n        <div>\n          {!!title && (\n          <span className={`text-primary-text text-sm whitespace-nowrap overflow-hidden overflow-ellipsis block ${icon && 'ml-2'} ${textCss}`}>\n            {title}\n          </span>\n          )}\n\n        </div>\n      )}\n\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/MenuList/menuListCss.js",
    "content": "export const MenulistCss = {\n  menuItem: 'flex items-center hover:bg-gray-100 ',\n  menuListLink: 'pt-2 pb-2 pl-3 pr-3',\n  menuSpace: 'pt-2 pb-2 pl-3 pr-3',\n};\n"
  },
  {
    "path": "packages/client/src/components/MessageNotify/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Icons } from '@dhiwise/icons';\nimport { InformessageCss } from './informessageCss';\n\nexport const MessageNotify = ({\n  messageType,\n  className,\n  isInfo,\n  isWarring,\n  isAlert,\n  children,\n  isClose,\n  closeClick,\n  messageCloseClass,\n  size,\n}) => {\n  const messageTypeCss = `${InformessageCss[[`message${messageType}`]]}`;\n  const messageSizeCss = `${InformessageCss[[`message${size}`]]}`;\n  const messageSizeText = `${InformessageCss[[`messageText${size}`]]}`;\n  const messageSizeImg = `${InformessageCss[[`messageImg${size}`]]}`;\n  return (\n    <div className={className}>\n      <div className={`${isClose && 'pr-12'} ${[InformessageCss.messagebox, messageTypeCss, messageSizeCss].join(' ')}`}>\n        {(isInfo || isWarring || isAlert) && (\n          <div className={`${InformessageCss.messageimg} ${messageSizeImg}`}>\n            {isInfo && <><Icons.Info color=\"#4289fd\" /></>}\n            {isWarring && <><Icons.Warring color=\"#ffbe00\" /></>}\n            {isAlert && <><Icons.Alert color=\"#E24C4B\" /></>}\n          </div>\n        )}\n        <p className={`${InformessageCss.messagedec} ${messageSizeText}`}>{children}</p>\n        {isClose && (\n          <div className={`${InformessageCss.messageclose} ${messageCloseClass}`} onClick={closeClick}>\n            <Icons.CloseBlack color=\"#232323\" />\n          </div>\n        )}\n      </div>\n    </div>\n  );\n};\nMessageNotify.propTypes = {\n  /** * warring true false */\n  isWarring: PropTypes.bool,\n  /** * alert true false */\n  isAlert: PropTypes.bool,\n  /** * info true false */\n  isInfo: PropTypes.bool,\n  /** * close true false */\n  isClose: PropTypes.bool,\n  /** * How large should the button be? */\n  messageType: PropTypes.oneOf(['info', 'warring', 'alert']),\n  size: PropTypes.oneOf(['normal', 'small']),\n  /**\n   * Additional classname\n   */\n  className: PropTypes.string,\n};\nMessageNotify.defaultProps = {\n  size: 'normal',\n};\n"
  },
  {
    "path": "packages/client/src/components/MessageNotify/informessageCss.js",
    "content": "export const InformessageCss = {\n  messagebox: 'relative flex items-start rounded-3 border-l-4',\n  messagenormal: 'p-3',\n  messagesmall: 'p-2',\n  messageimg: 'flex-shrink-0',\n  messageImgnormal: 'w-4 mr-3 ',\n  messageImgsmall: 'w-3.5 mr-2',\n  messagedec: 'text-primary-message font-bold flex-grow',\n  messageTextnormal: 'text-sm',\n  messageTextsmall: 'text-xs',\n  messageclose: 'w-4 h-4 object-contain m-auto absolute right-5 top-0 bottom-0 cursor-pointer',\n  messageinfo: 'bg-secondary-bluelight border-secondary-blue',\n  messagewarring: 'bg-secondary-yellowlight border-secondary-yellow',\n  messagealert: 'bg-secondary-redlight border-gray-deactivebg',\n};\n"
  },
  {
    "path": "packages/client/src/components/NoData/index.js",
    "content": "import React from 'react';\nimport Lottie from 'react-lottie';\nimport PropTypes from 'prop-types';\nimport animationData from './notfoundproject.json';\nimport { Button } from '../Button';\nimport { Description } from '../Description';\nimport { Heading } from '../Heading';\n\nconst NoData = (props) => {\n  const {\n    title, description, onClick, btnText, className, imageHeight, imgSize, smallBox, isLoading = false,\n  } = props;\n  const defaultOptions = {\n    loop: true,\n    autoplay: true,\n    animationData,\n    rendererSettings: {\n      preserveAspectRatio: 'xMidYMid slice',\n    },\n  };\n  return (\n    <div className=\"flex justify-center items-center py-5 w-full h-full\">\n      <div className={`text-center w-6/12 ${className}`}>\n        <div className=\"nodDataFound\">\n          <Lottie\n            options={defaultOptions}\n            height={imageHeight || 250}\n            width={imgSize || 250}\n          />\n        </div>\n        {!!title && <Heading className={` ${smallBox ? '-mt-4' : '-mt-12'}`} variant={smallBox ? 'h5' : 'h4'}>{title}</Heading>}\n        {description\n          ? (\n            <Description className=\"mt-2\">\n              {description}\n              {' '}\n            </Description>\n          )\n          : null}\n        {onClick && btnText\n          ? <Button onClick={onClick} className=\"mt-4\" shape=\"rounded\" variant=\"primary\" loading={isLoading}>{btnText}</Button>\n          : null}\n      </div>\n    </div>\n  );\n};\nexport default NoData;\nNoData.propTypes = {\n  /**\n   * display no data title\n   */\n  title: PropTypes.string,\n  /**\n   * display no data description\n   */\n  description: PropTypes.string,\n  /**\n   * onclick btn text\n   */\n  btnText: PropTypes.string,\n  /**\n   * function onclick\n   */\n  onClick: PropTypes.func,\n\n};\n\nNoData.defaultProps = {\n  // title: 'No Data Found',\n  // description: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has  and typesetting industry. Lorem Ipsum has.',\n};\n"
  },
  {
    "path": "packages/client/src/components/NoData/notfoundproject.json",
    "content": "{\"v\":\"5.4.1\",\"fr\":29.9700012207031,\"ip\":0,\"op\":132.00000537647,\"w\":1024,\"h\":768,\"nm\":\"Comp 1\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":3,\"nm\":\"Null 1\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":0,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[512,364,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"ip\":316.000012870944,\"op\":316.000012870944,\"st\":0,\"bm\":0,\"hidden\":0},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"Shape Layer 3\",\"parent\":4,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[15.069,93,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,93,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":30,\"s\":[{\"i\":[[0,0],[0,-9.694],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,-12.229],[0,0],[4.98,0],[0,0],[0,-9.694],[0,0]],\"v\":[[101.919,-93],[119.5,-75.419],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-119.5,-40.823],[-97.323,-63],[25.468,-63],[34.5,-72.032],[34.5,-75.419],[52.081,-93]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":35,\"s\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}],\"e\":[{\"i\":[[0,0],[1.245,-9.521],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[2.414,-12.509],[0,0],[4.98,0],[0,0],[1.812,-10.382],[0,0]],\"v\":[[121.293,-67.168],[136.721,-49.587],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-102.279,-14.991],[-79.24,-37.168],[42.689,-37.168],[51.721,-46.2],[52.69,-49.587],[71.455,-67.168]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":40,\"s\":[{\"i\":[[0,0],[1.245,-9.521],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[2.414,-12.509],[0,0],[4.98,0],[0,0],[1.812,-10.382],[0,0]],\"v\":[[121.293,-67.168],[136.721,-49.587],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-102.279,-14.991],[-79.24,-37.168],[42.689,-37.168],[51.721,-46.2],[52.69,-49.587],[71.455,-67.168]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":45,\"s\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}],\"e\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":124,\"s\":[{\"i\":[[0,0],[2.179,-9.391],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[4.225,-12.72],[0,0],[4.98,0],[0,0],[3.172,-10.897],[0,0]],\"v\":[[135.824,-47.794],[149.637,-30.213],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-89.363,4.383],[-65.678,-17.794],[55.605,-17.794],[64.637,-26.826],[66.333,-30.213],[85.985,-47.794]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,-9.694],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,-12.229],[0,0],[4.98,0],[0,0],[0,-9.694],[0,0]],\"v\":[[101.919,-93],[119.5,-75.419],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-119.5,-40.823],[-97.323,-63],[25.468,-63],[34.5,-72.032],[34.5,-75.419],[52.081,-93]],\"c\":true}]},{\"t\":128.000005213547}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0.08627450980392157,1,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":6,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0,0.08627450980392157,1,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":316.000012870944,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"Shape Layer 4\",\"parent\":1,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[0,0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-35.209,-27.596],[13,14],[-4,-9.5]],\"o\":[[0,0],[18.5,14.5],[-12.519,-13.482],[5.242,12.451]],\"v\":[[128.5,-143],[195.5,-191],[172,-165],[183.5,-181]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"gs\",\"o\":{\"a\":0,\"k\":100,\"ix\":9},\"w\":{\"a\":0,\"k\":6,\"ix\":10},\"g\":{\"p\":3,\"k\":{\"a\":0,\"k\":[0,1,0.5019607843137255,0.050980392156862744,0.5,0,0.712,0.912,1,0,0.424,1],\"ix\":8}},\"s\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"e\":{\"a\":0,\"k\":[100,0],\"ix\":5},\"t\":1,\"lc\":2,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":13},\"nm\":\"Gradient Stroke 1\",\"mn\":\"ADBE Vector Graphic - G-Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[10,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[-67.81,84.615],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 5\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-35.209,-27.596],[13,14],[-4,-9.5]],\"o\":[[0,0],[18.5,14.5],[-12.519,-13.482],[5.242,12.451]],\"v\":[[128.5,-143],[195.5,-191],[172,-165],[183.5,-181]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"gs\",\"o\":{\"a\":0,\"k\":100,\"ix\":9},\"w\":{\"a\":0,\"k\":6,\"ix\":10},\"g\":{\"p\":3,\"k\":{\"a\":0,\"k\":[0,1,0.5019607843137255,0.050980392156862744,0.5,0,0.712,0.912,1,0,0.424,1],\"ix\":8}},\"s\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"e\":{\"a\":0,\"k\":[100,0],\"ix\":5},\"t\":1,\"lc\":2,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":13},\"nm\":\"Gradient Stroke 1\",\"mn\":\"ADBE Vector Graphic - G-Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 4\",\"np\":3,\"cix\":2,\"ix\":2,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-32,36]],\"o\":[[0,0],[32,-36]],\"v\":[[20,-36],[50,-198]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"gs\",\"o\":{\"a\":0,\"k\":100,\"ix\":9},\"w\":{\"a\":0,\"k\":6,\"ix\":10},\"g\":{\"p\":3,\"k\":{\"a\":0,\"k\":[0,1,0.5019607843137255,0.050980392156862744,0.5,0,0.712,0.912,1,0,0.424,1],\"ix\":8}},\"s\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"e\":{\"a\":0,\"k\":[100,0],\"ix\":5},\"t\":1,\"lc\":2,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":13},\"nm\":\"Gradient Stroke 1\",\"mn\":\"ADBE Vector Graphic - G-Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 3\",\"np\":3,\"cix\":2,\"ix\":3,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[77,-17]],\"o\":[[0,0],[-77,17]],\"v\":[[-74,-30],[-208,-116]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"gs\",\"o\":{\"a\":0,\"k\":100,\"ix\":9},\"w\":{\"a\":0,\"k\":6,\"ix\":10},\"g\":{\"p\":3,\"k\":{\"a\":0,\"k\":[0,1,0.5019607843137255,0.050980392156862744,0.5,0,0.712,0.912,1,0,0.424,1],\"ix\":8}},\"s\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"e\":{\"a\":0,\"k\":[100,0],\"ix\":5},\"t\":1,\"lc\":2,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":13},\"nm\":\"Gradient Stroke 1\",\"mn\":\"ADBE Vector Graphic - G-Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 2\",\"np\":3,\"cix\":2,\"ix\":4,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-85,-34]],\"o\":[[0,0],[85,34]],\"v\":[[129,-67],[308,-130]],\"c\":false},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[1,0,0,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"gs\",\"o\":{\"a\":0,\"k\":100,\"ix\":9},\"w\":{\"a\":0,\"k\":6,\"ix\":10},\"g\":{\"p\":3,\"k\":{\"a\":0,\"k\":[0,1,0.5019607843137255,0.050980392156862744,0.5,0,0.712,0.912,1,0,0.424,1],\"ix\":8}},\"s\":{\"a\":0,\"k\":[0,0],\"ix\":4},\"e\":{\"a\":0,\"k\":[100,0],\"ix\":5},\"t\":1,\"lc\":2,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":13},\"nm\":\"Gradient Stroke 1\",\"mn\":\"ADBE Vector Graphic - G-Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":5,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0_1_0p167_0p167\"],\"t\":40,\"s\":[0],\"e\":[100]},{\"t\":58.0000023623884}],\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0_1_0p167_0p167\"],\"t\":36,\"s\":[0],\"e\":[100]},{\"t\":54.0000021994651}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":6,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":316.000012870944,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"Shape Layer 5\",\"parent\":1,\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":50,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[-13,138,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,93,0],\"ix\":1},\"s\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.924,0.924,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.751,0.751,0.333],\"y\":[0,0,0]},\"n\":[\"0p924_1_0p751_0\",\"0p924_1_0p751_0\",\"0p667_1_0p333_0\"],\"t\":16,\"s\":[49.726,49.726,100],\"e\":[132.726,132.726,100]},{\"i\":{\"x\":[0.924,0.924,0.667],\"y\":[1,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"n\":[\"0p924_1_0p333_0\",\"0p924_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":30,\"s\":[132.726,132.726,100],\"e\":[132.726,132.726,100]},{\"i\":{\"x\":[0.833,0.833,0.833],\"y\":[1,1,1]},\"o\":{\"x\":[0.333,0.333,0.333],\"y\":[0,0,0]},\"n\":[\"0p833_1_0p333_0\",\"0p833_1_0p333_0\",\"0p833_1_0p333_0\"],\"t\":118,\"s\":[132.726,132.726,100],\"e\":[49.726,49.726,100]},{\"t\":128.000005213547}],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":1,\"k\":[{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":32,\"s\":[{\"i\":[[0,0],[0,-9.694],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,-12.229],[0,0],[4.98,0],[0,0],[0,-9.694],[0,0]],\"v\":[[101.919,-93],[119.5,-75.419],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-119.5,-40.823],[-97.323,-63],[25.468,-63],[34.5,-72.032],[34.5,-75.419],[52.081,-93]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0.498,-9.625],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0.966,-12.341],[0,0],[4.98,0],[0,0],[0.725,-9.969],[0,0]],\"v\":[[109.669,-82.667],[126.389,-65.087],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-112.611,-30.49],[-90.09,-52.667],[32.356,-52.667],[41.389,-61.7],[41.776,-65.087],[59.83,-82.667]],\"c\":true}]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p833_0p833_0p167_0p167\",\"t\":36,\"s\":[{\"i\":[[0,0],[0.498,-9.625],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0.966,-12.341],[0,0],[4.98,0],[0,0],[0.725,-9.969],[0,0]],\"v\":[[109.669,-82.667],[126.389,-65.087],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-112.611,-30.49],[-90.09,-52.667],[32.356,-52.667],[41.389,-61.7],[41.776,-65.087],[59.83,-82.667]],\"c\":true}],\"e\":[{\"i\":[[0,0],[0,-9.694],[0,0],[12.229,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,4.98],[0,0],[-9.694,0]],\"o\":[[9.694,0],[0,0],[0,12.229],[0,0],[-12.229,0],[0,0],[0,-12.229],[0,0],[4.98,0],[0,0],[0,-9.694],[0,0]],\"v\":[[101.919,-93],[119.5,-75.419],[119.5,70.823],[97.323,93],[-97.323,93],[-119.5,70.823],[-119.5,-40.823],[-97.323,-63],[25.468,-63],[34.5,-72.032],[34.5,-75.419],[52.081,-93]],\"c\":true}]},{\"t\":40.0000016292334}],\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[1,1,1,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":6,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0,0.08627450980392157,1,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":true},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Shape 1\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":0,\"op\":316.000012870944,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":5,\"ty\":4,\"nm\":\"NO DATA Outlines\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"s\":true,\"x\":{\"a\":0,\"k\":452,\"ix\":3},\"y\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.03],\"y\":[0.238]},\"n\":[\"0p667_1_0p03_0p238\"],\"t\":35,\"s\":[344],\"e\":[204]},{\"i\":{\"x\":[0.667],\"y\":[1]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p667_1_0p333_0\"],\"t\":45,\"s\":[204],\"e\":[204]},{\"i\":{\"x\":[0.957],\"y\":[0.75]},\"o\":{\"x\":[0.333],\"y\":[0]},\"n\":[\"0p957_0p75_0p333_0\"],\"t\":98,\"s\":[204],\"e\":[324]},{\"t\":105.000004276738}],\"ix\":4}},\"a\":{\"a\":0,\"k\":[0,0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[122.539,122.539,100],\"ix\":6}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[11.813,-28.459],[11.813,-15.645],[7.664,-28.459],[1.477,-28.459],[1.477,0],[7.664,0],[7.664,-12.938],[11.514,0],[18,0],[18,-28.459]],\"c\":true},\"ix\":2},\"nm\":\"N\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.9215686274509803,0.9215686274509803,0.9215686274509803,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"N\",\"np\":3,\"cix\":2,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0.141,1.172],[0.738,0.996],[1.213,0.498],[1.523,0],[1.207,-0.527],[0.709,-0.984],[0.135,-1.189],[0,-2.859],[0,0],[-0.141,-1.172],[-0.738,-0.996],[-1.213,-0.498],[-1.524,0],[-1.207,0.527],[-0.709,0.984],[-0.135,1.19],[0,2.859]],\"o\":[[0,-2.93],[-0.141,-1.172],[-0.738,-0.996],[-1.213,-0.498],[-1.606,0],[-1.207,0.527],[-0.709,0.984],[-0.135,1.19],[0,0],[0,2.93],[0.141,1.172],[0.738,0.996],[1.213,0.498],[1.605,0],[1.207,-0.527],[0.709,-0.984],[0.135,-1.189],[0,0]],\"v\":[[37.881,-16.664],[37.67,-22.816],[36.352,-26.068],[33.425,-28.31],[29.32,-29.057],[25.102,-28.266],[22.228,-25.998],[20.962,-22.737],[20.76,-16.664],[20.76,-11.795],[20.971,-5.643],[22.289,-2.391],[25.216,-0.149],[29.32,0.598],[33.539,-0.193],[36.413,-2.461],[37.679,-5.722],[37.881,-11.795]],\"c\":true},\"ix\":2},\"nm\":\"O\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ind\":1,\"ty\":\"sh\",\"ix\":2,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0.141,-0.445],[0.504,0],[0.135,0.387],[0,1.652],[0,0],[-0.205,0.299],[-0.387,0],[-0.147,-0.369],[0,-1.324]],\"o\":[[0,1.676],[-0.141,0.445],[-0.492,0],[-0.135,-0.387],[0,0],[0,-1.465],[0.205,-0.299],[0.457,0],[0.146,0.369],[0,0]],\"v\":[[30.48,-8.068],[30.27,-4.887],[29.303,-4.219],[28.362,-4.799],[28.16,-7.857],[28.16,-21.146],[28.468,-23.792],[29.355,-24.24],[30.261,-23.687],[30.48,-21.146]],\"c\":true},\"ix\":2},\"nm\":\"O\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\",\"mn\":\"ADBE Vector Filter - Merge\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.921568986481,0.921568986481,0.921568986481,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"O\",\"np\":5,\"cix\":2,\"ix\":2,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[-0.879,0.193],[-0.598,0.486],[-0.24,0.861],[0,2.555],[0,0],[0.164,0.92],[0.656,0.75],[1.26,0.328],[3.574,0],[0,0]],\"o\":[[0,0],[1.769,0],[0.879,-0.193],[0.598,-0.486],[0.24,-0.861],[0,0],[0,-2.695],[-0.164,-0.92],[-0.656,-0.75],[-1.26,-0.328],[0,0],[0,0]],\"v\":[[46.986,0],[56.32,0],[60.293,-0.29],[62.508,-1.31],[63.765,-3.331],[64.125,-8.455],[64.125,-18.422],[63.879,-23.845],[62.648,-26.35],[59.774,-27.967],[52.523,-28.459],[46.986,-28.459]],\"c\":true},\"ix\":2},\"nm\":\"D\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ind\":1,\"ty\":\"sh\",\"ix\":2,\"ks\":{\"a\":0,\"k\":{\"i\":[[-0.293,-0.17],[-0.082,-0.363],[0,-1.289],[0,0],[0.246,-0.428],[1.066,0],[0,0]],\"o\":[[0.293,0.17],[0.082,0.363],[0,0],[0,1.898],[-0.246,0.428],[0,0],[0.809,0]],\"v\":[[56.039,-23.335],[56.602,-22.535],[56.725,-20.057],[56.725,-9],[56.355,-5.511],[54.387,-4.869],[54.387,-23.59]],\"c\":true},\"ix\":2},\"nm\":\"D\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\",\"mn\":\"ADBE Vector Filter - Merge\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.921568986481,0.921568986481,0.921568986481,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"D\",\"np\":5,\"cix\":2,\"ix\":3,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[68.981,-28.459],[65.206,0],[72.857,0],[73.302,-5.115],[75.949,-5.115],[76.346,0],[83.909,0],[79.677,-28.459]],\"c\":true},\"ix\":2},\"nm\":\"A\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ind\":1,\"ty\":\"sh\",\"ix\":2,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-0.754,5.449],[-0.375,-3.223]],\"o\":[[0.193,-2.519],[0.377,4.746],[0,0]],\"v\":[[73.208,-10.16],[74.628,-22.113],[75.755,-10.16]],\"c\":true},\"ix\":2},\"nm\":\"A\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\",\"mn\":\"ADBE Vector Filter - Merge\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.921568986481,0.921568986481,0.921568986481,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"A\",\"np\":5,\"cix\":2,\"ix\":4,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[81.914,-28.459],[81.914,-22.764],[86.291,-22.764],[86.291,0],[93.691,0],[93.691,-22.764],[98.086,-22.764],[98.086,-28.459]],\"c\":true},\"ix\":2},\"nm\":\"T\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.921568986481,0.921568986481,0.921568986481,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"T\",\"np\":3,\"cix\":2,\"ix\":5,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"o\":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],\"v\":[[100.428,-28.459],[96.653,0],[104.304,0],[104.749,-5.115],[107.396,-5.115],[107.793,0],[115.356,0],[111.125,-28.459]],\"c\":true},\"ix\":2},\"nm\":\"A\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ind\":1,\"ty\":\"sh\",\"ix\":2,\"ks\":{\"a\":0,\"k\":{\"i\":[[0,0],[-0.754,5.449],[-0.375,-3.223]],\"o\":[[0.193,-2.519],[0.377,4.746],[0,0]],\"v\":[[104.655,-10.16],[106.075,-22.113],[107.202,-10.16]],\"c\":true},\"ix\":2},\"nm\":\"A\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"mm\",\"mm\":1,\"nm\":\"Merge Paths 1\",\"mn\":\"ADBE Vector Filter - Merge\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0,0,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":2,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":4,\"ml2\":{\"a\":0,\"k\":4,\"ix\":8},\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":true},{\"ty\":\"fl\",\"c\":{\"a\":0,\"k\":[0.921568986481,0.921568986481,0.921568986481,1],\"ix\":4},\"o\":{\"a\":0,\"k\":100,\"ix\":5},\"r\":1,\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[0,0],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"A\",\"np\":5,\"cix\":2,\"ix\":6,\"mn\":\"ADBE Vector Group\",\"hd\":false}],\"ip\":35.0000014255792,\"op\":106.000004317469,\"st\":25.0000010182709,\"bm\":0}],\"markers\":[]}"
  },
  {
    "path": "packages/client/src/components/PopOver/index.js",
    "content": "import React from 'react';\nimport Popover from 'react-popover';\n\nexport const PopOver = ({\n  data, popOverValue, className, place, dropdownWrapClass, style,\n}) => {\n  const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);\n  const showPopup = React.useCallback(() => {\n    setIsPopoverOpen(!isPopoverOpen);\n  });\n\n  return (\n    <Popover\n      body={[\n        <>\n          {popOverValue}\n        </>,\n      ]}\n      style={style}\n      isOpen={isPopoverOpen}\n      onOuterAction={showPopup}\n      refreshIntervalMs={10}\n      enterExitTransitionDurationMs={10}\n      tipSize={10}\n      place={place || null}\n      className={`popupCustom ${dropdownWrapClass}`}\n    >\n      <span\n        className={className}\n        onClick={showPopup}\n      >\n        {data}\n      </span>\n    </Popover>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/components/Popup/index.js",
    "content": "import React from 'react';\nimport Modal from 'react-modal';\nimport PropTypes from 'prop-types';\nimport { Icons } from '@dhiwise/icons';\nimport { Button } from '../Button';\nimport { Heading } from '../Heading';\nimport { Description } from '../Description';\n\nconst PopupCss = {\n  closebutton: 'absolute right-6 top-6 focus:outline-none',\n  closebuttonimg: 'w-5',\n  popupwrap: 'w-full bg-gray-black border-1 border-gray-100 rounded-lg',\n  overlay: 'fixed top-0 bottom-0 w-full h-full z-10',\n  titleCss: 'text-primary-text font-bold py-4 px-6 border-b border-gray-100',\n  popupbody: 'p-4 md:p-6',\n  poupupfooter: 'flex flex-wrap items-center md:flex-nowrap justify-end py-3 px-2 md:px-8 border-t border-gray-100',\n};\nconst customStyles = {\n  content: {\n    top: '50%',\n    left: '50%',\n    right: 'auto',\n    bottom: 'auto',\n    marign: 'auto',\n    transform: 'translate(-50%, -50%)',\n    border: 'none',\n    background: 'transparent',\n    overflow: 'visible',\n  },\n};\n\nexport const Popup = (props) => (\n  <Modal\n    isOpen={props.isOpen}\n    onAfterOpen={props.afterOpenModal}\n    onRequestClose={props.closeModal}\n    style={customStyles}\n    contentLabel=\"Example Modal\"\n    className={`${props.size ? props.size : 'xxl:w-6/12 xl:w-8/12 '} absolute m-auto bg-white focus:outline-none`}\n    overlayClassName={`${PopupCss.overlay} ${props.backPopup && 'backPopup'}`}\n    appElement={document.getElementById('root')}\n  >\n    <div className={`${PopupCss.popupwrap} ${props.popupWrap}`}>\n      {!!props.title && (\n        <>\n          <div className={`${PopupCss.titleCss} popupHeader`}>\n            <Heading variant=\"h4\" className={props.titleClass}>{props.title}</Heading>\n            {!!props.desc\n          && (\n          <Description className=\"mt-0.5\">\n            {props.desc}\n          </Description>\n          )}\n          </div>\n        </>\n      )}\n      {props.closeFalse ? null : (\n        <button onClick={props.closeModal} className={`${PopupCss.closebutton} ${props.CloseClass}`}>\n          <div className={PopupCss.closebuttonimg}><Icons.Close /></div>\n        </button>\n      )}\n      <div className={`${PopupCss.popupbody} ${props.bodyClass}`} style={props.style}>{props.children}</div>\n      {(props.submit || props.cancel) && (\n      <div className={`${PopupCss.poupupfooter} popupFooter `}>\n        {props.cancel && (\n        <Button\n          onClick={props.handleCancel}\n          className=\"m-1 md:mr-2\"\n          type=\"cancel\"\n          variant=\"outline\"\n          shape=\"rounded\"\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          {...(props.isAutoFocusOnSave && { tabindex: -1 })}\n        >\n          {props.cancel}\n        </Button>\n        )}\n        {!!props.extraButton\n        && (\n        <Button className=\"m-1 md:mr-2\" variant=\"secondary\" shape=\"rounded\" onClick={props.handleExtra}>\n          {props.extraButton}\n        </Button>\n        )}\n        {props.submit && (\n        <Button\n          onClick={props.handleSubmit}\n          type=\"submit\"\n          shape=\"rounded\"\n          loading={props.submitLoading}\n          disabled={props.disabledSubmit || false}\n        >\n          {props.submit}\n        </Button>\n        )}\n      </div>\n      ) }\n    </div>\n  </Modal>\n);\n\nPopup.propTypes = {\n  size: PropTypes.oneOf(['xl', 'lg', 'md', 'sm', 'xs']),\n};\n"
  },
  {
    "path": "packages/client/src/components/Radio/RadioGroup.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport PropTypes from 'prop-types';\nimport React, { forwardRef, useState } from 'react';\nimport { classNames } from '../utils';\nimport { radioCss } from './radioCss';\nimport './radiogroup.css';\n\nexport const Radio = forwardRef((props, ref) => {\n  const {\n    children = '',\n    value = '',\n    isParentDisabled = false,\n    disabled = false,\n    // labelClass = 'spark-radio-label',\n    checked = false,\n    name = '',\n    prefixCls = 'spark-radio',\n    wrapperClass = 'spark-radio-wrapper',\n    className = '',\n    ...restProps\n  } = props;\n  const wrapperClasses = classNames(wrapperClass, className, {\n    [`${wrapperClass}-checked`]: checked,\n    [`${wrapperClass}-disabled`]: disabled || isParentDisabled,\n  });\n\n  const radioClass = classNames(prefixCls, {\n    [`${prefixCls}-checked`]: checked,\n    [`${prefixCls}-disabled`]: disabled || isParentDisabled,\n\n  });\n\n  return (\n    <label className={`${wrapperClasses} ${radioCss.radioWrap}`}>\n      <span className={radioClass}>\n        <input\n          role=\"radio\"\n          aria-checked={checked}\n          checked={checked}\n          className={`${prefixCls}-input`}\n          type=\"radio\"\n          name={name}\n          ref={ref}\n          disabled={disabled}\n          value={value}\n          {...restProps}\n        />\n        <span className={`${prefixCls}-inner`} />\n      </span>\n      {!!children && <span className={radioCss.radioBoxLabel}>{children}</span>}\n    </label>\n  );\n});\n\nRadio.displayName = 'Radio';\n\nexport const RadioGroup = ({\n  direction = 'horizontal',\n  onChange = () => { },\n  prefixCls = 'spark-radio',\n  wrapperClassname = '',\n  wrapperStyle = {},\n  selectedValue,\n  children,\n  name,\n  label = '',\n  error = '',\n  className,\n  errorClass = 'spark-input-radio-text',\n  /**\n   * disabled on Radiogroup component disables all children\n   */\n  disabled = false,\n}) => {\n  const [value, setValue] = useState(selectedValue || '');\n\n  React.useEffect(() => {\n    setValue(selectedValue);\n  }, [selectedValue]);\n\n  const wrapperClass = classNames(`${prefixCls}-group`, wrapperClassname, {\n    'vertical-options': direction === 'vertical',\n  });\n\n  const handleChange = (event, val, isDisabled) => {\n    if (isDisabled) return;\n    setValue(val);\n    onChange && onChange(val, event);\n  };\n\n  const childrens = React.Children.map(children, (child) => {\n    if (child.type === Radio) {\n      return React.cloneElement(child, {\n        name,\n        checked: child.props.value === value,\n        isParentDisabled: disabled,\n        onChange: (e) => handleChange(e, child.props.value, child.props.disabled),\n        direction,\n        disabled: child.props.disabled,\n      });\n    }\n    return child;\n  });\n\n  return (\n    <div className={`${wrapperClass} ${className}`} style={wrapperStyle}>\n      {\n        !!label && <label className={radioCss.radioLabel}>{label}</label>\n      }\n      {childrens}\n\n      {!!error && <div><span className={errorClass}>{error}</span></div>}\n\n    </div>\n  );\n};\n\nRadioGroup.propTypes = {\n  name: PropTypes.string,\n  direction: PropTypes.oneOf([\n    'vertical',\n    'horizontal',\n  ]),\n  children: PropTypes.node.isRequired,\n  selectedValue: PropTypes.oneOfType([\n    PropTypes.string,\n    PropTypes.bool,\n    PropTypes.number,\n  ]),\n  /**\n   * disabled on Radiogroup component disables all children\n   */\n  disabled: PropTypes.bool,\n};\n"
  },
  {
    "path": "packages/client/src/components/Radio/radioCss.js",
    "content": "export const radioCss = {\n  radioLabel: 'text-primary-text text-base block w-full font-normal leading-6',\n  radioBoxLabel: 'text-primary-text text-sm block w-full font-normal',\n  radioWrap: 'flex items-center',\n};\n"
  },
  {
    "path": "packages/client/src/components/Radio/radiogroup.css",
    "content": ".spark-radio-group {\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n  /* margin: 0; */\n  padding: 0;\n  color: rgba(0, 0, 0, 0.65);\n  font-size: 14px;\n  font-variant: tabular-nums;\n  line-height: 1.5;\n  list-style: none;\n  -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  font-feature-settings: \"tnum\", \"tnum\";\n  /* display: inline-block; */\n}\n.spark-radio,\n.spark-radio-wrapper {\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n  padding: 0;\n  color: rgba(0, 0, 0, 0.65);\n  font-size: 14px;\n  font-variant: tabular-nums;\n  line-height: 1.5;\n  list-style: none;\n  -webkit-font-feature-settings: \"tnum\", \"tnum\";\n  font-feature-settings: \"tnum\", \"tnum\";\n  position: relative;\n  /* display: inline-block; */\n  white-space: nowrap;\n  cursor: pointer;\n}\n.spark-radio-wrapper-disabled{\n  cursor: not-allowed;\n  opacity: 0.5;\n}\n/* .spark-radio-wrapper {\n  margin: 0 8px 0 0;\n} */\n.spark-radio {\n  margin: 0;\n  display: inline-flex;\n  vertical-align: sub;\n  outline: none;\n}\nform input[type=\"checkbox\"],\nform input[type=\"radio\"] {\n  width: 14px;\n  height: 14px;\n  line-height: normal;\n}\n.spark-radio-input {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1;\n  cursor: pointer;\n  opacity: 0;\n}\n.spark-radio-checked .spark-radio-inner {\n  background-color: var(--color-bg-primary) !important;\n  border: 1px solid var(--color-bg-primary);\n}\n.spark-radio-inner {\n  position: relative;\n  top: 0;\n  left: 0;\n  display: block;\n  width: 20px;\n  height: 20px;\n  background-color:var(--color-gray-input);\n  border: 1px solid var(--color-gray-70);\n  /* border: 1px solid #d9d9d9; */\n  border-radius: 100px;\n  -webkit-transition: all 0.3s;\n  transition: all 0.3s;\n}\n.spark-radio-input:focus ~ .spark-radio-inner{\n  box-shadow: 0 0 0 3px rgb(0 97 255 / 40%);\n  /* background: var(--color-gray-70); */\n}\n.spark-radio-checked:after {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 1px solid var(--color-bg-primary);\n  border-radius: 50%;\n  visibility: hidden;\n  -webkit-animation: antRadioEffect 0.36s ease-in-out;\n  animation: antRadioEffect 0.36s ease-in-out;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both;\n  content: \"\";\n}\nspan.spark-radio + * {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.spark-radio-checked .spark-radio-inner:after {\n  -webkit-transform: scale(1);\n  -ms-transform: scale(1);\n  transform: scale(1);\n  opacity: 1;\n  -webkit-transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n  transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n}\n.spark-radio-inner:after {\n  background-color: #fff !important;\n}\n.spark-radio-inner:after {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  margin: auto;\n  display: block;\n  width: 8px;\n  height: 8px;\n  background-color: var(--color-bg-primary);\n  border-top: 0;\n  border-left: 0;\n  border-radius: 10px;\n  transform: scale(0);\n  opacity: 0;\n  transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);\n  content: \" \";\n}\n.vertical-options {\n  display: flex;\n  flex-direction: column;\n}\n\n.spark-radio-disabled .spark-radio-inner {\n  background-color: #f5f5f5;\n  border-color: #d9d9d9 !important;\n  cursor: not-allowed;\n}\n.spark-radio-disabled input{\n  width: 100%;\n  height: 100%;\n  cursor: not-allowed;\n}\n/* .spark-radio-disabled + span {\n  color: rgba(0, 0, 0, 0.25);\n  cursor: not-allowed;\n} */\n.spark-radio-header-label {\n  color: #000;\n  font-size: 14px;\n  display: block;\n  width: 100%;\n  font-weight: 600;\n  margin-bottom: 10px;\n}\n.spark-input-radio-text {\n  color: #ee3b3b;\n  font-size: 16px;\n}\n\n\n\n/* new */\n.radioBoxWrap{\n  display: block;\n  position: relative;\n  padding-left: 25px;\n  margin-bottom: 12px;\n  cursor: pointer;\n  font-size: 20px;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.radioBoxWrap input {\n  position: absolute;\n  opacity: 0;\n  left: 0;\n  top: 0;\n  z-index: 1;\n  height: 16px;\n  width: 16px;\n  cursor: pointer;\n}\n\n.radioChecker {\n  position: absolute;\n  top: -5px;\n  left: 0;\n  height: 16px;\n  width: 16px;\n  background-color: var(--color-gray-90);\n  border-radius: 50%;\n}\n\n.radioBoxWrap:hover input ~ .radioChecker {\n  background-color: #ccc;\n}\n\n.radioBoxWrap input:checked ~ .radioChecker {\n  background-color: var(--color-bg-primary);\n}\n\n.radioChecker:after {\n  content: \"\";\n  position: absolute;\n  display: none;\n}\n\n.radioBoxWrap input:checked ~ .radioChecker:after {\n  display: block;\n}\n.radioBoxWrap .radioChecker:after {\n \ttop: 5px;\n\tleft:5px;\n\twidth: 6px;\n\theight: 6px;\n\tborder-radius: 50%;\n\tbackground: white;\n}"
  },
  {
    "path": "packages/client/src/components/ReactDrawer/DrawerClose.js",
    "content": "import { Icons } from '@dhiwise/icons';\nimport React from 'react';\nimport { IconBox } from '../IconBox';\n\nexport const DrawerClose = ({ onClick }) => (\n  <IconBox variant=\"ghost\" className=\"absolute right-0 top-4\" onClick={onClick} icon={<Icons.Close />} />\n);\n"
  },
  {
    "path": "packages/client/src/components/ReactDrawer/DrawerFooter.js",
    "content": "import React from 'react';\nimport ErrorMsg from '../ErrorMsg';\nimport { Button } from '../Button';\n\nexport const DrawerFooter = ({\n  isAutoFocusOnSave, isSaveNext, isNextSubmitting, handleNextSubmit, // manage differnt props for save&next\n  submitTitle, handleSubmit, isSubmitting, handleCancel, cancelTitle, error, canSubmit = true, saveNext,\n}) => (\n  <div className=\"px-5 py-3 border-t border-gray-100 flex justify-end sidebarFooter\">\n    {\n      error && <ErrorMsg error={error} className=\"mr-auto\" />\n    }\n\n    <Button\n      variant=\"outline\"\n      shape=\"rounded\"\n      onClick={handleCancel}\n       // eslint-disable-next-line react/jsx-props-no-spreading\n      {...(isAutoFocusOnSave && { tabindex: -1 })}\n    >\n      {cancelTitle}\n    </Button>\n    {!!saveNext && (\n    <Button\n      variant=\"primary\"\n      disabled={!canSubmit}\n      shape=\"rounded\"\n      className=\"ml-2\"\n      onClick={handleSubmit}\n      loading={isSubmitting}\n    >\n      {saveNext}\n    </Button>\n    )}\n    <Button\n      variant=\"primary\"\n      disabled={!canSubmit}\n      shape=\"rounded\"\n      className=\"ml-2\"\n      onClick={isSaveNext ? handleNextSubmit : handleSubmit}\n      loading={isSaveNext ? isNextSubmitting : isSubmitting}\n    >\n      {submitTitle}\n    </Button>\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/ReactDrawer/DrawerHead.js",
    "content": "import React from 'react';\nimport { Heading } from '../Heading';\n\nexport const DrawerHead = ({ children, title, className }) => (\n  <div className={`px-5 pr-16 py-3 border-b border-gray-100 sidebarTop ${className}`}>\n    <Heading variant=\"h4\">{title}</Heading>\n    {children}\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/ReactDrawer/index.js",
    "content": "/* eslint-disable camelcase */\n/*!\n * ReactDrawer\n * Licensed under the MIT license\n *\n * Copyright (c) 2016 Tony Li\n */\n\n// import animate from 'animate.css';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { Icons } from '@dhiwise/icons';\nimport { ReactDrawerCss } from './reactDrawerCss';\n\nclass ReactDrawer extends React.Component {\n  constructor(props) {\n    super(props);\n    this.openDrawer = this.openDrawer.bind(this);\n    this.closeDrawer = this.closeDrawer.bind(this);\n    this.onAnimationEnded = this.onAnimationEnded.bind(this);\n  }\n\n  UNSAFE_componentWillMount() {\n    this.setState({\n      open: this.props.open,\n      hiddenOverlay: true,\n      hiddenDrawer: true,\n    });\n  }\n\n  componentDidMount() {\n    this.drawer.addEventListener('webkitAnimationEnd', this.onAnimationEnded);\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    if (nextProps.open !== this.state.open) {\n      nextProps.open ? this.openDrawer() : this.closeDrawer();\n    }\n  }\n\n  componentWillUnmount() {\n    this.drawer.removeEventListener('webkitAnimationEnd', this.onAnimationEnded);\n  }\n\n  onAnimationEnded() {\n    if (!this.state.open) {\n      this.setState({\n        hiddenOverlay: true,\n        hiddenDrawer: true,\n      });\n    }\n  }\n\n  getOverlayClassName(drawerCss) {\n    return classNames(\n      'react-drawer-overlay',\n      drawerCss.overlay,\n      //   animate.animated,\n      {\n        // [`${animate.fadeIn}`]: this.state.open,\n        // [`${animate.fadeOut}`]: !this.state.open,\n        [`${drawerCss.hidden}`]: this.state.hiddenOverlay,\n      },\n    );\n  }\n\n  getDrawerClassName(drawerCss) {\n    const position = this.props.position || 'right';\n    const themeAttr = `drawer${position}`;\n    const drawerTheme = drawerCss[themeAttr];\n    // const fade = animate[`fade${direction}${start}`];\n    return classNames(\n      'react-drawer-drawer',\n      drawerCss.drawer,\n      drawerTheme,\n      //   animate.animated,\n      //   fade,\n      {\n        [`${drawerCss.hidden}`]: this.state.hiddenDrawer,\n      },\n    );\n  }\n\n  openDrawer() {\n    this.setState({\n      hiddenOverlay: false,\n      hiddenDrawer: false,\n      open: true,\n    });\n  }\n\n  closeDrawer() {\n    this.setState({\n      open: false,\n    });\n    if (this.props.onClose) {\n      this.props.onClose();\n    }\n  }\n\n  render() {\n    const overlayClass = this.getOverlayClassName(ReactDrawerCss);\n    const drawerClass = this.getDrawerClassName(ReactDrawerCss);\n    const typeClass = `${ReactDrawerCss[[`drawer${this.props.type}`]]}`;\n    return (\n      <div className=\"\">\n        {!this.props.noOverlay ? (\n          <div\n            ref={(c) => { this.overlay = c; }}\n            className={`${overlayClass}`}\n            onClick={this.closeDrawer}\n          />\n        ) : null}\n        <div\n          className={`${drawerClass} ${this.props.size} ${typeClass}`}\n          ref={(c) => { this.drawer = c; }}\n        >\n          {this.props.CloseFalse ? null\n            : (\n              <div onClick={this.closeDrawer} className=\"w-5 h-5 absolute right-5 top-6 cursor-pointer\">\n                <Icons.Close />\n              </div>\n            )}\n          {this.props.children}\n        </div>\n      </div>\n    );\n  }\n}\n\nReactDrawer.propTypes = {\n  open: PropTypes.bool.isRequired,\n  onClose: PropTypes.func,\n  position: PropTypes.oneOf(['top', 'bottom', 'right', 'left']),\n  type: PropTypes.oneOf(['horizontal', 'vertical']),\n  noOverlay: PropTypes.bool,\n};\n\nexport default ReactDrawer;\n"
  },
  {
    "path": "packages/client/src/components/ReactDrawer/reactDrawerCss.js",
    "content": "export const ReactDrawerCss = {\n  drawer: 'fixed block bg-gray-black border-gray-100 border-t border-1 shadows-dw1 z-1000000',\n  drawerbottom: 'bottom-0',\n  drawertop: 'top-0',\n  drawerright: 'right-0',\n  drawerleft: 'left-0',\n  drawervertical: 'w-6/12 top-0 bottom-0',\n  drawerhorizontal: 'h-64 w-full left-0 right-0',\n  overlay: 'w-full h-full fixed top-0 left-0 z-1000000 bg-overlay transition-all',\n};\n"
  },
  {
    "path": "packages/client/src/components/SearchBox/RecentSearch.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport { DropdownMenu, MenuItem } from '../DropdownMenu';\n\nconst SearchBoxCss = {\n  recentcss: 'w-4 h-4 cursor-pointer',\n  recentimg: 'w-full h-full',\n};\nexport const RecentSearch = () => (\n  <DropdownMenu\n    position=\"left\"\n    dropdownMenu=\"absolute w-4 h-4 left-6\"\n    placeholder={() => (\n      <div className={SearchBoxCss.recentimg}>\n        <Icons.RecentSearch />\n      </div>\n    )}\n    className={SearchBoxCss.recentcss}\n    triggerType=\"component\"\n    trigger=\"recenet\"\n    title=\"Recent Search\"\n  >\n    <MenuItem text=\"# Files\" location=\"/\" />\n    <MenuItem text=\"React project\" location=\"/\" />\n    <MenuItem text=\"Node.js project\" location=\"/\" />\n  </DropdownMenu>\n);\n"
  },
  {
    "path": "packages/client/src/components/SearchBox/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport debounce from 'lodash/debounce';\nimport { Icons } from '@dhiwise/icons';\nimport { RecentSearch } from './RecentSearch';\nimport { SearchBoxCss } from './searchBoxCss';\n\nexport const SearchBox = ({\n  children,\n  className = '',\n  size,\n  placeholder,\n  isRecentsearch,\n  isSearch,\n  header,\n  onSearch,\n  value = '',\n  searchOnEnter = false,\n  serachOnIconClick = false,\n  // backgroundColor,\n  ...props\n}) => {\n  const [internalValue, setInternalValue] = React.useState(value);\n\n  const delayedCallback = debounce((event) => {\n    onSearch(event.target.value);\n  }, 1500);\n\n  const handleSearchValue = (event) => {\n    event.persist();\n    delayedCallback(event);\n  };\n\n  React.useEffect(() => {\n    setInternalValue(value);\n  }, [value]);\n\n  const handleChange = (e) => {\n    const newValue = e.target.value;\n    !searchOnEnter && handleSearchValue(e);\n    setInternalValue(newValue);\n  };\n  const handleKeyPress = (e) => {\n    if (searchOnEnter && e.key === 'Enter') {\n      onSearch(internalValue);\n    }\n  };\n  const onClear = () => {\n    setInternalValue('');\n    onSearch('');\n  };\n  return (\n    <div\n      className={[SearchBoxCss.wrapper, size, className].join(' ')}\n      {...props}\n    >\n      {isRecentsearch && <RecentSearch />}\n      <input\n        {...props}\n        className={`${header && SearchBoxCss.HeaderSearchCss} truncate ${SearchBoxCss.InputBox} ${isRecentsearch ? 'pl-8' : 'pl-3'}`}\n        placeholder={placeholder}\n        onChange={handleChange}\n        value={internalValue}\n        onKeyPress={handleKeyPress}\n      />\n      {!internalValue\n        ? <div className={SearchBoxCss.IconBox} onClick={() => serachOnIconClick && searchOnEnter && onSearch(internalValue)}><Icons.Search /></div>\n        : <div className={SearchBoxCss.IconBox} onClick={() => onClear()}><Icons.Close /></div>}\n    </div>\n  );\n};\n\nSearchBox.propTypes = {\n  /**\n   * What background color to use\n   */\n  // backgroundColor: PropTypes.string,\n  /**\n   * How large should the button be?\n   */\n  variant: PropTypes.oneOf(['primary', 'outline']),\n  /**\n   * Shape of button\n   */\n  shape: PropTypes.oneOf(['square', 'rounded']),\n  /**\n   * is Button disabled\n   */\n  disabled: PropTypes.bool,\n  /**\n   * Optional click handler\n   */\n  onClick: PropTypes.func,\n  /**\n   * Additional classname\n   */\n  className: PropTypes.string,\n};\n\nSearchBox.defaultProps = {\n  // backgroundColor: null,\n  onClick: undefined,\n};\n"
  },
  {
    "path": "packages/client/src/components/SearchBox/searchBoxCss.js",
    "content": "export const SearchBoxCss = {\n  wrapper: 'h-full flex items-center justify-center relative',\n  InputBox: 'bg-gray-input border-1 border-gray-70 placeholder-primary text-body-text focus:outline-none focus:border-primary-dark w-full pr-8 rounded-3 h-full text-xs',\n  HeaderSearchCss: 'bg-headerSearch border-none',\n  IconBox: 'w-3 h-3 contain absolute right-5 cursor-pointer',\n  recentcss: 'w-4 h-4 absolute left-4 cursor-pointer',\n};\n"
  },
  {
    "path": "packages/client/src/components/Select/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/jsx-props-no-spreading */\n/* eslint-disable react/jsx-props-no-multi-spaces */\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport SelectBox from 'react-select';\nimport { sortOptions } from '../utils';\nimport {\n  SelectCss, LightSelect, DarkSelect, simlpeSelectCss, SmallDarkSelectCss, SmallSelectCss, MediumSelectCss,\n} from './selectCss';\nimport { Description } from '../Description';\n\n/**\n * This select box is being used from react-select library. For advanced usage check https://react-select.com/home\n */\nconst formatGroupLabel = (data) => (\n  <div className=\"flex justify-between groupSelect py-2 px-1 bg-gray-300\">\n    <span className=\"font-bold text-primary-text\">{data.name}</span>\n    <span className=\"font-bold text-primary-text\">{data.options.length}</span>\n  </div>\n);\nconst Select = React.forwardRef(({\n  label = '',\n  wrapperClass = '',\n  className = '',\n  options = [],\n  value = [],\n  placeholder = 'Select',\n  WrapClassName = '',\n  disabled = false,\n  sortKey = '',\n  isSearchable = true,\n  noOptionsMessage = 'No options found',\n  error = '',\n  wrapperStyle = {},\n  isClearable = true,\n  isMulti = false,\n  onChange = null,\n  valueKey = 'id',\n  labelKey = 'name',\n  isLabel,\n  isDec,\n  desc,\n  simpleSelect,\n  dark = false,\n  sizeSmall,\n  sizeMedium,\n  groupOptions,\n  defaultValue,\n  LeftLabel,\n  labelClassName,\n  htmlDesc,\n  components,\n  ...restProps\n}, ref) => {\n  const isFirstTime = React.useRef(true);\n  const [selectOptions, setSelectOptions] = React.useState(sortKey ? sortOptions(options, sortKey) : options);\n\n  React.useEffect(() => {\n    setSelectOptions(sortKey ? sortOptions(options, sortKey) : options);\n  }, [options]);\n\n  const getValue = React.useCallback(() => {\n    const defaultChecked = options?.filter((option) => !!option.default);\n    if ([undefined, null].includes(value) || (Array.isArray(value) && value.length === 0)) {\n      if (isFirstTime.current) {\n        isFirstTime.current = false;\n        return defaultChecked;\n      }\n    } else {\n      if (isMulti) {\n        return options?.filter((option) => value && value.includes(option[valueKey]));\n      }\n      // eslint-disable-next-line eqeqeq\n      return options.find((option) => option[valueKey] == value);\n    }\n    return null;\n  }, [options, value]);\n\n  const handleChange = (data) => {\n    if (!onChange) return;\n    if (isMulti) {\n      onChange(data?.map((d) => d[valueKey]) || null);\n    } else {\n      onChange([undefined, null].includes(data?.[valueKey]) ? null : data?.[valueKey]);\n    }\n  };\n\n  let groupClass = 'spark-select';\n  if (wrapperClass) {\n    groupClass += ` ${wrapperClass}`;\n  }\n  if (error) {\n    groupClass += ' spark-select-error';\n  }\n  return (\n    <div className={`${groupClass} ${disabled && 'cursor-not-allowed'} ${WrapClassName}`} style={{ ...wrapperStyle }}>\n      {!!(label || desc)\n        && (\n          <div className={`${LeftLabel}`}>\n            {!!label && <label className={`${SelectCss.selectlabel} ${labelClassName}`}>{label}</label>}\n          </div>\n        )}\n      <SelectBox\n        ref={ref}\n        className={className}\n        classNamePrefix=\"react-select\"\n        placeholder={placeholder}\n        options={groupOptions || selectOptions}\n        formatGroupLabel={formatGroupLabel}\n        isSearchable={isSearchable}\n        isDisabled={!!disabled}\n        noOptionsMessage={() => noOptionsMessage}\n        // classNamePrefix={classNamePrefix}\n        isClearable={isClearable}\n        isMulti={isMulti}\n        closeMenuOnSelect={!isMulti}\n        onChange={handleChange}\n        value={getValue()}\n        getOptionLabel={(data) => data[labelKey]}\n        getOptionValue={(data) => data[valueKey]}\n        isOptionDisabled={(option) => option.isdisabled}\n        styles={(dark ? { ...DarkSelect, ...SelectCss, ...sizeSmall && SmallDarkSelectCss }\n          : simpleSelect ? { ...simlpeSelectCss, ...SelectCss }\n            : sizeMedium ? { ...MediumSelectCss, ...SelectCss } : {\n              ...LightSelect, ...SelectCss, ...sizeSmall && SmallSelectCss,\n            })}\n        defaultValue={defaultValue}\n        components={components}\n        {...restProps}\n\n      />\n      {!!desc && <Description className={SelectCss.desc}>{desc}</Description>}\n      {!!htmlDesc\n          && <Description className={SelectCss.desc}><div dir=\"ltr\" dangerouslySetInnerHTML={{ __html: htmlDesc }} /></Description> }\n      {!!error && <span className={SelectCss.erorrClass}>{error}</span>}\n    </div>\n  );\n});\n\nSelect.displayName = 'Select';\n\nexport { Select };\nSelect.propTypes = {\n  /**\n   * Select label\n   */\n  label: PropTypes.string,\n  /**\n   * key in options array to display label\n   */\n  labelKey: PropTypes.string,\n  /**\n   * key in options array to get value\n   */\n  valueKey: PropTypes.string,\n  /**\n   * options for select box\n   */\n  options: PropTypes.arrayOf(\n    PropTypes.shape({\n      icon: PropTypes.string,\n      name: PropTypes.string.isRequired,\n      id: PropTypes.oneOfType([\n        PropTypes.string,\n        PropTypes.number,\n        PropTypes.bool,\n      ]),\n    }),\n  ),\n  /**\n   * Can seelcted option be cleared?\n   */\n  isClearable: PropTypes.bool,\n  /**\n   * Can multiple options be selected?\n   */\n  isMulti: PropTypes.bool,\n  /**\n   * Select box placeholder\n   */\n  placeholder: PropTypes.string,\n  /**\n   * classname prefix to apply existing styles\n   */\n  disabled: PropTypes.bool,\n  /**\n   * can options be searched\n   */\n  isSearchable: PropTypes.bool,\n  /**\n   * Message to display when no options found\n   */\n  noOptionsMessage: PropTypes.string,\n  /**\n   * Helper text to display at bottom of input\n   */\n  error: PropTypes.string,\n  /**\n   * error class\n   */\n  errorClass: PropTypes.string,\n  /**\n   * class which wraps whole component, label and select\n   */\n  wrapperClass: PropTypes.string,\n  /**\n   * class to apply select component\n   */\n  className: PropTypes.string,\n};\n"
  },
  {
    "path": "packages/client/src/components/Select/selectCss.css",
    "content": ""
  },
  {
    "path": "packages/client/src/components/Select/selectCss.js",
    "content": "/* eslint-disable no-nested-ternary */\nexport const SelectCss = {\n  selectlabel: 'mb-1.5 text-primary-text text-sm block w-full leading-5 font-normal',\n  desc: 'mt-1',\n  erorrClass: 'text-error text-sm mt-1 block',\n  selectWrap: 'bg-gray-90 border-1 border-gray-90 p-2 rounded-3 focus:outline-none focus:border-primary-dark',\n  option: (provided, state) => ({\n    ...provided,\n    // eslint-disable-next-line no-nested-ternary\n    backgroundColor: state.isSelected ? 'var(--color-bg-primary) !important' : state.isFocused ? 'var(--color-bg-primary) !important' : 'var(--color-bg-white) !important',\n    borderBottom: '1px solid var(--color-gray-90)',\n    padding: '5px 10px',\n    fontSize: '14px',\n    color: state.isSelected ? '#fff' : state.isFocused ? '#fff' : 'var(--color-text-primary)',\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    opacity: state.isDisabled ? 0.5 : 1,\n    wordBreak: 'break-word',\n  }),\n  menu: (provided) => ({\n    ...provided,\n    backgroundColor: 'transparent',\n    margin: '0',\n    border: '1px solid var(--color-gray-90)',\n    boxShadow: 'var(--box-shadow)',\n  }),\n  input: (provided) => ({\n    ...provided,\n    color: 'text-primary-text',\n  }),\n  placeholder: (provided) => ({\n    ...provided,\n    color: 'var(--color-placeholder-primary)',\n    fontSize: '12px',\n    whiteSpace: 'nowrap',\n    textOverflow: 'ellipsis',\n    overflow: 'hidden',\n    top: 'auto',\n    transform: 'translate(0,0)',\n    // position: 'relative',\n  }),\n  multiValue: (provided) => ({\n    ...provided,\n    backgroundColor: 'var(--color-gray-200)',\n    color: 'var(--color-text-primary)',\n    flexWrap: 'no-wrap',\n  }),\n  multiValueLabel: (provided) => ({\n    ...provided,\n    // backgroundColor:\"var(--color-bg-default-light)\",\n    color: 'var(--color-text-primary)',\n    fontSize: '75%',\n    padding: '1px',\n    paddingLeft: '4px',\n  }),\n  multiValueRemove: (provided) => ({\n    ...provided,\n    backgroundColor: 'transparent !important',\n    color: 'var(--color-text-primary) !important',\n    cursor: 'pointer',\n  }),\n  singleValue: (provided, state) => {\n    const opacity = state.isDisabled ? 0.5 : 1;\n    const transition = 'opacity 300ms';\n    return {\n      ...provided,\n      color: 'var(--color-gray-white)',\n      // marginTop:\"4px\",\n      opacity,\n      transition,\n    };\n  },\n  dropdownIndicator: (provided) => ({\n    ...provided,\n    fill: 'var(--color-gray-white)',\n  }),\n  group: (provided) => ({\n    ...provided,\n    fontSize: '14px',\n    padding: '0 10px',\n  }),\n};\nexport const DarkSelect = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-inputSub)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'var(--color-gray-inputSub)',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: '1px 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    color: 'var(--color-gray-white)',\n    // border:\"none\",\n    border: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-300) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n  }),\n};\nexport const LightSelect = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-input)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'var(--color-gray-input)',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: '1px 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    color: 'var(--color-gray-white)',\n    // border:\"none\",\n    border: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-70) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n  }),\n};\n\nexport const SmallSelectCss = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-input)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'var(--color-gray-input)',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: '0 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    minHeight: '26px',\n    color: 'var(--color-gray-white)',\n    // border:\"none\",\n    border: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-70) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  input: (provided) => ({\n    ...provided,\n    padding: '0 0px',\n    margin: '1px',\n    color: 'text-primary-text',\n  }),\n  indicatorsContainer: (provided) => ({\n    ...provided,\n    height: '26px',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n    padding: '0px 8px',\n  }),\n  singleValue: (provided, state) => {\n    const opacity = state.isDisabled ? 0.5 : 1;\n    const transition = 'opacity 300ms';\n    return {\n      ...provided,\n      color: 'var(--color-gray-white)',\n      fontSize: '12px',\n      // marginTop:\"4px\",\n      opacity,\n      transition,\n    };\n  },\n};\nexport const SmallDarkSelectCss = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-inputSub)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'var(--color-gray-inputSub)',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: '0 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    minHeight: '30px',\n    color: 'var(--color-gray-white)',\n    // border:\"none\",\n    border: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-300) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  input: (provided) => ({\n    ...provided,\n    padding: '1px 0px',\n    color: 'text-primary-text',\n  }),\n  indicatorsContainer: (provided) => ({\n    ...provided,\n    height: '30px',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n    padding: '0px 8px',\n  }),\n  singleValue: (provided, state) => {\n    const opacity = state.isDisabled ? 0.5 : 1;\n    const transition = 'opacity 300ms';\n    return {\n      ...provided,\n      color: 'var(--color-gray-white)',\n      fontSize: '12px',\n      // marginTop:\"4px\",\n      opacity,\n      transition,\n    };\n  },\n};\n\nexport const MediumSelectCss = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-input)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'var(--color-gray-input)',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: '0 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    minHeight: '30px',\n    color: 'var(--color-gray-white)',\n    // border:\"none\",\n    border: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-70) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  input: (provided) => ({\n    ...provided,\n    padding: '0 0px',\n    margin: '1px',\n    color: 'text-primary-text',\n  }),\n  indicatorsContainer: (provided) => ({\n    ...provided,\n    height: '30px',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n    padding: '0px 8px',\n  }),\n  singleValue: (provided, state) => {\n    const opacity = state.isDisabled ? 0.5 : 1;\n    const transition = 'opacity 300ms';\n    return {\n      ...provided,\n      color: 'var(--color-gray-white)',\n      fontSize: '12px',\n      // marginTop:\"4px\",\n      opacity,\n      transition,\n    };\n  },\n};\n\nexport const simlpeSelectCss = {\n  menuList: (provided) => ({\n    ...provided,\n    padding: 0,\n    maxHeight: '150px',\n    borderRadius: '0 0 3px 3px',\n    backgroundColor: 'var(--color-gray-input)',\n    border: 'none',\n  }),\n  control: (provided, state) => ({\n    ...provided,\n    background: 'transparent',\n    opacity: state.isDisabled ? 0.5 : 1,\n    cursor: state.isDisabled ? 'not-allowed' : 'pointer',\n    padding: ' 0',\n    // none of react-select's styles are passed to <Control />\n    width: '100%',\n    display: 'flex',\n    color: 'var(--color-gray-white)',\n    border: 'none',\n    // borderBottom: state.isFocused ? '1px solid var(--color-bg-primary)' : '1px solid var(--color-gray-70) !important',\n    borderRadius: '3px',\n    boxShadow: 'none',\n  }),\n  valueContainer: (provided) => ({\n    ...provided,\n    flexWrap: 'nowrap',\n  }),\n};\n"
  },
  {
    "path": "packages/client/src/components/SelectTree/index.js",
    "content": "import { isEmpty, flatten } from 'lodash';\nimport React from 'react';\nimport DropdownTreeSelect from 'react-dropdown-tree-select';\nimport 'react-dropdown-tree-select/dist/styles.css';\nimport { ORM_TYPE } from '../../constant/Project/applicationStep';\nimport { Description } from '../Description';\nimport { SelectCss } from '../Select/selectCss';\n\n/**\n * mode:multiSelect\nhierarchical\nsimpleSelect\nradioSelect\n */\n\nexport const defaultAttributes = {\n  [ORM_TYPE.MONGOOSE]: {\n    _id: { type: 'ObjectId' },\n    isActive: { type: 'Boolean' },\n    createdAt: { type: 'String' },\n    updatedAt: { type: 'String' },\n    addedBy: { type: 'ObjectId' },\n    updatedBy: { type: 'ObjectId' },\n  },\n  [ORM_TYPE.SEQUELIZE]: {\n    isActive: { type: 'BOOLEAN' },\n    createdAt: { type: 'STRING' },\n    updatedAt: { type: 'STRING' },\n    addedBy: { type: 'STRING' },\n    updatedBy: { type: 'STRING' },\n  },\n};\n\nexport const SelectTree = React.memo(({\n  placeholder = '',\n  disabled,\n  label,\n  data = {},\n  mode = 'multiSelect',\n  labelClass,\n  handleChange = () => {},\n  className = '',\n  WrapClassName = '',\n  defaultValue = [],\n  disabledKey = [], // disable selection for particular key\n  noDataMessage = '',\n  LeftLabel,\n  desc = '',\n  error = '',\n  id,\n  dark,\n  size,\n  onKeyDown,\n  customIconClick = () => {},\n  // icon,\n  customDataJson = {}, // If  data is custom when data syntax are different\n\n}) => {\n  const changeRef = React.useRef({});\n  const nodeConversion = React.useCallback((node) => ({ fullName: node?._parentName ? `${node?._parentName}.${node?.label}` : node?.label, singleName: node?.label }), []);\n  const handleAttributeChange = ({ currentNode, selectedNode }) => {\n    handleChange({\n      allSelectedNode: selectedNode?.map((node) => nodeConversion(node)),\n      currentSelectedNode: nodeConversion(currentNode),\n    });\n  };\n  changeRef.current = {\n    handleAttributeChange,\n    defaultValue,\n    disabledKey,\n  };\n  return (\n    <div className={WrapClassName}>\n      {!!(label || desc)\n        && (\n        <div className={`${LeftLabel}`}>\n          {!!label\n          && (\n          <div className={labelClass}>\n            <label className=\"mb-1.5 text-primary-text text-sm block w-full font-normal leading-5\">{label}</label>\n          </div>\n          )}\n        </div>\n        )}\n      <div className=\"SelectTreeDisable\">\n        <DropDownComponent\n          onKeyDown={onKeyDown}\n          id={id}\n          data={data}\n          changeRef={changeRef}\n          className={`${className} ${dark && 'darkSelect'} ${size === 'small' && 'smallBox'}`}\n          mode={mode}\n          noDataMessage={noDataMessage}\n          placeholder={placeholder}\n          disabled={disabled}\n          customDataJson={customDataJson}\n          clearData={isEmpty(defaultValue)}\n          customIconClick={customIconClick}\n          // icon={icon}\n          // tagLabel=\"address.react\"\n        />\n      </div>\n      {!!desc\n    && <Description className=\"mt-1\">{desc}</Description>}\n      {!!error && <span className={SelectCss.erorrClass}>{error}</span>}\n    </div>\n  );\n});\nSelectTree.displayName = 'SelectTree';\n\n// expanded\nconst DropDownComponent = React.memo(({ // icon,\n  customIconClick, onKeyDown, changeRef, customDataJson, data, className, mode, placeholder, noDataMessage = '', clearData = false, disabled = false, id,\n}) => {\n  const [newData, setData] = React.useState({});\n\n  const recursiveTree = (recursiveData, parent = null) => (Object.keys(recursiveData)?.map((mainKey) => (\n    recursiveData[mainKey]\n   && typeof (recursiveData[mainKey]) === 'object'\n    && {\n      label: mainKey,\n      parent,\n      value: mainKey,\n      isIcon: recursiveData[mainKey]?.isIcon,\n      customKey: recursiveData[mainKey]?.customKey,\n      ...(!isEmpty(changeRef.current?.defaultValue) ? {\n        expanded: flatten(changeRef.current?.defaultValue?.map((expand) => {\n          const parentArray = expand.split('.');\n          parentArray.push(parentArray.slice(0, expand.split('.').lastIndexOf('.')).join('.'));\n          return parentArray;\n        })).includes(parent ? parent + mainKey : mainKey),\n      } : {}),\n      ...(!isEmpty(changeRef.current.defaultValue) ? { isDefaultValue: changeRef.current.defaultValue?.includes(parent ? `${parent}.${mainKey}` : mainKey) } : {}),\n      ...(!isEmpty(changeRef.current.disabledKey) && { disabled: changeRef.current.disabledKey?.includes(parent ? `${parent}.${mainKey}` : mainKey) }),\n      ...(Object.values(recursiveData[mainKey])?.findIndex((value) => typeof (value) === 'object') > -1\n        ? {\n          children: recursiveTree(recursiveData[mainKey], parent ? `${parent}.${mainKey}` : mainKey),\n        } : {}), // If Object key value pair\n      ...(Array.isArray(recursiveData[mainKey]) ? { children: recursiveTree({ ...recursiveData[mainKey]?.[0] }, parent ? `${parent}.${mainKey}` : mainKey) } : {}), // If array key value pair\n    }))).filter((el) => el && el);\n\n  React.useEffect(() => {\n    setData(isEmpty(customDataJson) ? recursiveTree(data) : customDataJson);\n  }, [changeRef.current?.defaultValue, clearData]);\n\n  return (\n    <DropdownTreeSelect\n      onKeyDown={onKeyDown}\n      id={id}\n      onFocus={() => { setData(isEmpty(customDataJson) ? recursiveTree(data) : customDataJson); }}\n      mode={mode}\n      className={`select-tree ${className}`}\n      data={newData}\n      disabled={disabled}\n      texts={{ placeholder, noMatches: noDataMessage }}\n      onChange={changeRef.current.handleAttributeChange}\n      noData={isEmpty(data) && isEmpty(customDataJson)}\n      customIconClick={customIconClick}\n      // icon={icon}\n    />\n  );\n});\nDropDownComponent.displayName = 'DropDownComponent';\n"
  },
  {
    "path": "packages/client/src/components/SelectTree/selectTreeCss.css",
    "content": ".select-tree{\n\n}\n.select-tree .dropdown,\n.select-tree .dropdown-trigger{\n    width: 100%;\n}\n.select-tree.react-dropdown-tree-select .dropdown{\n    display: block;\n}\n.select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger{\n    @apply rounded border-gray-70 bg-gray-input border-1 flex items-center focus:border-primary-dark focus:outline-none;\n    padding: 4.7px 4px;\n    overflow: hidden;\n    width: 100%;\n}\n.select-tree.react-dropdown-tree-select.smallBox .dropdown .dropdown-trigger{\n    padding: 2px 4px;\n}\n.small .select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger{\n    padding: 0 4px;\n}\n.small .tag-item{\n    margin: 2.5px 4px;\n}\n.small .select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger .tag-item input{\n    font-size: 12px;\n}\n.medium .select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger{\n    padding: 1.5px 4px;\n}\n.medium .select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger .tag-item input{\n    font-size: 12px;\n}\n.select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger .tag-item input{\n    @apply bg-transparent border-none placeholder-primary text-sm focus:border-primary-dark;\n}\n.select-tree.react-dropdown-tree-select .dropdown .dropdown-content{\n    @apply w-full bg-white border-1 border-gray-200 rounded-bl rounded-br;\n    /* bg-gray-selectDropdown */\n    z-index: 10;\n    padding: 0;\n}\n.select-tree.react-dropdown-tree-select .dropdown .dropdown-content .no-matches{\n    width: 100%;\n    text-align: center;\n    display: block;\n    padding: 10px;\n    opacity: 0.5;\n}\n.select-tree .tag{\n    padding-right: 1rem;\n}\n.select-tree .tag-list{\n    @apply w-full flex items-center;\n    padding-right: 35px;\n}\n.select-tree .tag-item{\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n.select-tree .tag-item:last-child{\n    display: none;\n}\n.select-tree .tag-item:first-child{\n    display: block;\n}\n.select-tree .dropdown-content ul li{\n    /* @apply p-1; */\n    /* padding: 0.45rem 10px !important; */\n    padding-top: 0;\n    padding-bottom: 0;\n    border-bottom: 1px solid var(--color-gray-90);\n    display: flex;\n    align-items: center;\n    width: 100%;\n}\n.select-tree .dropdown-content ul li label{\n    display: flex;\n    align-items: center;\n    padding: 0.45rem 10px !important;\n    flex-grow: 1;\n}\n.select-tree .dropdown-content ul li .radioBoxWrap{\n    padding-left: 0;\n    margin: 0;\n    margin-right: 5px;\n    width: 14px;\n    height: 14px;\n}\n.select-tree .dropdown-content ul li .radioBoxWrap .spark-radio-inner{\n    width: 14px;\n    height: 14px;\n}\n.select-tree .dropdown-content ul li .checkBoxWrap {\n    position: relative;\n}\n.select-tree .dropdown-content ul li .checkBoxWrap input{\n    position: absolute;\n    left: 0;\n    top: 0;\n    opacity: 0;\n}\n.select-tree .dropdown-content ul li .radioBoxWrap input:checked ~ .spark-radio-inner{\n    background-color: var(--color-bg-primary);\n    border:1px solid var(--color-bg-primary);\n}\n.select-tree .dropdown-content ul li .radioBoxWrap input:checked ~ .spark-radio-inner:after{\n    opacity: 1;\n    transform: scale(0.7);\n}\n.select-tree .dropdown-content ul li.focused .radioBoxWrap input:checked ~ .spark-radio-inner{\n    border:1px solid #fff;\n}\n.select-tree .dropdown-content ul li .checkBoxWrap input:checked ~ .spark-checkbox-inner{\n    background-color: var(--color-bg-primary);\n    border:1px solid var(--color-bg-primary);\n}\n.select-tree .dropdown-content ul li .checkBoxWrap input:checked ~ .spark-checkbox-inner:after{\n    opacity: 1;\n    border: 1px solid #fff;\n    border-top: 0;\n    border-left: 0;\n    transform: rotate(\n45deg\n ) scale(1) translate(-50%,-50%);\n    transition: all .2s cubic-bezier(.12,.4,.29,1.46);\n    left: 3px;\n    width: 0.20rem;\n    height: 0.4rem;\n}\n.select-tree .dropdown-content ul li.focused input:checked ~ .spark-checkbox-inner{\n    border:1px solid #fff;\n}\n.select-tree .dropdown-content ul li .checkBoxWrap .spark-checkbox-inner{\n    width: 14px;\n    height: 14px;\n}\n.select-tree .dropdown-content ul li i{\n    @apply text-primary-text mr-3 focus:outline-none;\n    flex-shrink: 0;\n    padding: 0.45rem 0 0.45rem 10px!important;\n    margin-right: 0;\n}\n.select-tree .dropdown-content ul li label .node-label{\n    @apply text-primary-text text-sm capitalize font-normal;\n}\n.select-tree .dropdown-content ul li label input{\n    @apply mr-1;\n}\n.select-tree .dropdown-content ul li.leaf[aria-level=\"1\"] i{\n    display: none\n}\n.select-tree .node.focused{\n    @apply bg-primary-dark;\n}\n.select-tree .node.focused i,\n.select-tree .node.focused label .node-label{\n    @apply text-defaultWhite;\n}\n.select-tree .tag{\n    @apply bg-gray-200 text-primary-text text-xs px-2 py-0 capitalize flex items-center;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    display: block;\n    position: relative;\n}\n.select-tree .tag-remove{\n    @apply text-primary-text ml-1;\n    position: absolute;\n    right: 6px;\n    top: 0;\n    bottom: 0;\n    margin: auto;\n}\n.select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger.arrow.top:after,\n.dropdown .dropdown-trigger.arrow.bottom:after{\n    @apply absolute right-4 text-primary-text text-xxs;\n    color:var( --color-gray-white) !important;\n}\n.select-tree.react-dropdown-tree-select  .infinite-scroll-component {\n    max-height: 160px;\n}\n.tag-list .tag-item:first-child{\n    display: block !important;\n}\n.tag-list .tag-item:last-child{\n    display: none;\n    width: 100%;\n}\n.tag-list .tag-item:last-child input{\n    width: 100%;\n}\n/* Select tree hide item */\n.selectValue .tag-list .tag-item{\n    display: none !important;\n}\n.selectValue .tag-list .tag-item:last-child{\n    display: block !important;\n}\n.SelectTreeDisable .disabled {\n    opacity: 0.5;\n    cursor: no-drop;\n}\n\n/* dark */\n.darkSelect.select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger{\n    background-color: var(--color-gray-inputSub);\n    border: 1px solid var(--color-gray-300);\n}\n.darkSelect.select-tree.react-dropdown-tree-select .dropdown .dropdown-trigger:focus{\n    border-color: var(--color-bg-primary);\n}\n.darkSelect.select-tree.react-dropdown-tree-select .dropdown .dropdown-content{\n    background-color: var(--color-gray-inputSub);\n}\n"
  },
  {
    "path": "packages/client/src/components/SidebarMenuList/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React, { useState } from 'react';\nimport { MenuItem } from 'react-pro-sidebar';\nimport { Link } from 'react-router-dom';\nimport PropTypes from 'prop-types';\nimport { Icons } from '@dhiwise/icons';\nimport { SidebarMenuListCss } from './sidebarMenuListCss';\n\nexport const SidebarMenuList = React.memo(({\n  title = '',\n  isSubMenu = false,\n  subMenuList = [],\n  subTitle = '',\n  onClick = () => { },\n  mainMenuList = [],\n  titleKey = '',\n  initialSelectedId = '',\n  Icon,\n  IconActive,\n  onIconClick,\n  IconError,\n}) => {\n  const [isMenu, setIsMenu] = useState(false);\n  const menuSelect = () => {\n    setIsMenu(!isMenu);\n  };\n  const Path = window.location.pathname;\n  const [mainMenuId, setMainMenuId] = useState(false);\n\n  const handelMainMenu = React.useCallback((menuSelectedId) => {\n    setMainMenuId(menuSelectedId);\n    onClick(menuSelectedId);\n  }, []);\n\n  React.useEffect(() => {\n    setMainMenuId(initialSelectedId);\n  }, [initialSelectedId]);\n\n  return (\n    <>\n      {/* //TODO:subMenu dynamic set */}\n      {isSubMenu ? (\n        <div className={SidebarMenuListCss.sidebarMenu}>\n          {subTitle && <div className=\"px-3 py-2\">{subTitle}</div>}\n          {subMenuList?.map((d) => (\n            <Link\n              key={d?._id || d.title}\n              className={`${title && 'mx-3'} block`}\n              to={d.link}\n              onClick={onClick}\n            >\n              <MenuItem\n                // key={key}\n                onClick={menuSelect}\n                className={`${SidebarMenuListCss.subMenuList} ${Path === d.link && SidebarMenuListCss.menuActive\n                }`}\n              >\n                <div className=\"flex flex-wrap items-center\">\n                  <div className=\"w-4 h-4 mr-2\">\n                    {Path === d.link ? <Icons.ListMenu color=\"#ffffff\" /> : <Icons.ListMenu />}\n                  </div>\n                  <span\n                    className={`${Path === d.link && 'text-defaultWhite'\n                    } text-primary-text`}\n                  >\n                    {d.Subtitle}\n                  </span>\n                </div>\n              </MenuItem>\n            </Link>\n          ))}\n        </div>\n      ) : (\n\n        mainMenuList?.map((menu) => (\n          <MenuItem\n            key={`menu${menu?._id}`}\n            onClick={() => handelMainMenu(menu?._id)}\n            className={`${SidebarMenuListCss.menuList}  ${mainMenuId === menu._id && menu.isErr ? 'bg-secondary-red border-secondary-red' : ''}  ${mainMenuId === menu._id && SidebarMenuListCss.menuActive}`}\n          >\n            <div className=\"flex items-center justify-between w-full\">\n              <span className={`${menu.isErr ? 'text-secondary-red' : ''} ${mainMenuId === menu._id && 'text-defaultWhite'} text-sm leading-5 truncate text-primary-text`}>\n                {menu[titleKey] ?? '-'}\n              </span>\n              {menu.total\n              && (\n                <span className={`text-sm text-primary-text ${mainMenuId === menu._id && 'text-defaultWhite'}`}>\n                  {menu?.total}\n                </span>\n              )}\n              {Icon && menu.code\n                && <div className=\"mr-2 w-3 h-3\" onClick={() => onIconClick?.(menu)}>{mainMenuId === menu?._id ? IconActive : menu.isErr ? IconError : Icon}</div>}\n            </div>\n          </MenuItem>\n        )))}\n    </>\n  );\n});\n\nSidebarMenuList.propTypes = {\n  /** * link redirect to use */\n  // key: PropTypes.string,\n  /** * Optional click handler */\n  onClick: PropTypes.func,\n  /** * manuclassname be? */\n  title: PropTypes.string,\n  /** * Profile tru false */\n  isSubMenu: PropTypes.bool,\n  /** * icon true false */\n  subTitle: PropTypes.string,\n  /** * Main Menu list of array when isSubMenu false */\n  // eslint-disable-next-line react/forbid-prop-types\n  mainMenuList: PropTypes.array,\n  /** * title key passed key which used to shown in title */\n  titleKey: PropTypes.string,\n  /** * used to pass Initial selected Id */\n  initialSelectedId: PropTypes.string,\n};\nSidebarMenuList.displayName = 'SidebarMenuList';\n"
  },
  {
    "path": "packages/client/src/components/SidebarMenuList/sidebarMenuListCss.js",
    "content": "export const SidebarMenuListCss = {\n  menuList: 'text-primary-text border-b-1 border-gray-100 py-1',\n  menuActive: 'bg-primary-dark text-primary-defaultWhite border-primary-dark',\n  subMenuList: 'text-primary-text w-full',\n  sidebarMenu: 'text-primary-text border-b-1 border-gray-100 py-1',\n  sidebarBottomAction: 'absolute bottom-0 w-full',\n  thumbMenuActive: 'border-primary-dark',\n};\n"
  },
  {
    "path": "packages/client/src/components/Spinner/index.js",
    "content": "import React from 'react';\nimport './spinner.css';\n\nexport function Spinner({ className }) {\n  return (\n    <div className={`dhi-ellipsis ${className}`}>\n      <div />\n      <div />\n      <div />\n      <div />\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/components/Spinner/spinner.css",
    "content": ".dhi-ellipsis {\n  display: block;\n  position: absolute;\n  right: 0px;\n  left:-7px;\n  top: 0;\n  bottom: 0;\n  margin: auto;\n  width: 80px;\n  height: 13px;\n  -webkit-transform: scale(0.7);\n  transform: scale(0.7);\n}\n.dhi-ellipsis div {\n  position: absolute;\n  top: 0px;\n  width: 13px;\n  height: 13px;\n  border-radius: 50%;\n  background: #fff;\n  animation-timing-function: cubic-bezier(0, 1, 1, 0);\n}\n.spinnerMedium{\n  transform: scale(0.6);\n  width: 60px;\n}\n.themeSpinner div{\n  background-color: var(--color-outline-button-text);\n}\n.theme.dhi-ellipsis div{\n  background: var(--color-bg-primary);\n}\n.dhi-ellipsis div:nth-child(1) {\n  left: 8px;\n  animation: dhi-ellipsis1 0.6s infinite;\n}\n.dhi-ellipsis div:nth-child(2) {\n  left: 8px;\n  animation: dhi-ellipsis2 0.6s infinite;\n}\n.dhi-ellipsis div:nth-child(3) {\n  left: 32px;\n  animation: dhi-ellipsis2 0.6s infinite;\n}\n.dhi-ellipsis div:nth-child(4) {\n  left: 56px;\n  animation: dhi-ellipsis3 0.6s infinite;\n}\n.dhi-ellipsis.spinnerMedium div:nth-child(1),\n.dhi-ellipsis.spinnerMedium div:nth-child(2){\n  left: 0;\n}\n.dhi-ellipsis.spinnerMedium div:nth-child(3) {\n  left: 24px;\n}\n.dhi-ellipsis.spinnerMedium div:nth-child(4) {\n  left: 48px;\n}\n@keyframes dhi-ellipsis1 {\n  0% {\n    transform: scale(0);\n  }\n  100% {\n    transform: scale(1);\n  }\n}\n@keyframes dhi-ellipsis3 {\n  0% {\n    transform: scale(1);\n  }\n  100% {\n    transform: scale(0);\n  }\n}\n@keyframes dhi-ellipsis2 {\n  0% {\n    transform: translate(0, 0);\n  }\n  100% {\n    transform: translate(24px, 0);\n  }\n}"
  },
  {
    "path": "packages/client/src/components/StepFooter/index.js",
    "content": "import React from 'react';\nimport ErrorMsg from '../ErrorMsg';\nimport { Button } from '../Button';\n\nexport const StepFooter = ({\n  Back,\n  backClick = () => {},\n  Next,\n  nextClick = () => {},\n  isNextDisable = false,\n  isSaveDisable = false,\n  nextLoading = false,\n  saveText,\n  saveClick = () => {},\n  saveLoading = false,\n  backLoading = false, errorMessage,\n  children,\n  className,\n}) => (\n  <div className={`flex items-center justify-end stepFooter bg-gray-black py-2 px-5 border-t border-gray-100 ${className}`}>\n    {errorMessage && (\n    <div className=\"flex-grow\">\n      <ErrorMsg error={errorMessage} />\n    </div>\n    )}\n    {children}\n    {Back && <Button loading={backLoading} variant=\"outline\" onClick={backClick} className=\"min-w-32\" shape=\"rounded\" size=\"medium\">{Back}</Button>}\n    {saveText && <Button loading={saveLoading} disabled={isSaveDisable} variant=\"primary\" onClick={saveClick} className=\"ml-2 min-w-32\" shape=\"rounded\" size=\"medium\">{saveText}</Button>}\n    {Next && <Button loading={nextLoading} disabled={isNextDisable} variant=\"primary\" onClick={nextClick} className=\"ml-2 min-w-32\" shape=\"rounded\" size=\"medium\">{Next}</Button>}\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/Tag/index.js",
    "content": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Icons } from '@dhiwise/icons';\nimport { TagCss } from './tagCss';\n\nexport const variantConstant = {\n  primary: 'primary',\n  secondary: 'secondary',\n  coolGray: 'coolGray',\n  active: 'active',\n  deactive: 'deactive',\n};\n\nexport const TagGroup = ({\n  spaceNone, titleKey = 'tag', onClick = () => {}, valueKey = '', disabled = false, disabledTag = [], TagList = [], className,\n}) => (\n  <div className={`${spaceNone ? 'mt-0' : 'mt-4'}`}>\n    { [...disabledTag, ...TagList]?.map((t, index) => (\n      <Tag\n        size={t.size}\n        title={t[titleKey]}\n        key={t[titleKey]}\n        variant={t.tagVariant}\n        close={t.close}\n        className={`mr-1 mb-1 ${className} ${(disabled || !!disabledTag?.find((tag) => tag[titleKey] === t[titleKey])) && TagCss.disabledTag} whitespace-nowrap`}\n        onClick={(disabled || !!disabledTag?.find((tag) => tag[titleKey] === t[titleKey])) ? undefined : onClick}\n        value={t[valueKey] || index}\n      />\n    ))}\n  </div>\n);\n\nexport const Tag = ({\n  title, variant, className, size, close, onClick = () => { }, value,\n}) => {\n  const variantClass = `${TagCss[[`tag${variant}`]]}`;\n  const sizeClass = `${TagCss[[`tag${size}`]]}`;\n  return (\n    <div className={[TagCss.tagWrap, sizeClass, className, variantClass].join(' ')} onClick={() => onClick(value)}>\n      {title}\n      {!!close\n      && (\n      <div className=\"w-3 h-3 ml-2\">\n        <Icons.Close />\n      </div>\n      )}\n    </div>\n  );\n};\nTag.propTypes = {\n  /**\n     * How large should the button be?\n     */\n  variant: PropTypes.oneOf(['primary', 'secondary', 'coolGray', 'active', 'deactive', 'ghost']),\n  size: PropTypes.oneOf(['normal', 'small', 'xxs']),\n  /**\n   * Optional click handler\n   */\n  onClick: PropTypes.func,\n};\n\nTag.defaultProps = {\n  variant: 'coolGray',\n  size: 'normal',\n  onClick: undefined,\n};\n"
  },
  {
    "path": "packages/client/src/components/Tag/tagCss.js",
    "content": "export const TagCss = {\n  tagWrap: 'cursor-pointer inline-flex justify-between items-center inline-block rounded-3',\n  tagprimary: 'bg-primary-dark border-1 border-primary-dark text-defaultWhite',\n  tagsecondary: 'border-1 border-gray-70 text-primary-text',\n  tagghost: 'text-lg text-primary-dark cursor-text',\n  tagcoolGray: 'border-1 border-gray-100 text-primary-text',\n  tagactive: 'bg-activebg  text-activetext',\n  tagdeactive: 'bg-deactivebg text-deactivetext',\n  tagnormal: 'py-0.5 px-3 text-xxs font-semibold leading-5',\n  tagsmall: 'px-1 py-0.5 text-xxs leading-4 font-semibold',\n  tagxxs: 'text-xxs leading-3 p-0.5 -right-12',\n  disabledTag: 'opacity-60 cursor-not-allowed',\n};\n"
  },
  {
    "path": "packages/client/src/components/TextArea/index.js",
    "content": "import React, { forwardRef } from 'react';\nimport PropTypes from 'prop-types';\nimport { TextAreaCss } from './textareaCss';\nimport { Description } from '../Description';\nimport { InputCss } from '../Input/inputCss';\n\nexport const TextArea = forwardRef(\n  ({\n    desc, label, maxLength = '', children, textareaClass, className, placeholder, error, ...name\n  }, ref) => (\n    <div className={className}>\n      {!!(label || desc) && (\n      <div className=\"\">\n        {!!label && <label className={TextAreaCss.lebel}>{label}</label>}\n      </div>\n      )}\n      <textarea\n        placeholder={placeholder}\n        className={`${TextAreaCss.textarea} ${textareaClass}`}\n        ref={ref}\n        // eslint-disable-next-line react/jsx-props-no-spreading\n        {...name}\n        maxLength={maxLength}\n      >\n        {children}\n      </textarea>\n      {!!desc && <Description className={TextAreaCss.desc}>{desc}</Description>}\n      {!!error && <span className={InputCss.errorClass}>{error}</span>}\n    </div>\n  ),\n);\nTextArea.propTypes = {\n  label: PropTypes.string,\n  textareaClass: PropTypes.string,\n  className: PropTypes.string,\n  placeholder: PropTypes.string,\n};\nTextArea.displayName = 'TextArea';\n"
  },
  {
    "path": "packages/client/src/components/TextArea/textareaCss.js",
    "content": "export const TextAreaCss = {\n  lebel: 'mb-1.5 text-primary-text text-sm block w-full font-normal leading-5',\n  desc: 'mt-1',\n  textarea: 'block text-primary-text text-sm placeholder-primary font-normal text-sm py-1.5 px-2 w-full focus:border-primary-dark focus:outline-none border-1 border-gray-70 leading-normal rounded bg-gray-input h-32',\n};\n"
  },
  {
    "path": "packages/client/src/components/ToggleBox/index.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\n\nexport const ToggleBox = ({\n  onClick, isPin, isSidebar, ClassName,\n}) => (\n  <div\n    onClick={onClick}\n    className={`w-5 h-5 absolute -top-1 border-1 border-gray-30 rounded-full flex z-10000 bg-gray-200 cursor-pointer ${\n      isPin ? 'leftSet' : '-left-3'\n    } ${ClassName}`}\n  >\n    {isSidebar && (\n      <div className=\"w-2 h-2 m-auto \">\n        <Icons.RightArrow />\n      </div>\n    )}\n    {!isSidebar && (\n      <div className=\"w-2 h-2 m-auto rotate-180 transform\">\n        <Icons.RightArrow />\n      </div>\n    )}\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/components/hooks/index.js",
    "content": "import useBoolean from './useBoolean';\n\nexport {\n  useBoolean,\n};\n"
  },
  {
    "path": "packages/client/src/components/hooks/useBoolean.js",
    "content": "import * as React from 'react';\n\nconst useBoolean = (status) => {\n  const [boolean, setBoolean] = React.useState(status);\n  const setTrue = () => setBoolean(true);\n  const setFalse = () => setBoolean(false);\n  const setToggle = () => {\n    setBoolean((value) => !value);\n  };\n  return [boolean, setTrue, setFalse, setToggle];\n};\nexport default useBoolean;\n"
  },
  {
    "path": "packages/client/src/components/index.js",
    "content": "import { Checkbox } from './Checkbox';\nimport { RadioGroup, Radio } from './Radio/RadioGroup';\nimport { Input } from './Input';\nimport { StringInput } from './Input/StringInput';\nimport { NumberInput } from './Input/NumberInput';\nimport { NegativeInput } from './Input/NegativeInput';\nimport { DrawerClose } from './ReactDrawer/DrawerClose';\nimport { DrawerHead } from './ReactDrawer/DrawerHead';\nimport { DrawerFooter } from './ReactDrawer/DrawerFooter';\nimport { PercentageInput } from './Input/PercentageInput';\nimport { DecimalInput } from './Input/DecimalInput';\nimport { Select } from './Select';\nimport { Button } from './Button';\nimport { CardView } from './CardView';\nimport { Popup } from './Popup';\nimport { MessageNotify } from './MessageNotify';\nimport { ContainerBox } from './ContainerBox';\nimport { LinkTag } from './LinkTag';\nimport { Heading } from './Heading';\nimport { SearchBox } from './SearchBox';\nimport { Description } from './Description';\nimport { TextArea } from './TextArea';\nimport { Tag, TagGroup } from './Tag';\nimport { Spinner } from './Spinner';\nimport { SelectTree } from './SelectTree';\nimport { SidebarMenuList } from './SidebarMenuList';\nimport { ListBoxWrap } from './ListBox/ListBoxWrap';\nimport { MenuBox } from './MenuList';\nimport { ListTitle } from './ListBox/LIstTitle';\nimport { DropdownMenu, MenuItem } from './DropdownMenu';\nimport { IconBox } from './IconBox';\nimport { ConfirmationAlert } from './ConfirmAlert';\nimport { LabelBox } from './Label';\nimport { Loader } from './Loader';\nimport { APIKeyValue } from './APIKeyValue';\nimport { StepFooter } from './StepFooter';\n\nimport { BoxLayout } from './BoxLayout';\nimport { BackButton } from './BackButton';\nimport { Datepicker } from './DatePicker';\nimport NoData from './NoData';\nimport ErrorMsg from './ErrorMsg';\nimport { DeleteIcon } from './IconBox/DeleteIcon';\nimport { CodeEditor } from './CodeEditor';\nimport { Error } from './Error';\nimport { ToggleBox } from './ToggleBox';\n\nInput.String = StringInput;\nInput.Number = NumberInput;\nInput.Negative = NegativeInput;\nInput.Percentage = PercentageInput;\nInput.Decimal = DecimalInput;\nexport {\n  // eslint-disable-next-line max-len\n  DrawerFooter, DrawerHead, DrawerClose, ToggleBox, MenuBox, StepFooter, Error, APIKeyValue, CodeEditor, DeleteIcon, ErrorMsg, Loader, NoData, LabelBox, ConfirmationAlert, IconBox, Datepicker, BackButton, BoxLayout, TagGroup, ListTitle, MenuItem, DropdownMenu, ListBoxWrap, SidebarMenuList, SelectTree, Tag, TextArea, Description, SearchBox, Heading, LinkTag, ContainerBox, MessageNotify, Popup, CardView, Checkbox, RadioGroup, Input, Select, Button, Radio, StringInput, NumberInput, NegativeInput, PercentageInput, Spinner,\n};\n"
  },
  {
    "path": "packages/client/src/components/utils.js",
    "content": "/* eslint-disable no-restricted-syntax */\nimport { useEffect, useRef } from 'react';\n\nexport function classNames(...rest) {\n  const classes = [];\n  const hasOwn = {}.hasOwnProperty;\n  for (let i = 0; i < rest.length; i += 1) {\n    const arg = rest[i];\n\n    if (arg) {\n      const argType = typeof arg;\n\n      if (argType === 'string' || argType === 'number') {\n        classes.push(arg);\n      } else if (Array.isArray(arg)) {\n        if (arg.length) {\n          // eslint-disable-next-line prefer-spread\n          const inner = classNames.apply(null, arg);\n          if (inner) {\n            classes.push(inner);\n          }\n        }\n      } else if (argType === 'object') {\n        if (arg.toString !== Object.prototype.toString) {\n          classes.push(arg.toString());\n        } else {\n          for (const key in arg) {\n            if (hasOwn.call(arg, key) && arg[key]) {\n              classes.push(key);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  return classes.join(' ');\n}\n\nexport function useCombinedRefs(...refs) {\n  const targetRef = useRef();\n\n  useEffect(() => {\n    refs.forEach((ref) => {\n      if (!ref) return;\n\n      if (typeof ref === 'function') {\n        ref(targetRef.current);\n      } else {\n        // eslint-disable-next-line no-param-reassign\n        ref.current = targetRef.current;\n      }\n    });\n  }, [refs]);\n\n  return targetRef;\n}\n\nexport const sortOptions = (array = [], sortKey) => {\n  if (!Array.isArray(array)) return [];\n\n  return array.sort((a, b) => {\n    const left = a[sortKey] ?? Number.MAX_SAFE_INTEGER;\n    const right = b[sortKey] ?? Number.MAX_SAFE_INTEGER;\n    return left - right;\n  });\n};\n\nexport const regex = {\n  string: /^[A-Za-z .]+$/,\n  firstSpace: /^[A-Za-z.]+$/,\n  number: /^-?\\d*\\.?\\d{0,6}$/,\n  decimalFloatDouble: /^(?!0\\d)\\d*(\\.\\d*)?$/,\n  positive: /^\\d*[0-9]\\d*$/,\n  notZeroPositive: /^[1-9][0-9]*$/,\n  negative: /^-\\d*\\.?\\d{0,6}$/,\n  percentage: /(^100(\\.0{1,2})?$)|(^([1-9]([0-9])?|0)(\\.[0-9]{1,2})?$)/,\n  website: /^[-., A-Za-z0-9]+$/,\n  alphanum: /^[a-zA-Z0-9]$/,\n  integer: /^[-+]?\\d*$/,\n  posNegDecimalFloatDouble: /^[-+]?(?!0\\d)\\d*(\\.\\d*)?$/,\n};\n"
  },
  {
    "path": "packages/client/src/config/LazyLoader.js",
    "content": "import Loadable from 'react-loadable';\nimport React from 'react';\n// import Lottie from 'react-lottie';\n// import animationData from './loaderdata.json';\nimport logoLoader from '../assets/images/gif/logo-loader.gif';\n\nexport default function LazyLoader(opts) {\n  return Loadable({\n    loading: () => (\n      <div className=\"min-h-screen flex items-center justify-center\">\n        {/* <Lottie\n          options={defaultOptions}\n          height={200}\n          width={200}\n        /> */}\n        <img width=\"200\" height=\"200\" src={logoLoader} alt=\"loader\" />\n      </div>\n    ),\n    delay: 200,\n    timeout: 10000,\n    ...opts,\n  });\n}\n"
  },
  {
    "path": "packages/client/src/config/Loader.js",
    "content": "import React from 'react';\n\nexport default function Loader() {\n  return (\n    <div className=\"w-full h-full fixed block top-0 left-0 bg-white opacity-75 z-50\">\n      <span className=\"text-green-500 opacity-75 top-1/2 my-0 mx-auto block relative w-0 h-0\">\n        <svg className=\"animate-spin h-5 w-5 mr-3 ...\" viewBox=\"0 0 24 24\" />\n      </span>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/config/Root.js",
    "content": "import React from 'react';\nimport {\n  Route, Switch,\n} from 'react-router-dom';\nimport LazyLoader from './LazyLoader';\n\nconst BuildProcess = LazyLoader({ loader: () => import('../container/common') });\nconst TechnologySetStep = LazyLoader({ loader: () => import('../container/Shared/TechnologySetStep') });\n\nconst PlatFormConfiguration = LazyLoader({ loader: () => import('../container/CRUD/Configuration') });\nconst Modal = LazyLoader({ loader: () => import('../container/CRUD/Modal') });\nconst ModelRoleAccess = LazyLoader({ loader: () => import('../container/RoleAccess') });\nconst Dashboard = LazyLoader({ loader: () => import('../container/Dashboard') });\nconst ModelPermission = LazyLoader({ loader: () => import('../container/CRUD/Permission') });\nconst NodeConstant = LazyLoader({ loader: () => import('../container/Constant') });\nconst Policy = LazyLoader({ loader: () => import('../container/Policy') });\nconst Routes = LazyLoader({ loader: () => import('../container/CRUD/Routes') });\n\nconst NodeEnvironment = LazyLoader({ loader: () => import('../container/EnvironmentVariable') });\nconst Configuration = LazyLoader({ loader: () => import('../container/Configuration') });\n\nconst App = () => {\n  document.getElementsByTagName('html')[0].classList.add('theme-black');\n\n  return (\n    <>\n      <Switch>\n        <Route path=\"/\" component={TechnologySetStep} exact />\n\n        {/* project & application */}\n        <Route path=\"/technology-step\" component={TechnologySetStep} />\n\n        {/* Nodejs */}\n        {/* CRUD */}\n        <Route path=\"/node/crud/platform\" component={PlatFormConfiguration} />\n        <Route path=\"/node/crud/model\" component={Modal} />\n        <Route path=\"/node/crud/permission\" component={ModelPermission} />\n        <Route path=\"/node/crud/routes\" component={Routes} />\n\n        <Route path=\"/node/dashboard\" component={Dashboard} />\n        <Route path=\"/node/role-access\" component={ModelRoleAccess} />\n        <Route path=\"/node/constant\" component={NodeConstant} />\n        <Route path=\"/node/middleware\" component={Policy} />\n\n        <Route path=\"/node/environment-variable\" component={NodeEnvironment} />\n        <Route path=\"/node/configuration\" component={Configuration} />\n\n        <Route path=\"/build-app\" component={BuildProcess} />\n\n        <Route path=\"*\" component={() => (<div>Not Found</div>)} />\n\n      </Switch>\n    </>\n  );\n};\nexport default App;\n"
  },
  {
    "path": "packages/client/src/config/loaderdata.json",
    "content": "{\"v\":\"5.7.4\",\"fr\":30,\"ip\":0,\"op\":37,\"w\":500,\"h\":500,\"nm\":\"DhiWise Logo 2\",\"ddd\":0,\"assets\":[],\"layers\":[{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Layer 2 Outlines\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[174.176,114.662,0],\"ix\":2,\"l\":2},\"a\":{\"a\":0,\"k\":[99.218,83.247,0],\"ix\":1,\"l\":2},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6,\"l\":2}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[-1.743,29.63],[39.353,-3.694],[-0.005,-70.005],[-0.454,-4.448],[-5.457,0.199]],\"o\":[[1.888,-32.105],[-69.698,6.543],[-0.004,4.471],[5.357,0.403],[127.356,-4.641]],\"v\":[[89.83,-20.92],[31.965,-72.053],[-91.713,61.545],[-91.037,74.932],[-74.81,75.548]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[1,0.501999978458,0.051000000449,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":3,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":10,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[99.218,83.248],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":0,\"k\":0,\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"t\":30,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":900,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":2,\"ty\":4,\"nm\":\"Layer 3 Outlines\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[186.164,253.86,0],\"ix\":2,\"l\":2},\"a\":{\"a\":0,\"k\":[108.35,70.099,0],\"ix\":1,\"l\":2},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6,\"l\":2}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[8.362,0],[0,45.544],[-0.121,1.776],[27.647,0.037],[4.64,0.326],[-6.694,-9.985],[-61.479,41.15]],\"o\":[[-45.544,0],[0,-1.741],[-25.657,10.3],[-4.725,0],[3.802,11.404],[41.2,61.462],[-7.979,2.501]],\"v\":[[76.197,25.231],[-6.267,-57.234],[-6.085,-62.598],[-86.786,-47.061],[-100.85,-47.532],[-85.034,-15.303],[100.85,21.449]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[1,0.501999978458,0.051000000449,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":3,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":10,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[108.35,70.099],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":0,\"k\":0,\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"t\":30,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":900,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":3,\"ty\":4,\"nm\":\"Layer 4 Outlines\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[337.993,248.375,0],\"ix\":2,\"l\":2},\"a\":{\"a\":0,\"k\":[102.826,245.18,0],\"ix\":1,\"l\":2},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6,\"l\":2}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[61.017,13.862],[26.965,-12.541],[-1.293,0],[-0.007,-45.539],[0,0],[0,0],[0,0]],\"o\":[[-29.004,-6.563],[1.281,0],[45.539,0],[0,0],[0,0],[0,0],[-0.003,-62.571]],\"v\":[[-8.995,-231.117],[-95.327,-221.897],[-91.46,-221.982],[-8.995,-139.53],[-8.995,237.68],[95.327,237.68],[95.327,-100.442]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0.380000005984,1,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":3,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":10,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[102.826,245.18],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":0,\"k\":0,\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"t\":30,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":900,\"st\":0,\"bm\":0},{\"ddd\":0,\"ind\":4,\"ty\":4,\"nm\":\"Layer 5 Outlines\",\"sr\":1,\"ks\":{\"o\":{\"a\":0,\"k\":100,\"ix\":11},\"r\":{\"a\":0,\"k\":0,\"ix\":10},\"p\":{\"a\":0,\"k\":[184.268,381.999,0],\"ix\":2,\"l\":2},\"a\":{\"a\":0,\"k\":[140.305,126.767,0],\"ix\":1,\"l\":2},\"s\":{\"a\":0,\"k\":[100,100,100],\"ix\":6,\"l\":2}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ix\":1,\"ks\":{\"a\":0,\"k\":{\"i\":[[0.005,35.626],[-3.323,9.059],[15.995,-0.731],[2.175,0],[23.344,17.897],[8.249,12.389],[-55.166,-49.33],[-49.33,55.165],[-4.679,8.203]],\"o\":[[-0.014,-9.65],[-14.707,6.333],[-2.138,0.096],[-29.416,0.042],[-11.816,-9.05],[-49.329,55.166],[55.165,49.329],[6.295,-7.04],[-33.845,-11.122]],\"v\":[[76.076,-41.903],[81.079,-70.189],[34.645,-59.507],[28.193,-59.35],[-53.172,-86.887],[-83.476,-119.268],[-72.908,69.939],[116.298,59.371],[132.805,36.443]],\"c\":true},\"ix\":2},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\",\"hd\":false},{\"ty\":\"st\",\"c\":{\"a\":0,\"k\":[0,0.380000005984,1,1],\"ix\":3},\"o\":{\"a\":0,\"k\":100,\"ix\":4},\"w\":{\"a\":0,\"k\":3,\"ix\":5},\"lc\":1,\"lj\":1,\"ml\":10,\"bm\":0,\"nm\":\"Stroke 1\",\"mn\":\"ADBE Vector Graphic - Stroke\",\"hd\":false},{\"ty\":\"tr\",\"p\":{\"a\":0,\"k\":[140.305,126.767],\"ix\":2},\"a\":{\"a\":0,\"k\":[0,0],\"ix\":1},\"s\":{\"a\":0,\"k\":[100,100],\"ix\":3},\"r\":{\"a\":0,\"k\":0,\"ix\":6},\"o\":{\"a\":0,\"k\":100,\"ix\":7},\"sk\":{\"a\":0,\"k\":0,\"ix\":4},\"sa\":{\"a\":0,\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"cix\":2,\"bm\":0,\"ix\":1,\"mn\":\"ADBE Vector Group\",\"hd\":false},{\"ty\":\"tm\",\"s\":{\"a\":0,\"k\":0,\"ix\":1},\"e\":{\"a\":1,\"k\":[{\"i\":{\"x\":[0.833],\"y\":[0.833]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"t\":0,\"s\":[0]},{\"t\":30,\"s\":[100]}],\"ix\":2},\"o\":{\"a\":0,\"k\":0,\"ix\":3},\"m\":1,\"ix\":2,\"nm\":\"Trim Paths 1\",\"mn\":\"ADBE Vector Filter - Trim\",\"hd\":false}],\"ip\":0,\"op\":900,\"st\":0,\"bm\":0}],\"markers\":[]}"
  },
  {
    "path": "packages/client/src/constant/Nodecrud.js",
    "content": "import { APPLICATION_CODE } from './Project/applicationStep';\n\nexport const RedirectUrl = {\n  [APPLICATION_CODE.nodeExpress]: {\n    platformConfig: {\n      nextUrl: '/node/crud/model',\n      previousUrl: '',\n      backScreenUrl: '/node/dashboard',\n      noDataUrl: '',\n      pageUrl: '/node/crud/platform',\n    },\n    model: {\n      nextUrl: '/node/crud/permission',\n      previousUrl: '/node/crud/platform',\n      backScreenUrl: '/node/dashboard',\n      noDataUrl: '',\n      pageUrl: '/node/crud/model',\n      afterBuildNextUrl: '/node/crud/permission',\n    },\n    permission: {\n      nextUrl: '/node/crud/routes',\n      previousUrl: '/node/crud/model',\n      backScreenUrl: '/node/dashboard',\n      noDataUrl: '',\n      pageUrl: '/node/crud/permission',\n      afterBuildPreviousUrl: '/node/crud/model',\n    },\n    route: {\n      nextUrl: '',\n      previousUrl: '/node/crud/permission',\n      backScreenUrl: '/node/dashboard',\n      noDataUrl: '',\n      pageUrl: '/node/crud/routes',\n    },\n  },\n};\n\nexport const LAYOUT_STEP_MODULE_NAME = {\n  [APPLICATION_CODE.nodeExpress]: 'NodeCRUD',\n};\n"
  },
  {
    "path": "packages/client/src/constant/Project/applicationStep.js",
    "content": "const USER_TYPE = {\n  USER: 1,\n  ADMIN: 2,\n};\nconst PLATFORM_TYPE = {\n  Admin: 'Admin',\n  Device: 'Mobile app',\n  Desktop: 'Desktop',\n  Client: 'Front(Website)',\n};\nconst PLATFORM_VALUE = {\n  Admin: 'admin',\n  Device: 'device',\n  Desktop: 'desktop',\n  Client: 'client',\n};\nexport const PLATFORM_FILTER = [\n  { id: PLATFORM_VALUE.Admin, name: PLATFORM_TYPE.Admin },\n  { id: PLATFORM_VALUE.Device, name: PLATFORM_TYPE.Device },\n  { id: PLATFORM_VALUE.Desktop, name: PLATFORM_TYPE.Desktop },\n  { id: PLATFORM_VALUE.Client, name: PLATFORM_TYPE.Client },\n];\n\nexport const USER_TYPE_FILTER = [\n  { id: USER_TYPE.USER, name: 'User' },\n  { id: USER_TYPE.ADMIN, name: 'Admin' },\n];\n\nconst AUTH_MODEL = {\n  USER: 1,\n};\nconst AUTH_MODEL_FILTER = [\n  { id: AUTH_MODEL.USER, name: 'User' },\n];\n\nexport const ORM_TYPE = {\n  MONGOOSE: 1,\n  SEQUELIZE: 2,\n};\n\nexport const DATABASE_TYPE = {\n  MONGODB: 1,\n  SQL: 2,\n  MYSQL: 3,\n  POSTGRE_SQL: 4,\n};\n\nexport const DATABASE_SELECTION = [\n  { id: ORM_TYPE.MONGOOSE, name: 'Mongoose' },\n  { id: ORM_TYPE.SEQUELIZE, name: 'Sequelize' },\n];\n\nconst DATABASE_SEQUALIZE_SELECTION = [\n  // [ORM_TYPE.MONGOOSE]: [\n  { id: DATABASE_TYPE.MONGODB, name: 'MongoDB' },\n  // ],\n  // [ORM_TYPE.SEQUELIZE]: [\n  { id: DATABASE_TYPE.MYSQL, name: 'MySQL' },\n  { id: DATABASE_TYPE.SQL, name: 'SQL Server' },\n  { id: DATABASE_TYPE.POSTGRE_SQL, name: 'PostgreSQL' },\n  // ],\n];\n\nexport const APP_NAME_PATTERN = {\n  NODE_EXPRESS: /^([0-9 _-]*[a-zA-Z]){3,}[0-9 _-]*$/,\n\n};\n\nexport const APP_NAME_VALIDATION_MESSAGE = {\n  NODE_EXPRESS: {\n    name: {\n      required: 'Please enter application name.',\n      minLength: 'Application name must be of minimum 1 characters.',\n      maxLength: 'Application name must be of maximum 40 characters.',\n      pattern: 'Application name can be alphanumeric and only allows - and _ special character',\n      validate: 'Start your application name with an alphanumeric with a minimum of 3 alphabets, and (-, _) are allowed.',\n      duplicate: 'Please enter different application name.',\n    },\n  },\n};\n\nexport const APPLICATION_CODE = {\n  nodeExpress: 'NODE_EXPRESS',\n};\n\nexport const APPLICATION_STEP = [\n\n  {\n    name: 'configInput[port]',\n    dbKey: 'configInput.port',\n    description: 'Enter application port to connect with your application.',\n    rules: { required: true, min: 1000, max: 65535 },\n    component: 'numberInput',\n    label: 'Application port*',\n    placeholder: 'Enter application port',\n    validationMsg: {\n      required: 'Please enter application port.',\n      min: 'Application port must be of minimum 1000.',\n      max: 'Application port must be of maximum 65535.',\n    },\n    defaultValue: '5000',\n    extraProps: {\n    },\n  },\n  {\n    name: 'stepInput[ormType]',\n    dbKey: 'stepInput.ormType',\n    ishidden: true,\n    description: 'Code will get generated according to the selected ORM.',\n    rules: { required: true },\n    component: 'dropdown',\n    label: 'ORM type*',\n    placeholder: 'Select ORM type',\n    validationMsg: {\n      required: 'Please select ORM type.',\n    },\n    options: DATABASE_SELECTION,\n    extraProps: {\n    },\n  },\n  {\n    name: 'stepInput[databaseType]',\n    dbKey: 'stepInput.databaseType',\n    description: 'Code will get generated according to the selected database type.',\n    rules: { required: true },\n    component: 'dropdown',\n    label: 'Database type*',\n    placeholder: 'Select database type',\n    validationMsg: {\n      required: 'Please select database type.',\n    },\n    options: DATABASE_SEQUALIZE_SELECTION,\n    extraProps: {\n    },\n  },\n  {\n    name: 'configInput[databaseName]',\n    dbKey: 'configInput.databaseName',\n    description: 'Enter name of the database for your application.',\n    rules: {\n      required: true, minLength: 1, maxLength: 50, pattern: /^[a-zA-Z0-9_-]+$/,\n    },\n    component: 'input',\n    label: 'Database name*',\n    placeholder: 'Enter database name',\n    validationMsg: {\n      required: 'Please enter database name.',\n      minLength: 'Database name must be of minimum 1 characters.',\n      maxLength: 'Database name must be of maximum 50 characters.',\n      pattern: 'Database name only includes alphanumeric, -, _.',\n    },\n    defaultValue: '',\n  },\n  {\n    name: 'configInput[isAuthentication]',\n    dbKey: 'configInput.isAuthentication',\n    description: '',\n    ishidden: true,\n    rules: { required: false },\n    component: 'checkbox',\n    label: 'Authentication',\n    placeholder: 'Authentication',\n    validationMsg: {\n      required: '',\n    },\n    defaultValue: true,\n  },\n  {\n    name: 'authModel',\n    dbKey: 'authModel',\n    ishidden: true,\n    description: 'Select authentication model.',\n    rules: { required: true },\n    component: 'dropdown',\n    label: 'Auth model',\n    placeholder: 'Select auth model',\n    validationMsg: {\n      required: 'Please select auth model.',\n    },\n    defaultValue: AUTH_MODEL.USER,\n    options: AUTH_MODEL_FILTER,\n    extraProps: {\n      disabled: true,\n    },\n  },\n\n];\n\nexport const APPLICATION_DASHBOARD = {\n  NODE_EXPRESS: '/node/dashboard',\n};\n\nexport const APPLICATION_PAGE_HEADING = {\n  NODE_EXPRESS: 'node',\n};\n"
  },
  {
    "path": "packages/client/src/constant/applicationConfigConstant.js",
    "content": "import { APPLICATION_CODE, ORM_TYPE } from './Project/applicationStep';\n\nexport const UPLOAD_ATTACHMENT_OPTIONS = [\n  { name: 'local upload', id: 'local' },\n  { name: 'S3 public upload', id: 'S3' },\n  { name: 'S3 private upload', id: 's3_private' },\n\n];\n\nexport const APPLICATION_CONFIG_TABS = {\n  [APPLICATION_CODE.nodeExpress]: ['Authentication', 'Social auth', 'Security', 'Upload attachment', 'Data format config'],\n};\n\nexport const DISABLED_QUERY_PARAMETER_KEYS = ['_id', 'id', 'createdAt', 'updatedAt', 'addedBy', 'updatedBy'];\n\nexport const QUERY_PARAMETER_SUPPORTED_TYPES = {\n  [ORM_TYPE.MONGOOSE]: ['String', 'Number', 'Email'],\n  [ORM_TYPE.SEQUELIZE]: ['STRING', 'CHAR', 'TEXT', 'INTEGER', 'DOUBLE', 'FLOAT', 'DECIMAL'],\n  [ORM_TYPE.ELOQUENT]: ['STRING', 'CHAR', 'TEXT', 'INTEGER', 'DOUBLE', 'FLOAT', 'DECIMAL'],\n};\n\nexport const ATTRIBUTE_FORMAT_DATA_TYPE = {\n  DATE: 'date',\n  BOOLEAN: 'boolean',\n  STRING: 'string',\n};\n\nexport const MODEL_TYPE = {\n  ALL: 1,\n  SINGLE: 2,\n};\n\nexport const DATE_OPTIONS = ['h:mm A', 'h:mm:ss A', 'MM/DD/YYYY', 'MMMM D, YYYY', 'MMMM D, YYYY h:mm A', 'dddd, MMMM D, YYYY h:mm A', 'M/D/YYYY', 'MMM D, YYYY', 'MMM D, YYYY h:mm A', 'ddd, MMM D, YYYY h:mm A'];\n\nexport const STR_OPERATORS = ['space', ',', '|'];\n"
  },
  {
    "path": "packages/client/src/constant/applicationConstant.js",
    "content": "export const CONSTANT_GENERATE_TYPE = {\n  AUTO: 1,\n  MANUAL: 2,\n};\nexport const NODE_DATA_TYPE = {\n  NUMBER: 'number',\n  STRING: 'string',\n  JSON: 'json',\n  ARRAY: 'array',\n};\nexport const NODE_DATA_TYPE_OPTION = [\n  {\n    name: 'String',\n    value: NODE_DATA_TYPE.STRING,\n  },\n  {\n    name: 'Number',\n    value: NODE_DATA_TYPE.NUMBER,\n  },\n  {\n    name: 'Json',\n    value: NODE_DATA_TYPE.JSON,\n  },\n  {\n    name: 'Array of value',\n    value: NODE_DATA_TYPE.ARRAY,\n  },\n];\nexport const nodeConstantName = /^[a-zA-Z_]+[\\w0-9_]*$/;\n"
  },
  {
    "path": "packages/client/src/constant/buildProcessConstant.js",
    "content": "export const CODE_ARCHITECTURE = {\n  MVC: 'MVC',\n  CC: 'Clean Code',\n};\n\nexport const PROCESS_STEP_TYPE = {\n  PENDING: 1,\n  COMPLETE: 2,\n};\n\nexport const BUILD_PROCESS_STATUS = {\n  IN_QUEUE: 1,\n  IN_PROCESS: 2,\n  COMPLETED: 3,\n  FAILED: 4,\n  QUEUE_BUILD_REJECTED: 5,\n};\n\nexport const BUILD_ARCHITECTURE_CODE = {\n  MVC: 'MVC',\n  CC: 'CC',\n};\n"
  },
  {
    "path": "packages/client/src/constant/common.js",
    "content": "export const PLATFORMS = [\n  { name: 'admin', id: 'admin' },\n  { name: 'mobile app', id: 'device' },\n  { name: 'desktop', id: 'desktop' },\n  { name: 'client', id: 'client' },\n];\n\nexport const MAX_INPUT_FIELD_LIMIT = {\n  title: 250, // fileName,functionName\n  description: 500, // description\n  key: 250, // attribute name\n};\n"
  },
  {
    "path": "packages/client/src/constant/envVariable.js",
    "content": "export const ENV = {\n  DEVELOPMENT: 'DEVELOPMENT',\n  QA: 'QA',\n  PRODUCTION: 'PRODUCTION',\n};\n\nexport const TYPE_OPTIONS = (type) => (type ? Object.keys(type).map((x) => ({ id: type[x], name: x })) : []);\n"
  },
  {
    "path": "packages/client/src/constant/fileTypeConstant.js",
    "content": "export const FILE_TYPE_EXTENSIONS = [\n  { id: 'png', name: 'png' },\n  { id: 'jpeg', name: 'jpeg' },\n  { id: 'jpg', name: 'jpg' },\n  { id: 'gif', name: 'gif' },\n  { id: 'pdf', name: 'pdf' },\n  { id: 'doc', name: 'doc' },\n  { id: 'docx', name: 'docx' },\n  { id: 'msword', name: 'msword' },\n  { id: 'vnd.openxmlformats-officedocument.wordprocessingml.document', name: 'vnd.openxmlformats-officedocument.wordprocessingml.document' },\n  { id: 'xls', name: 'xls' },\n  { id: 'xlsx', name: 'xlsx' },\n  { id: 'vnd.ms-excel', name: 'vnd.ms-excel' },\n  { id: 'json', name: 'json' },\n  { id: 'x-msdos-program', name: 'x-msdos-program' },\n  { id: 'x-msdownload', name: 'x-msdownload' },\n  { id: 'exe', name: 'exe' },\n  { id: 'x-ms-dos-executable', name: 'x-ms-dos-executable' },\n];\n\nexport const EXTENSION_TYPE = {\n  DEFAULT: 1, //  unsupported/non clickable file\n  TEXT: 2,\n  IMAGE: 3,\n};\n"
  },
  {
    "path": "packages/client/src/constant/languageHeader.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport { APPLICATION_CODE } from './Project/applicationStep';\n\nexport const languageHeader = {\n  [APPLICATION_CODE.nodeExpress]: [\n    {\n      key: '1',\n      linkSet: 'configuration',\n      link: '/node/configuration',\n      tooltipID: 'configuration',\n      iconActive: <Icons.Configuration color=\"#ffffff\" />,\n      icon: <Icons.Configuration />,\n      tooltip: 'Configuration',\n    },\n    // {\n    //   key: '2',\n    //   linkSet: 'environment-variable',\n    //   link: '/node/environment-variable',\n    //   tooltipID: 'environment-variable',\n    //   iconActive: <Icons.Environment color=\"#ffffff\" />,\n    //   icon: <Icons.Environment />,\n    //   tooltip: 'Environment variable',\n    // },\n    {\n      key: '3',\n      linkSet: 'setting',\n      link: '/node/setting',\n      tooltipID: 'setting',\n      iconActive: <Icons.Setting color=\"#ffffff\" />,\n      icon: <Icons.Setting />,\n      tooltip: 'Setting',\n    },\n\n    {\n      key: '4',\n      linkSet: 'application',\n      link: '/application',\n      tooltipID: 'code',\n      iconActive: <Icons.SourceCode color=\"#ffffff\" />,\n      icon: <Icons.SourceCode />,\n      title: 'Code view',\n      menuClass: 'bg-gray-codeButton',\n    },\n  ],\n};\n"
  },
  {
    "path": "packages/client/src/constant/master.js",
    "content": "import { Input, Select, Checkbox } from '../components';\n\nexport const MASTER_PARENT_CODE = {\n  NOTIFICATION: 'NOTIFICATION',\n  SOCIAL_AUTH: 'SOCIAL_AUTH',\n  ANDROID_SOCIAL_AUTH: 'ANDROID_SOCIAL_AUTH',\n};\n\nexport const COMPONENT_TYPE = {\n  text: Input,\n  number: Input.Number,\n  select: Select,\n  checkbox: Checkbox,\n};\n"
  },
  {
    "path": "packages/client/src/constant/model.js",
    "content": "import pluralize from 'pluralize';\nimport { toLower } from 'lodash';\nimport { APPLICATION_CODE, DATABASE_TYPE } from './Project/applicationStep';\n\nexport const DB_TYPE = {\n  MONGODB: 'MONGODB',\n  SQL: 'SQL',\n  MYSQL: 'MYSQL',\n  POSTRAGSQL: 'POSTRAGSQL',\n};\n\nexport const DB_CONST = {\n  [DATABASE_TYPE.MONGODB]: DB_TYPE.MONGODB,\n  [DATABASE_TYPE.SQL]: DB_TYPE.SQL,\n  [DATABASE_TYPE.MYSQL]: DB_TYPE.MYSQL,\n  [DATABASE_TYPE.POSTGRE_SQL]: DB_TYPE.POSTRAGSQL,\n};\n\nexport const TABS = {\n  SCHEMA_TAB: 0,\n  HOOK_SETUP: 1,\n  INDEXING: 2,\n};\n\nexport const SCHEMA_TAB = {\n  TABLE_VIEW: 0,\n};\n\nexport const HOOK_TAB_TITLE = {\n  [APPLICATION_CODE.nodeExpress]: 'Hook setup',\n};\n\nexport const MODEL_ERROR_TABS = {\n  JSON_ERROR: 'Json error',\n  MODEL_ERROR: 'Model error',\n};\n\nexport const TYPES = {\n  JSON: 'JSON',\n  ARRAY: 'Array',\n  STRING: 'String',\n  NUMBER: 'Number',\n  BOOL: 'Boolean',\n  REF: 'Relationship',\n};\n\nexport const ALL_TABLE_TYPES = {\n  [DB_TYPE.MONGODB]: {\n    STRING: 'String',\n    EMAIL: 'Email',\n    NUMBER: 'Number',\n    BOOL: 'Boolean',\n    ARRAY: 'Array',\n    JSON: 'JSON',\n    MIXED: 'Mixed',\n    DATE: 'Date',\n    BUFFER: 'Buffer',\n    MAP: 'Map',\n    OBJECTID: 'ObjectId',\n    VIRTUAL_RELATION: 'virtualRelation',\n    SINGLELINE: 'SingleLine',\n    MULTILINE: 'MultiLine',\n    URL: 'URL',\n    DECIMAL: 'Decimal',\n    PERCENT: 'Percentage',\n    POINT: 'Point',\n  },\n  [DB_TYPE.POSTRAGSQL]: {\n    STRING: 'STRING',\n    TEXT: 'TEXT',\n    CHAR: 'CHAR',\n    BOOL: 'BOOLEAN',\n    INTEGER: 'INTEGER',\n    BIGINT: 'BIGINT',\n    FLOAT: 'FLOAT',\n    REAL: 'REAL',\n    DOUBLE: 'DOUBLE',\n    DECIMAL: 'DECIMAL',\n    DATE: 'DATE',\n    DATEONLY: 'DATEONLY',\n    UUID: 'UUID',\n    UUIDV4: 'UUIDV4',\n    BLOB: 'BLOB',\n    ENUM: 'ENUM',\n    JSON: 'JSON',\n    JSONB: 'JSONB',\n    ARRAY: 'ARRAY',\n    GEOMETRY: 'GEOMETRY',\n    GEOGRAPHY: 'GEOGRAPHY',\n    RANGE: 'RANGE',\n    TINYSTRING: 'TINYSTRING', // same as string\n    TINYINTEGER: 'TINYINTEGER', // same as integer\n  },\n  [DB_TYPE.MYSQL]: {\n    STRING: 'STRING',\n    TEXT: 'TEXT',\n    CHAR: 'CHAR',\n    BOOL: 'BOOLEAN',\n    INTEGER: 'INTEGER',\n    BIGINT: 'BIGINT',\n    FLOAT: 'FLOAT',\n    REAL: 'REAL',\n    DOUBLE: 'DOUBLE',\n    DECIMAL: 'DECIMAL',\n    DATE: 'DATE',\n    DATEONLY: 'DATEONLY',\n    TIMESTAMP: 'TIMESTAMP',\n    ENUM: 'ENUM',\n    JSON: 'JSON',\n    GEOMETRY: 'GEOMETRY',\n    GEOGRAPHY: 'GEOGRAPHY',\n    TINYSTRING: 'TINYSTRING',\n    TINYINTEGER: 'TINYINTEGER',\n    UnsignedBigInt: 'UnsignedBigInt',\n  },\n  [DB_TYPE.SQL]: {\n    STRING: 'STRING',\n    TEXT: 'TEXT',\n    CHAR: 'CHAR',\n    BOOL: 'BOOLEAN',\n    INTEGER: 'INTEGER',\n    BIGINT: 'BIGINT',\n    FLOAT: 'FLOAT',\n    REAL: 'REAL',\n    DOUBLE: 'DOUBLE',\n    DECIMAL: 'DECIMAL',\n    DATE: 'DATE',\n    DATEONLY: 'DATEONLY',\n    ENUM: 'ENUM',\n    TINYSTRING: 'TINYSTRING',\n    TINYINTEGER: 'TINYINTEGER',\n  },\n};\n\nexport const TABLE_TYPES_NAME = {\n  MONGODB: {\n    EMAIL: 'Email',\n    STRING: 'String',\n    NUMBER: 'Number',\n    BOOL: 'Boolean',\n    ARRAY: 'Array',\n    JSON: 'JSON',\n    MIXED: 'Mixed',\n    DATE: 'Date',\n    BUFFER: 'Buffer',\n    MAP: 'Map',\n    OBJECTID: 'Relationship',\n    SINGLELINE: 'SingleLine',\n    MULTILINE: 'MultiLine',\n    URL: 'URL',\n    DECIMAL: 'Decimal',\n    PERCENT: 'Percentage',\n    VIRTUAL_RELATION: 'Virtual Relationship',\n    POINT: 'Point',\n  },\n  SQL: { // Sequelize db\n    STRING: 'STRING',\n    TEXT: 'TEXT',\n    CHAR: 'CHAR',\n    BOOL: 'BOOLEAN',\n    INTEGER: 'INTEGER',\n    BIGINT: 'BIGINT',\n    FLOAT: 'FLOAT',\n    REAL: 'REAL',\n    DOUBLE: 'DOUBLE',\n    DECIMAL: 'DECIMAL',\n    DATE: 'DATE',\n    DATEONLY: 'DATEONLY',\n    TIMESTAMP: 'TIMESTAMP',\n    UUID: 'UUID',\n    UUIDV4: 'UUIDV4',\n    BLOB: 'BLOB',\n    ENUM: 'ENUM',\n    JSON: 'JSON',\n    JSONB: 'JSONB',\n    ARRAY: 'ARRAY',\n    GEOMETRY: 'GEOMETRY',\n    GEOGRAPHY: 'GEOGRAPHY',\n    RANGE: 'RANGE',\n    TINYSTRING: 'TINYSTRING',\n    TINYINTEGER: 'TINYINTEGER',\n    UnsignedBigInt: 'UnsignedBigInt',\n  },\n};\n\nexport const DEFAULT_OPTIONS = [\n  { name: 'As defined', id: 'AS_DEFINED', sequence: 1 },\n  { name: 'Null', id: 'NULL', sequence: 2 },\n  // { name: 'Current Timestamp', id: 'CUR_TIMESTAMP', sequence: 3 },\n];\n\nexport const KEYS = {\n  minLength: 'minLength',\n  maxLength: 'maxLength',\n  min: 'min',\n  max: 'max',\n  required: 'required',\n  lowercase: 'lowercase',\n  unique: 'unique',\n  filter: 'filter',\n  default: 'default',\n  trim: 'trim',\n  isEnum: 'isEnum',\n  enum: 'enum',\n  match: 'match',\n  isAutoIncrement: 'isAutoIncrement',\n  ref: 'ref',\n  localField: 'localField',\n  foreignField: 'foreignField',\n  comment: 'comment',\n  // sequelize\n  primary: 'primary',\n  tiny: 'tiny',\n  refAttribute: 'refAttribute',\n  relType: 'relType',\n  innerDataType: 'innerDataType',\n  private: 'private',\n};\n\nexport const getAllDisableField = (type, fields, dbType, opt = {}) => {\n  const TABLE_TYPES = ALL_TABLE_TYPES[dbType];\n  const isArrayJson = type === TABLE_TYPES.ARRAY || type === TABLE_TYPES.JSON;\n  let obj = {\n    [KEYS.comment]: isArrayJson || type === TABLE_TYPES.POINT,\n  };\n  if (dbType === DB_TYPE.MONGODB) {\n    // mongoDB\n    if (type === '_id') {\n      // add value false for _id\n      Object.keys(KEYS).forEach((x) => {\n        obj[x] = true;\n      });\n      obj.type = true;\n      obj[KEYS.attr] = false;\n      obj[KEYS.default] = false;\n    } else {\n      const defaultVal = isArrayJson || [TABLE_TYPES.OBJECTID, TABLE_TYPES.VIRTUAL_RELATION, TABLE_TYPES.POINT, TABLE_TYPES.MAP,\n        TABLE_TYPES.BUFFER, TABLE_TYPES.MIXED, TABLE_TYPES.SINGLELINE, TABLE_TYPES.MULTILINE].includes(type);\n      obj = {\n        ...obj,\n        [KEYS.minLength]: type !== TABLE_TYPES.STRING && type !== TABLE_TYPES.SINGLELINE && type !== TABLE_TYPES.MULTILINE,\n        [KEYS.maxLength]: type !== TABLE_TYPES.STRING && type !== TABLE_TYPES.SINGLELINE && type !== TABLE_TYPES.MULTILINE,\n        [KEYS.match]: type !== TABLE_TYPES.STRING,\n        [KEYS.min]: type !== TABLE_TYPES.DECIMAL && type !== TABLE_TYPES.NUMBER && type !== TABLE_TYPES.DATE,\n        [KEYS.max]: type !== TABLE_TYPES.DECIMAL && type !== TABLE_TYPES.NUMBER && type !== TABLE_TYPES.DATE,\n        [KEYS.lowercase]: !(type === TABLE_TYPES.STRING || type === TABLE_TYPES.SINGLELINE || type === TABLE_TYPES.MULTILINE || type === TABLE_TYPES.URL || type === TABLE_TYPES.EMAIL),\n        [KEYS.trim]: !(type === TABLE_TYPES.STRING || type === TABLE_TYPES.SINGLELINE || type === TABLE_TYPES.MULTILINE || type === TABLE_TYPES.URL || type === TABLE_TYPES.EMAIL),\n        // index: type === TABLE_TYPES.VIRTUAL_RELATION || type === TABLE_TYPES.OBJECTID || type === TABLE_TYPES.ARRAY || type === TABLE_TYPES.JSON,\n        [KEYS.filter]: defaultVal,\n        [KEYS.default]: defaultVal,\n        [KEYS.required]: isArrayJson || type === TABLE_TYPES.POINT,\n        [KEYS.unique]: isArrayJson || type === TABLE_TYPES.POINT || type === TABLE_TYPES.BOOL,\n        [KEYS.isAutoIncrement]: type !== TABLE_TYPES.NUMBER,\n        [KEYS.comment]: isArrayJson || type === TABLE_TYPES.POINT,\n        [KEYS.private]: isArrayJson || type === TABLE_TYPES.POINT,\n      };\n    }\n    if (fields?.isAutoIncrement) {\n      [KEYS.isEnum, KEYS.filter, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.min, KEYS.max, KEYS.match].forEach((x) => {\n        obj[x] = true;\n      });\n    }\n    if (opt?.attr === '_id') {\n      // Add default attribute \"_id\" for mongoose\n      Object.keys(KEYS).forEach((x) => {\n        obj[x] = true;\n      });\n      obj.type = true;\n      obj.attr = true;\n    }\n  } else {\n    // manage sequelize DB\n\n    // eslint-disable-next-line no-lonely-if\n    if (opt?.attr === 'id') {\n      // Add default attribute \"id\" for sql\n      Object.keys(KEYS).forEach((x) => {\n        obj[x] = true;\n      });\n      obj.type = true;\n      obj.attr = true;\n    } else {\n      obj = {\n        ...obj,\n        [KEYS.minLength]: ![TABLE_TYPES.TINYSTRING, TABLE_TYPES.STRING, TABLE_TYPES.TEXT, TABLE_TYPES.CHAR].includes(type),\n        [KEYS.maxLength]: ![TABLE_TYPES.TINYSTRING, TABLE_TYPES.STRING, TABLE_TYPES.TEXT, TABLE_TYPES.CHAR].includes(type),\n        [KEYS.isAutoIncrement]: type !== TABLE_TYPES.TINYINTEGER && type !== TABLE_TYPES.INTEGER && type !== TABLE_TYPES.BIGINT && type !== TABLE_TYPES.UnsignedBigInt,\n        [KEYS.unique]: type !== TABLE_TYPES.STRING && type !== TABLE_TYPES.TEXT && type !== TABLE_TYPES.CHAR,\n        [KEYS.primary]: [TABLE_TYPES.BLOB, TABLE_TYPES.ENUM, TABLE_TYPES.JSONB, TABLE_TYPES.JSON,\n          TABLE_TYPES.ARRAY, TABLE_TYPES.GEOGRAPHY, TABLE_TYPES.GEOMETRY, TABLE_TYPES.RANGE].includes(type),\n        [KEYS.required]: [TABLE_TYPES.DATE, TABLE_TYPES.DATEONLY, TABLE_TYPES.TIMESTAMP, TABLE_TYPES.UUID, TABLE_TYPES.UUIDV4,\n          TABLE_TYPES.BLOB, TABLE_TYPES.ENUM, TABLE_TYPES.JSONB, TABLE_TYPES.JSON,\n          TABLE_TYPES.ARRAY, TABLE_TYPES.GEOGRAPHY, TABLE_TYPES.GEOMETRY, TABLE_TYPES.RANGE].includes(type),\n        // [KEYS.tiny]: type !== TABLE_TYPES.BLOB && type !== TABLE_TYPES.TEXT,\n        [KEYS.min]: ![TABLE_TYPES.TINYINTEGER, TABLE_TYPES.INTEGER, TABLE_TYPES.BIGINT, TABLE_TYPES.FLOAT, TABLE_TYPES.DOUBLE,\n          TABLE_TYPES.REAL, TABLE_TYPES.DECIMAL, TABLE_TYPES.UnsignedBigInt].includes(type),\n        [KEYS.max]: ![TABLE_TYPES.TINYINTEGER, TABLE_TYPES.INTEGER, TABLE_TYPES.BIGINT, TABLE_TYPES.FLOAT, TABLE_TYPES.DOUBLE,\n          TABLE_TYPES.REAL, TABLE_TYPES.DECIMAL, TABLE_TYPES.UnsignedBigInt].includes(type),\n        [KEYS.trim]: true,\n        [KEYS.lowercase]: ![TABLE_TYPES.TINYSTRING, TABLE_TYPES.STRING, TABLE_TYPES.TEXT, TABLE_TYPES.CHAR].includes(type),\n        [KEYS.match]: ![TABLE_TYPES.STRING, TABLE_TYPES.TEXT, TABLE_TYPES.CHAR].includes(type),\n        [KEYS.default]: [TABLE_TYPES.UUID, TABLE_TYPES.UUIDV4, TABLE_TYPES.BLOB, TABLE_TYPES.JSON,\n          TABLE_TYPES.JSONB, TABLE_TYPES.ARRAY, TABLE_TYPES.GEOGRAPHY, TABLE_TYPES.GEOMETRY,\n          TABLE_TYPES.RANGE].includes(type),\n        [KEYS.filter]: [TABLE_TYPES.UUID, TABLE_TYPES.UUIDV4, TABLE_TYPES.BLOB, TABLE_TYPES.JSON,\n          TABLE_TYPES.JSONB, TABLE_TYPES.ARRAY, TABLE_TYPES.GEOGRAPHY, TABLE_TYPES.GEOMETRY,\n          TABLE_TYPES.RANGE].includes(type),\n      };\n      if (fields?.isAutoIncrement) {\n        [KEYS.isEnum, KEYS.filter, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.min, KEYS.max, KEYS.match].forEach((x) => {\n          obj[x] = true;\n        });\n      }\n      if (fields?.unique) {\n        obj.default = true;\n        obj.filter = true;\n      }\n\n      if (fields?.default || fields?.filter) {\n        obj.unique = true;\n      }\n    }\n    obj[KEYS.isAutoIncrement] = true;\n  }\n\n  if (fields?.match && !obj[KEYS.match]) {\n    // pattern enable then remove other validation\n    [KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim].forEach((x) => {\n      obj[x] = true;\n    });\n  }\n\n  return obj;\n};\n\nexport const ERROR_MSG = {\n  min: 'Default value must be greater than or equal to Min value',\n  max: 'Default value must be less than or equal to Max value',\n  minLength: 'Default value length must be greater than or equal to MinLength',\n  maxLength: 'Default value length must be less than or equal to MaxLength ',\n  minMax: 'Min value must be less than Max value',\n  minMaxLength: 'MinLength must be less than MaxLength',\n  foreignField: 'Select foreignField',\n  localField: 'Select localField',\n  type: 'Please input valid type',\n  point: 'Please input attribute having type Array',\n  match: 'Please input valid pattern',\n  pointAttr: 'For type point, attribute name must be type',\n  ref: 'Select model for relation',\n  refAttr: 'Select attribute for relation',\n  relType: 'Select type for relation',\n  indexType: 'Please input index data type',\n  indexName: 'Index name already exists',\n  attribute: 'Index contains duplicate attribute.',\n  ttl: 'Please input time in seconds to create TTL.',\n  requiredAttr: 'Please input attribute.',\n  requiredIndexType: 'Please select index type.',\n  requiredSubIndex: 'Please input atleast one attribute and type.',\n  requiredSqlSubIndex: 'Please input atleast one attribute.',\n  attrName: 'Please input valid attribute name',\n  email: 'Please input valid email for attribute having type Email',\n  duplicateAttr: 'Schema contains duplicate attribute.',\n  matchRegex: 'Please input valid default value as per pattern',\n  percentage: 'Please input default value beween 0 to 100',\n  url: 'Please input valid URL',\n};\n\nconst MONGOOSE_TYPES = {\n  SCHEMA_TYPES_OBJ: 'mongoose.schema.types.objectid',\n  TYPES_OBJ: 'mongoose.types.objectid',\n};\n\n// eslint-disable-next-line consistent-return\nexport const getAllParsedType = (type, TABLE_TYPES) => {\n  if (type) {\n    // eslint-disable-next-line no-param-reassign\n    if (toLower(type) === MONGOOSE_TYPES.SCHEMA_TYPES_OBJ || toLower(type) === MONGOOSE_TYPES.TYPES_OBJ) { type = TABLE_TYPES.OBJECTID; }\n    return type && Object.values(TABLE_TYPES).find((t) => toLower(t) === toLower((type)));\n  } return type;\n};\n\nconst SQL_TYPE_KEYS = {\n  [ALL_TABLE_TYPES.POSTRAGSQL.STRING]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.unique, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.match],\n  [ALL_TABLE_TYPES.POSTRAGSQL.TINYSTRING]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.unique, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.lowercase],\n  [ALL_TABLE_TYPES.POSTRAGSQL.TEXT]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.unique, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.match],\n  [ALL_TABLE_TYPES.POSTRAGSQL.CHAR]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.unique, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.match],\n  [ALL_TABLE_TYPES.POSTRAGSQL.BOOL]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default],\n  [ALL_TABLE_TYPES.POSTRAGSQL.INTEGER]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max, KEYS.isAutoIncrement],\n  [ALL_TABLE_TYPES.POSTRAGSQL.TINYINTEGER]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max, KEYS.isAutoIncrement],\n  [ALL_TABLE_TYPES.POSTRAGSQL.BIGINT]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max, KEYS.isAutoIncrement],\n  [ALL_TABLE_TYPES.POSTRAGSQL.FLOAT]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max],\n  [ALL_TABLE_TYPES.POSTRAGSQL.REAL]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max],\n  [ALL_TABLE_TYPES.POSTRAGSQL.DOUBLE]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max],\n  [ALL_TABLE_TYPES.POSTRAGSQL.DECIMAL]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max],\n  [ALL_TABLE_TYPES.POSTRAGSQL.DATE]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.default],\n  [ALL_TABLE_TYPES.POSTRAGSQL.DATEONLY]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.default],\n  [ALL_TABLE_TYPES.POSTRAGSQL.UUID]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary],\n  [ALL_TABLE_TYPES.POSTRAGSQL.UUIDV4]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary],\n  [ALL_TABLE_TYPES.POSTRAGSQL.BLOB]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.required],\n  [ALL_TABLE_TYPES.POSTRAGSQL.ENUM]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.default, KEYS.isEnum, KEYS.enum],\n  [ALL_TABLE_TYPES.POSTRAGSQL.JSONB]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType],\n  [ALL_TABLE_TYPES.POSTRAGSQL.JSON]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType],\n  [ALL_TABLE_TYPES.POSTRAGSQL.ARRAY]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.innerDataType],\n  [ALL_TABLE_TYPES.POSTRAGSQL.GEOMETRY]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType],\n  [ALL_TABLE_TYPES.POSTRAGSQL.GEOGRAPHY]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType],\n  [ALL_TABLE_TYPES.POSTRAGSQL.RANGE]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.innerDataType],\n  [ALL_TABLE_TYPES.MYSQL.TIMESTAMP]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.default],\n  [ALL_TABLE_TYPES.MYSQL.UnsignedBigInt]: [KEYS.private, KEYS.ref, KEYS.refAttribute, KEYS.relType, KEYS.primary, KEYS.required, KEYS.default, KEYS.min, KEYS.max, KEYS.isAutoIncrement],\n};\n\nconst ALL_TYPE_KEYS = {\n  [DB_TYPE.MONGODB]: {\n    [ALL_TABLE_TYPES.MONGODB.EMAIL]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default, KEYS.lowercase, KEYS.trim],\n    [ALL_TABLE_TYPES.MONGODB.STRING]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim, KEYS.match, KEYS.enum, KEYS.isEnum],\n    [ALL_TABLE_TYPES.MONGODB.NUMBER]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default, KEYS.min, KEYS.max, KEYS.enum, KEYS.isEnum, KEYS.isAutoIncrement],\n    [ALL_TABLE_TYPES.MONGODB.BOOL]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default],\n    [ALL_TABLE_TYPES.MONGODB.MIXED]: [KEYS.private, KEYS.required, KEYS.unique],\n    [ALL_TABLE_TYPES.MONGODB.DATE]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default],\n    [ALL_TABLE_TYPES.MONGODB.BUFFER]: [KEYS.private, KEYS.required, KEYS.unique],\n    [ALL_TABLE_TYPES.MONGODB.MAP]: [KEYS.private, KEYS.required, KEYS.unique],\n    [ALL_TABLE_TYPES.MONGODB.OBJECTID]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.ref],\n    [TYPES.REF]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.ref], // ref and objectid are same\n    [ALL_TABLE_TYPES.MONGODB.SINGLELINE]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim],\n    [ALL_TABLE_TYPES.MONGODB.MULTILINE]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim],\n    [ALL_TABLE_TYPES.MONGODB.URL]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default, KEYS.lowercase, KEYS.trim],\n    [ALL_TABLE_TYPES.MONGODB.DECIMAL]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default, KEYS.min, KEYS.max],\n    [ALL_TABLE_TYPES.MONGODB.PERCENT]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.default],\n    [ALL_TABLE_TYPES.MONGODB.VIRTUAL_RELATION]: [KEYS.private, KEYS.required, KEYS.unique, KEYS.ref, KEYS.localField, KEYS.foreignField],\n    [ALL_TABLE_TYPES.MONGODB.POINT]: [],\n  },\n  [DB_TYPE.POSTRAGSQL]: SQL_TYPE_KEYS,\n  [DB_TYPE.MYSQL]: SQL_TYPE_KEYS,\n  [DB_TYPE.SQL]: SQL_TYPE_KEYS,\n};\n\nexport const RELATION_TYPE = {\n  HAS_ONE: 1,\n  HAS_MANY: 2,\n};\n\nexport const SEQUELIZE_RELATION_TYPE = [{ id: 1, name: 'hasOne' }, { id: 2, name: 'hasMany' }];\n\n// model-hooks\nexport const HOOKS = {\n  TYPE: {\n    PRE: 'pre',\n    POST: 'post',\n  },\n  OPERATIONS: {\n    PRE: {\n      SAVE: 'save',\n      REMOVE: 'remove',\n      VALIDATE: 'validate',\n      FIND: 'find',\n      INIT: 'init',\n      UPDATEONE: 'updateOne',\n      AGGREGATE: 'aggregate',\n    },\n    POST: {\n      SAVE: 'save',\n      REMOVE: 'remove',\n      VALIDATE: 'validate',\n      FIND: 'find',\n      UPDATE: 'update',\n      INIT: 'init',\n    },\n  },\n};\n\nexport const nodeHooksData = () => {\n  function getData(arr, type) {\n    return Object.keys(arr).map((x) => ({ id: `${type}-${arr[x]}`, name: `${type}-${arr[x]}` }));\n  }\n  const preHooks = getData(HOOKS.OPERATIONS.PRE, HOOKS.TYPE.PRE);\n  const postHooks = getData(HOOKS.OPERATIONS.PRE, HOOKS.TYPE.POST);\n  return preHooks.concat(postHooks);\n};\n\nexport const getHookData = () => {\n  const hooksData = nodeHooksData();\n  return hooksData;\n};\n\nexport const DEFAULT_VALUES = {\n  attr: '',\n  type: '',\n  isEnum: false,\n  filter: '',\n  default: '',\n  min: '',\n  minLength: '',\n  max: '',\n  maxLength: '',\n  match: '',\n  lowercase: false,\n  trim: false,\n  required: false,\n  unique: false,\n  isAutoIncrement: false,\n  // tiny: false,\n  innerDataType: '',\n  primary: false,\n  private: false,\n  refAttribute: '',\n  relType: RELATION_TYPE.HAS_MANY,\n  ref: '',\n  enum: null,\n};\n\nexport const MONGO_TOTAL_FIELDS = 14;\nexport const SQL_TOTAL_FIELDS = 15;\nexport const SQL_FIELD_SEQ = {\n  attr: 1,\n  type: 2,\n  innerDataType: 3, // same col\n  isEnum: 3, // same col\n  filter: 4,\n  default: 5,\n  relation: 6,\n  private: 7,\n  primary: 8,\n  // tiny: 9,\n  required: 10,\n  unique: 11,\n  isAutoIncrement: 12,\n  minimum: 13,\n  maximum: 14,\n  lowercase: 15,\n  match: 16,\n};\n\nexport const ALL_FIELD_SEQ = {\n  [DB_TYPE.MONGODB]: {\n    attr: 1,\n    type: 2,\n    localField: 3,\n    subAttr: 4, // same seq as conditionally exists in same column\n    isEnum: 4, // same seq as conditionally exists in same column\n    relation: 4, // same seq as conditionally exists in same column\n    filter: 5,\n    default: 6,\n    private: 7,\n    required: 8,\n    unique: 9,\n    isAutoIncrement: 10,\n    minimum: 11,\n    maximum: 12,\n    lowercase: 13,\n    trim: 14,\n    match: 15,\n  },\n  [DB_TYPE.POSTRAGSQL]: SQL_FIELD_SEQ,\n  [DB_TYPE.SQL]: SQL_FIELD_SEQ,\n  [DB_TYPE.MYSQL]: SQL_FIELD_SEQ,\n};\n\nexport const getFieldPosition = (index, dbType) => {\n  const FIELD_SEQ = ALL_FIELD_SEQ[dbType];\n  const TOTAL_FIELDS = dbType === DB_TYPE.MONGODB ? MONGO_TOTAL_FIELDS : SQL_TOTAL_FIELDS;\n\n  const focIndex = index * TOTAL_FIELDS;\n  const FiledPosition = {\n    attr: focIndex + FIELD_SEQ.attr,\n    type: focIndex + FIELD_SEQ.type,\n    localField: focIndex + FIELD_SEQ.localField,\n    subAttr: focIndex + FIELD_SEQ.subAttr,\n    isEnum: focIndex + FIELD_SEQ.isEnum,\n    relation: focIndex + FIELD_SEQ.relation,\n    innerDataType: focIndex + FIELD_SEQ.innerDataType,\n    filter: focIndex + FIELD_SEQ.filter,\n    default: focIndex + FIELD_SEQ.default,\n    primary: focIndex + FIELD_SEQ.primary,\n    private: focIndex + FIELD_SEQ.private,\n    // tiny: focIndex + FIELD_SEQ.tiny,\n    required: focIndex + FIELD_SEQ.required,\n    unique: focIndex + FIELD_SEQ.unique,\n    isAutoIncrement: focIndex + FIELD_SEQ.isAutoIncrement,\n    minimum: focIndex + FIELD_SEQ.minimum,\n    maximum: focIndex + FIELD_SEQ.maximum,\n    lowercase: focIndex + FIELD_SEQ.lowercase,\n    trim: focIndex + FIELD_SEQ.trim,\n    match: focIndex + FIELD_SEQ.match,\n  };\n  return { FiledPosition, FIELD_SEQ, TOTAL_FIELDS };\n};\n\nexport const SUB_TOTAL_FIELDS = 14;\n\nexport const SUB_FIELD_SEQ = {\n  attr: 1,\n  type: 2,\n  localField: 3,\n  isEnum: 4, // same seq as conditionally exists in same column\n  relation: 4, // same seq as conditionally exists in same column\n  filter: 5,\n  default: 6,\n  required: 7,\n  unique: 8,\n  isAutoIncrement: 9,\n  minimum: 10,\n  maximum: 11,\n  lowercase: 12,\n  trim: 13,\n  match: 14,\n};\n\nexport const getSubFieldPosition = (index) => {\n  const focIndex = index * SUB_TOTAL_FIELDS;\n  const FiledPosition = {\n    attr: focIndex + SUB_FIELD_SEQ.attr,\n    type: focIndex + SUB_FIELD_SEQ.type,\n    localField: focIndex + SUB_FIELD_SEQ.localField,\n    isEnum: focIndex + SUB_FIELD_SEQ.isEnum,\n    relation: focIndex + SUB_FIELD_SEQ.relation,\n    filter: focIndex + SUB_FIELD_SEQ.filter,\n    default: focIndex + SUB_FIELD_SEQ.default,\n    required: focIndex + SUB_FIELD_SEQ.required,\n    unique: focIndex + SUB_FIELD_SEQ.unique,\n    isAutoIncrement: focIndex + SUB_FIELD_SEQ.isAutoIncrement,\n    minimum: focIndex + SUB_FIELD_SEQ.minimum,\n    maximum: focIndex + SUB_FIELD_SEQ.maximum,\n    lowercase: focIndex + SUB_FIELD_SEQ.lowercase,\n    trim: focIndex + SUB_FIELD_SEQ.trim,\n    match: focIndex + SUB_FIELD_SEQ.match,\n  };\n  return { FiledPosition };\n};\n\nexport const DEFAULT_TYPE_LENGTH = {\n  STRING: 255,\n  CHAR: 255,\n};\n\n// functions by dbType\nexport const util = {\n  getTableTypes: (dbType) => ALL_TABLE_TYPES[dbType],\n  getTypeKeys: (dbType) => ALL_TYPE_KEYS[dbType],\n  getTypeOptions: (dbType) => (ALL_TABLE_TYPES?.[dbType]\n    ? Object.keys(ALL_TABLE_TYPES[dbType])\n      .filter((x) => ((x !== ALL_TABLE_TYPES[dbType].TIMESTAMP && x !== ALL_TABLE_TYPES[dbType].UnsignedBigInt)))\n      .map((x, i) => ({\n        id: ALL_TABLE_TYPES[dbType][x],\n        name: dbType === DB_TYPE.MONGODB\n          ? TABLE_TYPES_NAME.MONGODB[x] : TABLE_TYPES_NAME.SQL[x],\n        sequence: i + 1,\n      })) : []),\n};\nexport const getParsedType = (type, dbType) => getAllParsedType(type, ALL_TABLE_TYPES[dbType]);\n\nconst EXCLUDE_PARSE_KEYS = ['type'];\n\nexport const parsedKeys = (obj, dbType) => {\n  if (!obj) return;\n  const TYPE_KEYS = util.getTypeKeys(dbType);\n\n  let isSub = false;\n  const json = { ...obj };\n  Object.keys(json).map((k) => {\n    if (EXCLUDE_PARSE_KEYS.includes(k)) return k;\n    if (k === 'minlength') {\n      // eslint-disable-next-line no-param-reassign\n      k = KEYS.minLength;\n      json[k] = json.minlength;\n      delete json.minlength;\n    }\n    if (k === 'maxlength') {\n      // eslint-disable-next-line no-param-reassign\n      k = KEYS.maxLength;\n      json[k] = json.maxlength;\n      delete json.maxlength;\n    }\n    if (json.type && TYPE_KEYS[json.type]) {\n      if (!TYPE_KEYS[json.type].includes(k)) {\n        if (!isSub && !['description', 'attr', 'key'].includes(k)) { isSub = true; }\n        delete json[k];\n      }\n    }\n    return k;\n  });\n  // eslint-disable-next-line consistent-return\n  return { json, isSub };\n};\n\nexport const getParsedKeys = (obj, dbType) => (obj ? parsedKeys(obj, dbType).json : null);\nexport const getDisableField = (type, fields, dbType, opt) => getAllDisableField(type, fields, dbType, opt);\nexport const isNumberType = (type, TABLE_TYPES) => [TABLE_TYPES.NUMBER, TABLE_TYPES.TINYINTEGER, TABLE_TYPES.INTEGER, TABLE_TYPES.TINYINTEGER, TABLE_TYPES.BIGINT,\n  TABLE_TYPES.FLOAT, TABLE_TYPES.REAL, TABLE_TYPES.DECIMAL, TABLE_TYPES.DOUBLE, TABLE_TYPES.UnsignedBigInt].includes(type);\n\nexport const ModelPanel = {\n  CUSTOM: { name: 'Custom', tabIndex: 0 },\n  LIBRARY: { name: 'Library', tabIndex: 1 },\n};\n\nexport const getSQLHookTemplate = (operation) => {\n  if (!operation) return '';\n  let hookName = '';\n  switch (operation) {\n    case 'save':\n      hookName = 'Create';\n      break;\n    case 'remove':\n      hookName = 'Destroy';\n      break;\n    case 'validate':\n      hookName = 'Validate';\n      break;\n    case 'find':\n      hookName = 'Find';\n      break;\n    case 'init':\n      hookName = 'Init';\n      break;\n    case 'updateOne':\n      hookName = 'Update';\n      break;\n    case 'aggregate':\n      hookName = 'Query';\n      break;\n    default: hookName = '';\n  }\n  return hookName;\n};\n\nexport const SQL_MODEL_NAME_LENGTH = 64; // 64 characters for MySQL database\nexport const MODEL_NAME_LENGTH = 127; // 127 bytes\nexport const MONGODB_INDEX_NAME_LENGTH = 127;\n\n// Don't change formatting of below function\nexport const getHookHeader = ({\n  dbType, type, operation, modelName, currentApplicationCode,\n}) => {\n  const startLine = '/*Method start*/';\n  const endLine = '/*You can write business logic*/';\n\n  if (currentApplicationCode === APPLICATION_CODE.nodeExpress) {\n    if (dbType === DB_TYPE.MONGODB) {\n      return `${startLine}\nschema.${type}('${operation}', async function(${type === 'post' ? 'docs, ' : ''}next) {\n\n${endLine}`;\n    }\n    const op = getSQLHookTemplate(operation);\n    return `${startLine}\n${type === HOOKS.TYPE.PRE ? 'before' : 'after'}${op}: [\nasync function (${modelName}, options){\n\n${endLine}`;\n  }\n\n  return `${endLine}`;\n};\n\n// Don't change formatting of below function\nexport const getHookFooter = ({ dbType, currentApplicationCode }) => {\n  const startLine = '/*Method close*/';\n  if (currentApplicationCode === APPLICATION_CODE.nodeExpress) {\n    if (dbType === DB_TYPE.MONGODB) {\n      return `${startLine}\n    next();\n})`;\n    }\n    return `${startLine}\n    },\n]`;\n  }\n\n  return `${startLine}\n}`;\n};\nexport const mongoDbModalName = /^[a-zA-Z_]+[\\w0-9_]*$/;\n\nexport const pluralizeTableName = (modelName = '') => (pluralize(modelName));\n"
  },
  {
    "path": "packages/client/src/constant/modelIndexing.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { cloneDeep } from 'lodash';\nimport { DB_TYPE } from './model';\n\nexport const SQL_INDEX = {\n  ORDER_TYPE_OPTIONS: [\n    { name: 'ASC', id: 'ASC', sequence: 1 },\n    { name: 'DESC', id: 'DESC', sequence: 2 },\n  ],\n  TYPE: {\n    BTREE: 'BTREE',\n    GIN: 'GIN',\n    PARTIAL: 'PARTIAL',\n    UNIQUE: 'UNIQUE',\n  },\n  COLLATE: ['ar_AE', 'ar_BH', 'ar_DZ', 'ar_EG', 'ar_IN', 'ar_IQ', 'ar_JO', 'ar_KW', 'ar_LB',\n    'ar_LY', 'ar_MA', 'ar_OM', 'ar_QA', 'ar_SA', 'ar_SD', 'ar_SY', 'ar_TN', 'ar_YE', 'be_BY',\n    'bg_BG', 'ca_ES', 'cs_CZ', 'da_DK', 'de_AT', 'de_BE', 'de_CH', 'de_DE', 'de_LU', 'el_GR',\n    'en_AU', 'en_CA', 'en_GB', 'en_IN', 'en_NZ', 'en_PH', 'en_US', 'en_ZA', 'en_ZW', 'es_AR',\n    'es_BO', 'es_CL', 'es_CO', 'es_CR', 'es_DO', 'es_EC', 'es_ES', 'es_GT', 'es_HN', 'es_MX',\n    'es_NI', 'es_PA', 'es_PE', 'es_PR', 'es_PY', 'es_SV', 'es_US', 'es_UY', 'es_VE', 'et_EE',\n    'eu_ES', 'fi_FI', 'fo_FO', 'fr_BE', 'fr_CA', 'fr_CH', 'fr_FR', 'fr_LU', 'gl_ES', 'gu_IN',\n    'he_IL', 'hi_IN', 'hr_HR', 'hu_HU', 'id_ID', 'is_IS', 'it_CH', 'it_IT', 'ja_JP', 'ko_KR',\n    'lt_LT', 'lv_LV', 'mk_MK', 'mn_MN', 'ms_MY', 'nb_NO', 'nl_BE', 'nl_NL', 'no_NO', 'pl_PL',\n    'pt_BR', 'pt_PT', 'rm_CH', 'ro_RO', 'ru_RU', 'ru_UA', 'sk_SK', 'sl_SI', 'sq_AL', 'sr_RS',\n    'sv_FI', 'sv_SE', 'ta_IN', 'te_IN', 'th_TH', 'tr_TR', 'uk_UA', 'ur_PK', 'vi_VN', 'zh_CN',\n    'zh_HK', 'zh_TW'],\n  GIN_OPERATOR_OPTIONS: ['jsonb_path_ops'],\n  ASSIGNMENT_OPERATOR_OPTIONS: ['in', 'nin', 'ne', '<', '>', '>=', '<=', 'eq'],\n  FIELD_SEQ: {\n    isExpanded: 1,\n    name: 2,\n    indexType: 3,\n    fields: 4,\n  },\n  SUB_FIELD_SEQ: {\n    attribute: 1,\n    order: 2,\n    operator: 2,\n    value: 3,\n    length: 3,\n  },\n  TOTAL_FIELDS: 4, // total columns\n  SUB_TOTAL_FIELDS: 3, // total columns\n  DEFAULT: {\n    SUB_OBJ: {\n      attribute: '',\n      // collate: '', commented as discussed with Avina\n      order: '',\n      length: undefined,\n      operator: '',\n      value: '',\n    },\n    ROW_OBJ: {\n      isExpanded: false,\n      name: '',\n      indexType: '',\n      fields: [],\n      // operator: '', this will be managed in sub-row\n      indexFields: [],\n    },\n  },\n};\n\nexport const MONGO_INDEX = {\n  FIELD_SEQ: {\n    name: 1,\n    ttl: 2,\n    expireAfterSeconds: 3,\n    unique: 4,\n  },\n  SUB_FIELD_SEQ: {\n    attribute: 1,\n    type: 2,\n  },\n  TOTAL_FIELDS: 4, // total columns\n  SUB_TOTAL_FIELDS: 2, // total columns\n  DEFAULT: {\n    ROW_OBJ: {\n      isExpanded: false,\n      name: '',\n      ttl: '',\n      expireAfterSeconds: '',\n      indexFields: [],\n    },\n    SUB_OBJ: {\n      attribute: '',\n      indexType: '',\n    },\n  },\n  MAX_SUB_ROWS_ALLOWED: 32,\n};\n\nexport const SQL_TYPE_OPTIONS = [\n  { name: SQL_INDEX.TYPE.BTREE, id: SQL_INDEX.TYPE.BTREE },\n  // { name: 'GIN index', id: SQL_INDEX.TYPE.GIN },\n  { name: SQL_INDEX.TYPE.PARTIAL, id: SQL_INDEX.TYPE.PARTIAL },\n  { name: SQL_INDEX.TYPE.UNIQUE, id: SQL_INDEX.TYPE.UNIQUE },\n];\n\nexport const MONGO_TYPE_OPTIONS = [\n  { name: 'Ascending', id: 1, sequence: 1 },\n  { name: 'Descending', id: -1, sequence: 2 },\n  { name: '2dSphere', id: '2dsphere', sequence: 3 },\n];\n\nexport const getTypeOptions = (constName) => Object.keys(constName).map(\n  (x) => ({ id: constName[x], name: constName[x] }),\n);\n\nexport const getCollateOpts = () => SQL_INDEX.COLLATE.map((x) => ({ id: x, name: x }));\nexport const getOperatorOpts = () => SQL_INDEX.GIN_OPERATOR_OPTIONS.map((x) => ({ id: x, name: x }));\nexport const getAssignOperatorOpts = () => SQL_INDEX.ASSIGNMENT_OPERATOR_OPTIONS.map((x) => ({ id: x, name: x }));\nexport const checkDuplicate = (arr) => arr.some((x) => x && arr.indexOf(x) !== arr.lastIndexOf(x));\nexport const findDuplicate = (arr) => arr.find((x) => arr.indexOf(x) !== arr.lastIndexOf(x));\nexport const getSubFieldPosition = (index, dbType) => {\n  const { SUB_FIELD_SEQ, SUB_TOTAL_FIELDS } = dbType === DB_TYPE.MONGODB ? MONGO_INDEX : SQL_INDEX;\n  const focIndex = index * SUB_TOTAL_FIELDS;\n  const FiledPosition = {\n    attribute: focIndex + SUB_FIELD_SEQ.attribute,\n    order: focIndex + SUB_FIELD_SEQ.order,\n    operator: focIndex + SUB_FIELD_SEQ.operator,\n    value: focIndex + SUB_FIELD_SEQ.value,\n    length: focIndex + SUB_FIELD_SEQ.length,\n    type: focIndex + SUB_FIELD_SEQ.type,\n  };\n  return { FiledPosition };\n};\nexport const getFieldPosition = (index, isSub, dbType) => {\n  if (isSub) return getSubFieldPosition(index, dbType);\n  const { FIELD_SEQ, TOTAL_FIELDS } = dbType === DB_TYPE.MONGODB ? MONGO_INDEX : SQL_INDEX;\n  const focIndex = index * TOTAL_FIELDS;\n  const FiledPosition = {\n    name: focIndex + FIELD_SEQ.name,\n    indexType: focIndex + FIELD_SEQ.indexType,\n    fields: focIndex + FIELD_SEQ.fields,\n    ttl: focIndex + FIELD_SEQ.ttl, // mongo\n    expireAfterSeconds: focIndex + FIELD_SEQ.expireAfterSeconds,\n    unique: focIndex + FIELD_SEQ.unique,\n  };\n  return { FiledPosition };\n};\n\nexport const prepareIndexing = ({ modelIndexes, dbType }) => {\n  if (modelIndexes?.length > 0) {\n    let temp = cloneDeep(modelIndexes);\n\n    if (dbType === DB_TYPE.MONGODB) {\n      // mongodb\n      temp = temp.map((x) => {\n        const tempFields = [];\n        const obj = {\n          ...x,\n          ...x.options,\n          ttl: !!x.options?.expireAfterSeconds,\n          isExist: true,\n          isExpanded: false,\n        };\n        delete obj.options;\n        if (x?.indexFields && Object.entries(x.indexFields)?.length > 0) {\n          Object.keys(x.indexFields).forEach((f) => {\n            tempFields.push({\n              attribute: f,\n              type: x.indexFields[f],\n              isExist: true,\n            });\n          });\n        }\n        obj.indexFields = tempFields;\n        return obj;\n      });\n    } else {\n      // sql\n      temp = temp.map((x) => {\n        if (x.isParserRequired && x?.name === 'PRIMARY') {\n        // old data script\n          const newIndexFields = [];\n          if (x.indexFields && Object.entries?.(x.indexFields)?.length > 0) {\n            Object.keys(x.indexFields).forEach((y) => {\n              newIndexFields.push({\n                attribute: y,\n                collate: 'en_US',\n                length: 1,\n                order: 'ASC',\n              });\n            });\n          }\n          return {\n            ...x,\n            isDefault: true,\n            indexType: SQL_INDEX.TYPE.BTREE,\n            indexFields: newIndexFields,\n            isExist: true,\n            isExpanded: false,\n          };\n        }\n        if (x?.indexFields?.length > 0) {\n          if (x.indexType === SQL_INDEX.TYPE.BTREE || x.indexType === SQL_INDEX.TYPE.PARTIAL) {\n            x.indexFields = x.indexFields.map((y) => ({ ...y, isExist: true }));\n          }\n        } else if (x.indexType === SQL_INDEX.TYPE.GIN) {\n          x.indexFields = [{ operator: x.operator, isExist: true }];\n        } else if (x.indexType && x.indexType !== SQL_INDEX.TYPE.UNIQUE) { x.indexFields = [SQL_INDEX.DEFAULT.SUB_OBJ]; }\n        return { ...x, isExist: true, isExpanded: false };\n      });\n    }\n    return temp;\n  }\n  return [];\n};\n"
  },
  {
    "path": "packages/client/src/constant/permission.js",
    "content": "export const DEVICE_TYPE = {\n  ADMIN: 'admin',\n  DEVICE: 'device',\n  CLIENT: 'client',\n  DESKTOP: 'desktop',\n};\n\nexport const DEVICE_TYPE_NAME = {\n  // ADMIN: 'Admin',\n  DEVICE: 'Mobile app',\n  CLIENT: 'Front(Website)',\n  // DESKTOP: 'Desktop',\n};\n\nexport const CRUD = {\n  C: 'C',\n  R: 'R',\n  U: 'U',\n  D: 'D',\n  BC: 'BC',\n  BU: 'BU',\n  HD: 'HD',\n  isAuth: 'isAuth',\n  isAuthObj: 'isAuthObj',\n  POLICY: 'policy',\n  ALL: 'ALL',\n  ALL_MODEL: 'ALL_MODEL',\n  ALL_DEVICE: 'ALL_DEVICE',\n};\n\nexport const LINKED_CRUD_OPERATION = {\n  C: ['C', 'BC'],\n  R: ['R'],\n  U: ['U', 'BU'],\n  D: ['D', 'HD'],\n};\n\nexport const CRUD_OPERATIONS = {\n  C: 'Create',\n  R: 'View',\n  U: 'Update',\n  D: 'Delete',\n  BC: 'Bulk Create',\n  BU: 'Bulk Update',\n  HD: 'Hard Delete',\n};\n\nexport const permission = [\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n      { all: 'Front' },\n      // { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n  {\n    title: 'Model1',\n    permissionSet: [\n      { all: 'Admin' },\n      { all: 'Device' },\n      { all: 'Front' },\n    ],\n  },\n];\n"
  },
  {
    "path": "packages/client/src/constant/policy.js",
    "content": "export const POLICY_GENERATE_TYPE = {\n  AUTO: 1,\n  MANUAL: 2,\n};\n"
  },
  {
    "path": "packages/client/src/constant/reservedVariable.js",
    "content": "import { APPLICATION_CODE } from './Project/applicationStep';\n\nexport const RESERVED_VALIDATION_MESSAGE = 'Oops! You cannot add reserved keyword as a key name.';\nexport const RESERVED_VARIABLES = {\n  COMMON: [\n    'break', 'catch', 'class', 'const', 'do',\n    'else', 'enum', 'true', 'false', 'finally',\n    'for', 'if', 'import', 'in', 'interface',\n    'null', 'package', 'private', 'protected', 'public',\n    'return', 'super', 'this', 'throw', 'try',\n    'typeof', 'var', 'while',\n  ],\n  [APPLICATION_CODE.nodeExpress]: {\n    NODE_EXPRESS: [\n      'abstract', 'arguments', 'await', 'boolean', 'byte',\n      'case', 'char', 'continue', 'debugger', 'default',\n      'delete', 'double', 'eval', 'export', 'extends',\n      'final', 'float', 'function', 'goto', 'implements',\n      'instanceof', 'int', 'let', 'long', 'native',\n      'new', 'short', 'static', 'switch', 'synchronized',\n      'throws', 'transient', 'void', 'volatile', 'with', 'yield',\n    ],\n  },\n};\n"
  },
  {
    "path": "packages/client/src/constant/rolePermission.js",
    "content": "export const MODULE_NO = {\n  USER: 1,\n  PROJECT: 7,\n  APPLICATION: 11,\n  PLANS: 21,\n  INVITATION: 109,\n  PERMISSION: 28,\n  MANAGE_MEMBER: 1001,\n  GIT_INTEGRATION: 1002,\n};\nexport const MODULE_URL = {\n  [MODULE_NO.USER]: '/account/profile',\n  [MODULE_NO.PROJECT]: '/project-list',\n  [MODULE_NO.INVITATION]: '/account/invite',\n  [MODULE_NO.MANAGE_MEMBER]: '/account/manage-member',\n};\n"
  },
  {
    "path": "packages/client/src/constant/routes.js",
    "content": "export const ROUTE_TYPES = [\n  { name: 'POST', id: 'post' },\n  { name: 'GET', id: 'get' },\n  { name: 'PUT', id: 'put' },\n  { name: 'DELETE', id: 'delete' },\n  { name: 'PATCH', id: 'patch' },\n  { name: 'HEAD', id: 'head' },\n  { name: 'OPTIONS', id: 'options' },\n  { name: 'PURGE', id: 'purge' },\n  { name: 'LINK', id: 'link' },\n  { name: 'UNLINK', id: 'unlink' },\n];\nexport const ROUTE_GENERATE_TYPE = {\n  AUTO: 1,\n  MANUAL: 2,\n};\n\nexport const ROUTE_HEADERS = [\n  'authorization',\n  'cache-control',\n  'content-type',\n];\n\nexport const ROUTE_VALIDATION_MESSAGE = {\n  uniqResponseKey: 'Oops! Invalid response name. Duplicate response name is not allowed.',\n  tabValidation: 'Oops! Some fields are left blank in the previous step. Kindly fill all required fields.',\n};\n\nexport const OPERATION_TYPE = {\n  post: {\n    create: 'C',\n    addBulk: 'BC',\n    list: 'R',\n  },\n  get: {\n    '{{id}}': 'R',\n  },\n  delete: {\n    softDelete: 'D',\n    '{{id}}': 'D',\n  },\n  put: {\n    '{{}}': 'U',\n    '{{id}}': 'U',\n    updateBulk: 'BU',\n  },\n};\n"
  },
  {
    "path": "packages/client/src/constant/sidebar.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\n\nexport const sidebar = {\n  NODE_EXPRESS: [\n    {\n      key: '1',\n      linkSet: 'crud/platform',\n      link: '/node/crud/platform',\n      tooltipID: 'crud',\n      iconActive: <Icons.Model color=\"#ffffff\" />,\n      icon: <Icons.CRUD />,\n      tooltip: 'CRUD',\n      afterBuildLink: '/node/crud/model',\n    },\n    {\n      key: '2',\n      linkSet: 'constant',\n      link: '/node/constant',\n      tooltipID: 'constant',\n      iconActive: <Icons.Constant color=\"#ffffff\" />,\n      icon: <Icons.Constant />,\n      tooltip: 'Constant',\n    },\n    {\n      key: '3',\n      linkSet: 'role-access',\n      link: '/node/role-access',\n      tooltipID: 'role-access',\n      iconActive: <Icons.RoleAccess color=\"#ffffff\" />,\n      icon: <Icons.RoleAccess />,\n      tooltip: 'Role access',\n    },\n    {\n      key: '4',\n      linkSet: 'middleware',\n      link: '/node/middleware',\n      tooltipID: 'middleware',\n      iconActive: <Icons.Policy color=\"#ffffff\" />,\n      icon: <Icons.Policy />,\n      tooltip: 'Middleware',\n    },\n    {\n      key: '5',\n      linkSet: 'environment-variable',\n      link: '/node/environment-variable',\n      tooltipID: 'environment-variable',\n      iconActive: <Icons.Environment color=\"#ffffff\" />,\n      icon: <Icons.Environment />,\n      tooltip: 'Environment variable',\n    },\n    {\n      key: '6',\n      linkSet: 'configuration',\n      link: '/node/configuration',\n      tooltipID: 'configuration',\n      iconActive: <Icons.Configuration color=\"#ffffff\" />,\n      icon: <Icons.Configuration />,\n      tooltip: 'Configuration',\n    },\n  ],\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/BuildCodeStructure/index.js",
    "content": "import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport {\n  Heading, Popup, CardView,\n} from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\nimport { BUILD_ARCHITECTURE_CODE } from '../../../constant/buildProcessConstant';\nimport { setBuildCodeState } from '../../../redux/reducers/buildCode';\nimport { codeGenerator } from '../../../redux/thunks/buildCode';\nimport { BuildVSCodePopup } from '../../Shared/BuildApp/BuildAppDropdown';\n\nconst BuildOptions = [\n  {\n    name: 'MVC',\n    id: BUILD_ARCHITECTURE_CODE.MVC,\n  },\n  {\n    name: 'Clean Code',\n    id: BUILD_ARCHITECTURE_CODE.CC,\n  },\n];\nexport const BuildCodeStructure = ({ openBuildRef }) => {\n  const [isOpen, handelOpen, handelClose] = useBoolean(false);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const dispatch = useDispatch();\n  const buildProject = (type) => {\n    dispatch(setBuildCodeState({ buildArchitecture: type }));\n\n    dispatch(codeGenerator({ applicationId, projectType: type }));\n\n    handelClose();\n  };\n  React.useImperativeHandle(openBuildRef, () => ({ handelOpen }));\n  return (\n    <>\n      <Popup closeModal={handelClose} size=\"w-6/12 xxl:w-4/12\" isOpen={isOpen} title=\"Code generator architecture\">\n        <div className=\"grid grid-cols-2 gap-5\">\n          {BuildOptions.map((options) => (\n            <CardView\n              key={options.id}\n              onClick={() => {\n                buildProject(options.id);\n              }}\n            >\n              <Heading variant=\"h4\">{options.name}</Heading>\n            </CardView>\n          ))}\n        </div>\n      </Popup>\n      <BuildVSCodePopup />\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Configuration/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useHistory } from 'react-router';\nimport { isEmpty } from 'lodash';\nimport {\n  editApplication,\n  // getApplication\n}\n  from '../../../api/project';\nimport {\n  Heading, StepFooter, Select, Loader,\n} from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\nimport { LAYOUT_STEP_MODULE_NAME, RedirectUrl } from '../../../constant/Nodecrud';\nimport {\n  PLATFORM_FILTER, USER_TYPE_FILTER,\n} from '../../../constant/Project/applicationStep';\nimport { selectCurrentApplication } from '../../../redux/reducers/projects';\nimport { encryptStorage } from '../../../utils/localStorage';\nimport { getError } from '../../../utils/validationMsgs';\nimport { StepHeader } from '../../Shared/Layout/StepHeader';\nimport LayoutStepUrl from '../../Shared/LayoutStepUrl';\nimport TagNameSelect from '../../Shared/TechnologySetStep/addNewTag';\nimport { useToastNotifications } from '../../hooks';\n\nconst Configuration = () => {\n  const {\n    errors, control,\n    getValues,\n    handleSubmit, watch, setValue,\n  } = useForm({ mode: 'all' });\n  const dispatch = useDispatch();\n  const buttonRef = React.useRef('');\n  const { addSuccessToast, addErrorToast } = useToastNotifications();\n  const applicationId = useSelector(({ projects }) => (projects.currentApplicationId));\n  const applicationList = useSelector(({ projects }) => (projects.currentProjectDetail.applicationList));\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const history = useHistory();\n  const [loading, setLoading, hideLoading] = useBoolean(false);\n  const [fetchLoading, setFetchLoading, hideFetchLoading] = useBoolean(false);\n  const configInput = applicationList?.find?.((d) => d._id === applicationId)?.configInput;\n\n  const defaultPlatForm = PLATFORM_FILTER.map((platform) => platform.id);\n  const [customPlatForm, setCustomPlatForm] = React.useState([]);\n  React.useEffect(() => {\n    setCustomPlatForm(configInput?.platform?.filter((p) => !customPlatForm.includes(p) && !defaultPlatForm.includes(p)).map((p) => ({ id: p, name: p })) ?? []);\n  }, []);\n  const getPlatformData = () => {\n    setFetchLoading();\n  };\n  React.useEffect(() => {\n    getPlatformData();\n    hideFetchLoading();\n    return () => {\n    // REMOVE\n    // to maintain remove toggle from sidebar when crud in url\n      !window.location.pathname.includes('crud') && encryptStorage.remove('sidebarToggle');\n    };\n  }, []);\n  const handleSave = (buttonName) => {\n    buttonRef.current = buttonName;\n    setLoading();\n\n    editApplication(applicationId, {\n      name: applicationList.find((app) => app._id === applicationId)?.name,\n      configInput: {\n        ...(configInput && configInput),\n        ...getValues(),\n      },\n    }).then((res) => {\n      addSuccessToast(res.message);\n      if (buttonName === 'next') history.push(RedirectUrl[currentApplicationCode].platformConfig.nextUrl);\n      hideLoading();\n      dispatch(\n        selectCurrentApplication({\n          currentProject: {\n            applications: applicationList.map((a) => (a._id === applicationId ? { ...a, ...res.data } : a)),\n          },\n        }),\n      );\n    }).catch((error) => {\n      addErrorToast(error);\n      hideLoading();\n    });\n  };\n  return (\n    <div className=\"flex flex-col h-screen\">\n      <StepHeader backTitle=\"Back to screen\" headTitle=\"CRUD\" link={RedirectUrl[currentApplicationCode].platformConfig.backScreenUrl} />\n      <LayoutStepUrl isOpenBigLayout={false} isBuildShow moduleName={LAYOUT_STEP_MODULE_NAME[currentApplicationCode]}>\n        {fetchLoading && <Loader />}\n        <div className=\"headTop p-3 px-5 border-b border-gray-200\">\n          <div className=\"w-8/12 xxl:w-6/12\">\n            <Heading variant=\"h5\">Platform Configuration</Heading>\n            {/* <Description className=\"mt-1\">Lorem Ipsum is simply dummy text of the Lorem Ipsum is simply dummy text of the Lorem Ipsum is simply dummy text of the</Description> */}\n          </div>\n        </div>\n        { !fetchLoading && (\n        <div className=\"p-3 px-5 overflow-auto flex-grow\">\n          <div className=\"grid grid-cols-2 gap-5\">\n            <Controller\n              control={control}\n              defaultValue={isEmpty(configInput?.platform) ? undefined : configInput?.platform}\n              name=\"platform\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <TagNameSelect\n                  {...controlProps}\n                  setCustomTag={(p) => {\n                    setCustomPlatForm(p.filter((platform) => !defaultPlatForm?.includes(platform.id)));\n                  }}\n                  onChange={(options) => {\n                    const adminAccess = getValues('loginAccess[Admin]')?.filter((admin) => options?.includes(admin));\n                    const customerAccess = getValues('loginAccess[User]')?.filter((user) => options?.includes(user));\n                    setValue('loginAccess[Admin]', isEmpty(adminAccess) ? undefined : adminAccess);\n                    setValue('loginAccess[User]', isEmpty(customerAccess) ? undefined : customerAccess);\n                    controlProps.onChange(options);\n                  }}\n                  tagNameCustom={customPlatForm}\n                  placeholder=\"Select platform selection\"\n                  options={PLATFORM_FILTER}\n                  isMulti\n                  label=\"Platform selection*\"\n                  desc={(\n                    <>\n                      Select the platform for which you would like to build an application. Just write any name and press enter to add a custom platform.\n                    </>\n                          )}\n                  error={getError(errors, 'platform', 'Platform')}\n                />\n              )}\n            />\n            <Controller\n              control={control}\n              name=\"types\"\n              defaultValue={configInput?.types}\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Select\n                  {...controlProps}\n                  placeholder=\"Select user type\"\n                  options={USER_TYPE_FILTER}\n                  isMulti\n                  valueKey=\"name\"\n                  label=\"User types*\"\n                  desc=\"Select user type who are going to use the application.\"\n                  error={getError(errors, 'types', 'User type')}\n                />\n              )}\n            />\n            {watch('types')?.includes?.('Admin') && (\n            <Controller\n              control={control}\n              defaultValue={configInput?.loginAccess?.Admin}\n              name=\"loginAccess[Admin]\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Select\n                  {...controlProps}\n                  placeholder=\"Select login access for admin\"\n                  options={[...PLATFORM_FILTER.filter((platform) => watch('platform')?.includes(platform.id)), ...customPlatForm.filter((platform) => watch('platform')?.includes(platform.id))]}\n                  isMulti\n                  label=\"Login access for admin* \"\n                  desc=\"Select platform allows admin to login.\"\n                  error={getError(errors?.loginAccess ?? {}, 'Admin', 'Login access for admin')}\n                />\n              )}\n            />\n            )}\n            {watch('types')?.includes?.('User') && (\n            <Controller\n              control={control}\n              defaultValue={configInput?.loginAccess?.User}\n              name=\"loginAccess[User]\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Select\n                  {...controlProps}\n                  placeholder=\"Select login access for user\"\n                  options={[...PLATFORM_FILTER.filter((platform) => watch('platform')?.includes(platform.id)), ...customPlatForm.filter((platform) => watch('platform')?.includes(platform.id))]}\n                  isMulti\n                  label=\"Login access for user* \"\n                  desc=\"Select platform allows user to login.\"\n                  error={getError(errors?.loginAccess ?? {}, 'User', 'Login access for user')}\n                />\n              )}\n            />\n            )}\n\n          </div>\n        </div>\n        )}\n        {/* // REMOVE */}\n        <StepFooter\n          nextClick={\n            handleSubmit(() => handleSave('next'))\n          }\n          saveClick={\n            handleSubmit(() => handleSave('save'))\n          }\n          saveLoading={buttonRef.current === 'save' && loading}\n          nextLoading={buttonRef.current === 'next' && loading}\n          Next=\"Save & Next\"\n          saveText=\"Save\"\n        />\n      </LayoutStepUrl>\n    </div>\n  );\n};\nexport default Configuration;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/AddModalPopup/index.js",
    "content": "import React from 'react';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { Controller, useForm } from 'react-hook-form';\nimport { toLower } from 'lodash';\nimport {\n  Popup, Input, TextArea,\n  // Button,\n} from '../../../../components';\nimport { addModel } from '../../../../redux/reducers/models';\nimport { API_URLS } from '../../../../api/constants';\nimport { apiClient } from '../../../../api/config';\nimport useToastNotifications from '../../../hooks/useToastNotifications';\nimport { useBoolean } from '../../../../components/hooks';\nimport { modelAttrRegex, nodeKeyRegex } from '../../../../utils/regex';\nimport { getError } from '../../../../utils/validationMsgs';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../constant/common';\nimport {\n  mongoDbModalName, DB_CONST, ALL_TABLE_TYPES,\n  SQL_MODEL_NAME_LENGTH, DB_TYPE, pluralizeTableName,\n} from '../../../../constant/model';\n\nexport const CreateModel = (props) => {\n  const dispatch = useDispatch();\n  const { applicationId, currentApplicationCode, dbType } = useSelector(({ projects }) => ({\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n    dbType: DB_CONST[projects.applicationDatabase.databaseType],\n  }), shallowEqual);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const [isSubmitting, setSubmitting, removeSetSubmitting] = useBoolean(false);\n  const modelNameLength = SQL_MODEL_NAME_LENGTH;\n  const {\n    handleSubmit, reset, errors, control, watch,\n  } = useForm({ mode: 'onChange' });\n\n  const prepareSchema = (schema) => {\n    const tSchema = {};\n    if (schema) {\n      // prepare schema from externally pasted input\n      const splitNewLine = schema.split(/\\n+/);\n      splitNewLine.forEach((s) => {\n        const words = s.trim().split(/[\\s,.]+/); // trim line and split into words\n        words.forEach((ws, i) => {\n          let w = ws.trim(); // trim words\n          const lastChar = w.charAt(w.length - 1); // get last char\n          if (lastChar && !modelAttrRegex.test(w)) {\n            // filter out if last char is not valid (name@)\n            w = ws.substring(0, ws.length - 1);\n          }\n          if (i % 2 === 0 && modelAttrRegex.test(w)) {\n            const typeArr = Object.values(ALL_TABLE_TYPES[dbType]);\n            let isTypeExist;\n            if (words[i + 1]) {\n              isTypeExist = typeArr.find((o) => toLower(o) === toLower(words[i + 1]));\n            } else if (!typeArr.includes(w)) isTypeExist = ALL_TABLE_TYPES[dbType]?.STRING;\n            if (isTypeExist) {\n              // assign type to attribute name\n              tSchema[w] = { type: isTypeExist };\n            }\n          }\n        });\n      });\n    }\n    return tSchema;\n  };\n\n  const onSubmit = (data) => {\n    if (isSubmitting) return;\n    const schemaJson = prepareSchema(data.schema);\n    // eslint-disable-next-line no-param-reassign\n    delete data.schema;\n    const modelName = data.name;\n\n    setSubmitting();\n\n    apiClient(API_URLS.schema.create, {\n      ...data,\n      name: modelName,\n      tableName: pluralizeTableName(modelName, currentApplicationCode),\n      schemaJson,\n      applicationId,\n      definitionType: currentApplicationCode,\n\n    })\n      .then((createRes) => {\n        addSuccessToast(createRes?.message);\n        createRes?.data?._id && dispatch(addModel(createRes?.data));\n        props.handleCancel();\n        reset();\n      })\n      .catch((err) => {\n        addErrorToast(err);\n      })\n      .finally(() => {\n        removeSetSubmitting();\n      });\n  };\n\n  return (\n    <Popup\n      isOpen={props.isOpen}\n      handleCancel={props.handleCancel}\n      handleSubmit={handleSubmit(onSubmit)}\n      closeModal={props.closeModal}\n      title=\"Create new model\"\n      isCancel\n      cancel=\"Cancel\"\n      isSubmit\n      submit=\"Create model\"\n      bodyClass=\"xxl:max-h-110 overflow-auto xl:max-h-96\"\n      submitLoading={isSubmitting}\n      isAutoFocusOnSave\n    >\n      <>\n        <form className=\"grid grid-cols-1 gap-5\" onSubmit={handleSubmit(onSubmit)}>\n          <div className=\"grid grid-cols-2 gap-5\">\n            <Controller\n              control={control}\n              name=\"name\"\n              rules={{ required: true, maxLength: modelNameLength }}\n              render={(controlProps) => (\n                <Input\n                  // eslint-disable-next-line react/jsx-props-no-spreading\n                  {...controlProps}\n                  autoFocus\n                  placeholder=\"Enter model name\"\n                  label=\"Model name*\"\n                  customRegex={dbType === DB_TYPE.MONGODB ? mongoDbModalName : nodeKeyRegex}\n                  // desc=\"Kindly enter the model name. The model name you write here will display everywhere.\"\n                  error={getError(errors, 'name', (errors?.name?.type === 'maxLength') ? modelNameLength : 'Model name')}\n                />\n              )}\n            />\n            <Controller\n              control={control}\n              name=\"tableName\"\n              defaultValue={watch('name') ? pluralizeTableName(watch('name'), currentApplicationCode) : ''}\n              render={(controlProps) => (\n                <Input\n                  // eslint-disable-next-line react/jsx-props-no-spreading\n                  {...controlProps}\n                  disabled\n                  placeholder={`${dbType === DB_TYPE.MONGODB ? 'Collection' : 'Table'} name`}\n                  label={`${dbType === DB_TYPE.MONGODB ? 'Collection' : 'Table'} name`}\n                  value={watch('name') ? pluralizeTableName(watch('name'), currentApplicationCode) : ''}\n                />\n              )}\n            />\n          </div>\n          <Controller\n            control={control}\n            name=\"schema\"\n            rules={{ required: false, maxLength: MAX_INPUT_FIELD_LIMIT.description }}\n            render={(controlProps) => (\n              <TextArea\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...controlProps}\n                placeholder=\"Enter model attribute like.&#10;name&#10;type&#10;description\"\n                label=\"Model attribute\"\n                desc=\"You can quickly enter your model attributes by pasting them in the above box vertically. \"\n                error={getError(errors, 'schema', (errors?.schema?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.description : 'Attribute')}\n              />\n            )}\n          />\n        </form>\n      </>\n    </Popup>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/DeleteModel.js",
    "content": "import React, { useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Icons } from '@dhiwise/icons';\nimport { deleteModel } from '../../../api/models';\nimport {\n  ConfirmationAlert, Description, IconBox, TagGroup,\n} from '../../../components';\nimport { useBoolean, useToastNotifications } from '../../hooks';\nimport { deleteCurrentModel } from '../../../redux/reducers/models';\nimport { useModel } from './Editor/ModelProvider';\n\nconst DeleteModel = React.memo(({ currentId, className, isDeleteWhiteIcon }) => {\n  const dispatch = useDispatch();\n  const [visibleDelete, setVisibleDelete, hideVisibleDelete] = useBoolean(false);\n  const [deleteLoader, setDeleteLoader, hideDeleteLoader] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const { setModelErrors, setNoChangeInTable } = useModel();\n  const modelList = useSelector((state) => state.models.modelList);\n  const currentApplicationCode = useSelector(({ projects }) => (projects.currentApplicationCode));\n  const [delData, setDelData] = useState();\n\n  const handleModelDelete = React.useCallback(({ isDependencyInfo }) => {\n    !isDependencyInfo && setDeleteLoader();\n    const request = {\n      id: currentId,\n      isHardDelete: true,\n      definitionType: currentApplicationCode,\n      isDependencyInfo,\n    };\n    deleteModel(request).then((data) => {\n      if (data?.code === 'OK') {\n        if (isDependencyInfo) {\n          // check for dependency\n          const tagList = data.data.map((x) => ({\n            title: `${x.modelName}-${x.key}`,\n            size: 'small',\n            variant: 'coolGray',\n          }));\n          setDelData(tagList);\n          setVisibleDelete();\n        } else {\n          // delete model\n          if (data?.message) addSuccessToast(data.message);\n          dispatch(deleteCurrentModel({ delId: currentId }));\n          setModelErrors((modelErrors) => modelErrors?.filter((error) => !modelList?.map((model) => model?.name)?.includes(error?.modelName))); // delete model errors if model is deleted\n          hideVisibleDelete();\n        }\n      } else if (data?.message) {\n        addErrorToast(data.message);\n        hideVisibleDelete();\n      }\n      setNoChangeInTable();\n      // dispatch(deleteCurrentModel());\n    }).catch((err) => {\n      hideVisibleDelete();\n      addErrorToast(err);\n    }).finally(hideDeleteLoader);\n  }, [currentId]);\n\n  const handleConfirmation = () => {\n    handleModelDelete({ isDependencyInfo: true });\n  };\n\n  const text = (\n    <div>\n      {\n        delData?.length > 0 ? (\n          <>\n            <Description className=\"mt-2 w-10/12 m-auto\">\n              You want to delete this model with all the below mention relationships as well as any references of this model in routes, custom query and model permission will be deleted permanently and cannot be restored in the future.\n            </Description>\n            <div className=\"mt-2\">\n              <TagGroup\n                className=\"cursor-text\"\n                titleKey=\"title\"\n                TagList={delData}\n              />\n            </div>\n          </>\n        ) : (\n          <Description className=\"mt-2 w-10/12 m-auto\">\n            You want to delete this model with all its references from relationships, routes, custom query and model permission permanently. Also, the deleted models cannot be restored in the future.\n          </Description>\n        )\n}\n    </div>\n  );\n\n  return (\n    <>\n      {\n        visibleDelete\n        && (\n        <ConfirmationAlert\n          isOpen={visibleDelete}\n          isLoading={deleteLoader}\n          size=\"w-6/12 xxl:w-5/12\"\n          handleSubmit={handleModelDelete}\n          handleClose={hideVisibleDelete}\n        >\n          {text}\n        </ConfirmationAlert>\n        )\n      }\n      {/* Remove */}\n      <IconBox\n        className={className}\n        onClick={handleConfirmation}\n        variant=\"ghost\"\n        size=\"small\"\n        icon={isDeleteWhiteIcon ? <Icons.Close color=\"#ffffff\" /> : <Icons.Close />}\n      />\n    </>\n  );\n});\n\nexport default DeleteModel;\nDeleteModel.displayName = 'DeleteModel';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/EditorProvider/index.js",
    "content": "/* eslint-disable no-param-reassign */\n/* eslint-disable radix */\nimport React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport {\n  omit, isEmpty, isEqual, cloneDeep, isObject, extend,\n} from 'lodash';\nimport {\n  util,\n  getDisableField,\n  getParsedType,\n  getParsedKeys,\n  parsedKeys,\n  SCHEMA_TAB,\n  TABS,\n  getHookData,\n  DB_TYPE,\n  isNumberType,\n  DB_CONST,\n  RELATION_TYPE,\n} from '../../../../../constant/model';\nimport { filterObjectUndefinedValues } from '../../../../../utils/dataTypes';\nimport {\n  getUnixTimestamp, getDateByTimestamp, dateTimeFormat, dateFormat, dateTimeFormatter, setDateToISO,\n} from '../../../../../utils/dateTimeFormatter';\nimport { ORM_TYPE } from '../../../../../constant/Project/applicationStep';\n\nconst getHookType = (str) => {\n  const arr = str.split('-');\n  return { type: arr[0], ...(arr[1] && { operation: arr[1] }) };\n};\n\nexport const EditorContext = React.createContext();\nconst arr = [];\nconst EditorProvider = React.memo(({\n  children, saveJSON,\n}) => {\n  const dbType = useSelector((state) => DB_CONST[state.projects.applicationDatabase.databaseType]);\n  const ormType = useSelector((state) => {\n    if (state.projects.applicationDatabase.ormType === ORM_TYPE.ELOQUENT) return ORM_TYPE.SEQUELIZE;\n    return state.projects.applicationDatabase.ormType;\n  });\n  const TABLE_TYPES = React.useMemo(() => util.getTableTypes(dbType), [dbType]);\n  const [mainActiveTab, setMainActiveTab] = React.useState(0);\n  const currentId = useSelector((state) => state.models.currentId);\n  const modelList = useSelector((state) => state.models.modelList) || [];\n  const currentModel = React.useMemo(() => modelList.find((model) => model._id === currentId), [currentId, modelList]);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n\n  const hookOptions = getHookData(currentApplicationCode);\n\n  const [code, setCode] = React.useState();\n  const [tableJson, setTableJson] = useState(arr);\n  const [activeTab, setActiveTab] = useState(SCHEMA_TAB.TABLE_VIEW);\n  const [customSetting, setCustomSetting] = React.useState({});\n  const [hooks, setHooks] = React.useState([]);\n  const [dependency, setDependency] = React.useState([]);\n\n  const listRef = React.useRef(null);\n\n  React.useEffect(() => {\n    const tempHooks = currentModel?.hooks ? [...currentModel?.hooks] : [];\n    const typeArr = [];\n\n    const newHooks = [];\n\n    hookOptions.map((t) => {\n      let obj = {};\n      const isExist = tempHooks.find((hook) => (t.id === ((`${hook.type}-${hook.operation}`))));\n      obj.code = '';\n      if (isExist) {\n        obj.isExist = true;\n        obj.code = isExist.code;\n      }\n      obj.hookType = t.id;\n      obj._id = t.id;\n      obj = {\n        ...obj,\n        ...getHookType(obj.hookType),\n      };\n      newHooks.push(obj);\n      typeArr.push(obj.hookType);\n      return t;\n    });\n    setHooks(newHooks);\n  }, [currentModel?.hooks]);\n\n  const handleAddRow = React.useCallback((tableArr, isAutoFocus) => {\n    // add new row\n    const newTable = tableArr ? cloneDeep(tableArr) : [...tableJson];\n    const obj = {\n      key: `r${newTable.length}`,\n    };\n    newTable.push(obj);\n    if (!isEqual(tableJson, newTable)) {\n      setTableJson(() => newTable);\n      requestAnimationFrame(() => {\n        listRef?.current?.resetAfterIndex?.(0);\n        // listRef?.current?.scrollToItem?.(newTable.length - 1); // add new row from head\n        if (isAutoFocus) {\n          // handleCurEleFocus(obj.key);\n        }\n      });\n    }\n  }, [tableJson, listRef?.current]);\n\n  function prepareTableObj(x, parent, opt, customModelList = []) {\n    if (x.minlength) {\n      // parse for case-insensitive\n      x.minLength = x.minlength;\n      delete x.minlength;\n    } if (x.maxlength) {\n      // parse for case-insensitive\n      x.maxLength = x.maxlength;\n      delete x.maxlength;\n    }\n    const obj = {\n      ...x,\n      type: getParsedType(x.type, dbType),\n      minLength:\n        x.minLength > x.maxLength ? undefined : x.minLength?.toString(),\n      maxLength:\n        x.minLength > x.maxLength ? undefined : x.maxLength?.toString(),\n      min: x.min > x.max ? undefined : x.min?.toString(),\n      max: x.min > x.max ? undefined : x.max?.toString(),\n      // attr: c,\n      isExpand: false,\n      ref: isEmpty(customModelList) ? modelList?.find((m) => m.name === x.ref)?._id : customModelList?.find((m) => m?.name === x.ref)?._id,\n    };\n    if (obj.ref) {\n      obj.refName = x.ref;\n    }\n    if (obj.default === null) obj.filter = 'NULL';\n    else if (obj.default !== undefined && obj.default !== null && obj.type !== TABLE_TYPES.BOOL) obj.filter = 'AS_DEFINED';\n    if ((dbType !== DB_TYPE.MONGODB && isNumberType(obj.type, TABLE_TYPES))) {\n      obj.filter = undefined;\n    }\n    if ([TABLE_TYPES.BOOL, '_id'].includes(obj.type) && obj.default !== undefined && obj.default !== null && typeof obj.default === 'boolean') obj.default = obj.default ? 'true' : 'false';\n    if (obj.type === TABLE_TYPES.VIRTUAL_RELATION && !obj.localField) {\n      obj.localField = '_id';\n    }\n    if (dbType !== DB_TYPE.MONGODB && obj.ref && !obj.relType) {\n      obj.relType = RELATION_TYPE.HAS_MANY;\n    }\n    if (opt?.newCustomSetting) {\n      // Mark attribute as private\n      const tempSetting = cloneDeep(customSetting) || {};\n      if (!parent && (obj.type === TABLE_TYPES.ARRAY || obj.type === JSON) && tempSetting?.[obj.attr]) {\n        // set false for row attribute\n        obj.private = false;\n        tempSetting[obj.attr].private = false;\n        tempSetting[obj.attr].isMarkedAsPrivate = false;\n      }\n      if (parent && typeof opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.private === 'boolean') {\n        // sub-attr\n        if (opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.isMarkedAsPrivate) {\n          tempSetting[parent.attr][obj.attr].private = obj.private;\n        } else {\n          obj.private = opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.private;\n          if (!tempSetting[parent.attr]) tempSetting[parent.attr] = {};\n          if (!tempSetting[parent.attr]?.[obj.attr]) tempSetting[parent.attr][obj.attr] = {};\n          tempSetting[parent.attr][obj.attr].private = opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.private;\n          tempSetting[parent.attr][obj.attr].isMarkedAsPrivate = true;\n        }\n      } else if (!parent && typeof opt?.newCustomSetting?.[obj.attr]?.private === 'boolean') {\n        // main row\n        if (opt?.newCustomSetting?.[obj.attr]?.isMarkedAsPrivate) {\n          tempSetting[obj.attr].private = obj.private;\n        } else {\n          obj.private = opt?.newCustomSetting?.[obj.attr]?.private;\n          if (!tempSetting[obj.attr]) tempSetting[obj.attr] = {};\n          tempSetting[obj.attr].private = opt?.newCustomSetting?.[obj.attr]?.private;\n          tempSetting[obj.attr].isMarkedAsPrivate = true;\n        }\n      }\n\n      // manage enum\n      if ((dbType === DB_TYPE.MONGODB && (obj.type === TABLE_TYPES.STRING || obj.type === TABLE_TYPES.NUMBER))\n      || obj.type === TABLE_TYPES.ENUM) {\n        let enumObj = {};\n        if (!parent) enumObj = opt?.newCustomSetting?.[obj.attr]?.enum;\n        else {\n        // sub-row\n        // eslint-disable-next-line no-lonely-if\n          if (parent?.attr && parent.type === TABLE_TYPES.JSON) {\n            enumObj = opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.enum;\n          } else if (parent?.attr && parent.type === TABLE_TYPES.ARRAY) {\n            enumObj = opt?.newCustomSetting?.[parent.attr]?.[0]?.[obj.attr]?.enum || opt?.newCustomSetting?.[parent.attr]?.[obj.attr]?.enum;\n          }\n        }\n\n        obj.enum = enumObj;\n        if (obj.enum?.default) obj.filter = 'AS_DEFINED';\n        if (obj.default !== null && obj.default !== undefined) obj.default = x.default;\n        obj.isEnum = typeof obj.enum === 'object' && Object.entries(obj.enum)?.length > 0;\n        if (!obj.isEnum) {\n          obj.enum = undefined;\n          obj.default = obj.default ?? undefined;\n        }\n        if (obj.enum?.default && (obj.default === null || obj.default === undefined)) {\n        // on remove default value remove it from customsetting too\n          // const tempSetting = cloneDeep(customSetting);\n          obj.enum = omit(obj.enum, 'default');\n          if (parent && tempSetting[parent.attr]?.[obj.attr]) { tempSetting[parent.attr][obj.attr].enum = obj.enum; } else if (!parent && tempSetting[obj.attr]) { tempSetting[obj.attr].enum = obj.enum; }\n        }\n      }\n      setCustomSetting(tempSetting);\n    }\n    if (obj.type === TABLE_TYPES.DATE && dbType === DB_TYPE.POSTRAGSQL && obj.default) {\n      // convert DATE for POSTRAGSQL DB\n      obj.default = getDateByTimestamp(obj.default, true); // true for time\n    } else if ((obj.type === TABLE_TYPES.DATE || obj.type === TABLE_TYPES.DATEONLY || obj.type === TABLE_TYPES.TIMESTAMP) && obj.default) {\n      obj.default = new Date(obj.default);\n    }\n    return obj;\n  }\n\n  const prepareTableView = React.useCallback(({\n    isAutoFocus = false, isMount = false, tCode, tCustomSetting, isReturnTempArray = false, customModelList = [], isExcludeArrayId,\n  }) => {\n    try {\n      if (activeTab === SCHEMA_TAB.TABLE_VIEW && !isMount) return; // parser need only when TREE_VIEW and CODE_VIEW is active tab\n      const curCode = tCode || code;\n      if (!curCode) return;\n      // prepare tableview data (code view json to array)\n      const parsedCode = isObject(curCode) ? curCode : JSON.parse(curCode);\n      // setLoading(true);\n      const tempArray = [];\n      const tempDependency = [];\n      const newCustomSetting = isMount ? tCustomSetting : customSetting;\n\n      if (curCode !== '{}') {\n        Object.keys(parsedCode).map((c, index) => {\n          let x = parsedCode[c];\n          const obj = {};\n          if (!x || isEmpty(x)) return c; // return if null or undefined or empty array/object\n          if (dbType === DB_TYPE.MONGODB && x?.type === TABLE_TYPES.ARRAY) {\n            // default value false of__id\n            let tempSub = {};\n            if (!isExcludeArrayId) { tempSub = extend(tempSub, { _id: { default: 'false', type: '_id' } }); }\n            x = [tempSub];\n          }\n\n          let isSubAttr = false;\n          if (dbType === DB_TYPE.MONGODB && typeof x === 'object' && Array.isArray(x)) {\n            isSubAttr = true;\n          } else if (dbType === DB_TYPE.MONGODB && typeof x === 'object' && Object.keys(x)?.length > 0) {\n            // type object\n            if (Object.values(x).some((v) => typeof v === 'object' && v)) {\n              // if any value has type object\n              isSubAttr = true;\n            } else {\n              // eslint-disable-next-line no-lonely-if\n              if (Object.keys(x).includes('type') && parsedKeys(x, dbType)?.isSub) {\n                isSubAttr = true;\n              } else {\n                isSubAttr = false;\n              }\n            }\n          }\n\n          if (isSubAttr) {\n            // sub-rows  ex:- if condition x=[{e:{}}] || x={e:{}}\n            const tempSubRows = [];\n            obj.type = Array.isArray(x) ? TABLE_TYPES.ARRAY : TABLE_TYPES.JSON;\n            obj.attr = c;\n            obj.key = `r${index}`;\n            if (x.description)obj.description = x.description;\n            let tempSub = Array.isArray(x) ? x[0] : x;\n            if (dbType === DB_TYPE.MONGODB && Array.isArray(x)) {\n              // default value false of__id\n              if (!isExcludeArrayId) {\n                tempSub = extend(tempSub,\n                  {\n                    _id: {\n                      default: typeof tempSub._id === 'boolean' ? tempSub._id.toString() : 'false',\n                      type: '_id',\n                    },\n                  });\n              }\n            } else if (dbType === DB_TYPE.MONGODB && !Array.isArray(x)) {\n              // default value false of__id (if obj then filter _id)\n              delete tempSub._id;\n            }\n            tempDependency.push({\n              oldKey: c,\n              newKey: '',\n              parentKey: '',\n            });\n            Object.keys(tempSub).map((y, yi) => {\n              let sr = tempSub[y];\n              if (!sr || isEmpty(sr)) return y; // return if null or undefined or empty array/object\n              if (typeof sr === 'string') {\n                sr = {};\n                sr.type = tempSub[y];\n              }\n              sr.attr = y;\n              sr.key = `rs${yi}`;\n              sr.rowKey = obj.key;\n              if (sr.attr !== '_id') { tempSubRows.push(prepareTableObj(sr, obj, { newCustomSetting }, customModelList)); } else {\n                tempSubRows.push(sr);\n              }\n              tempDependency.push({\n                oldKey: y,\n                newKey: '',\n                parentKey: c,\n              });\n              return y;\n            });\n            obj.subRows = tempSubRows;\n\n            tempArray.push(obj);\n          } else {\n            // main row\n            if (typeof x === 'string') {\n              x = {};\n              x.type = parsedCode[c];\n            }\n            x.attr = c;\n            x.key = `r${index}`;\n            tempArray.push(prepareTableObj(x, undefined, { newCustomSetting }, customModelList));\n            tempDependency.push({\n              oldKey: c,\n              newKey: '',\n              parentKey: '',\n            });\n          }\n          return c;\n        });\n      }\n      setDependency(tempDependency);\n      // setTableJson(tempArray);\n      if (isReturnTempArray) {\n        // eslint-disable-next-line consistent-return\n        return tempArray;\n      }\n      handleAddRow(tempArray, isAutoFocus);\n    } catch (e) {\n      // console.log(e);\n    }\n  }, [code, activeTab, customSetting, modelList, dbType]);\n\n  React.useMemo(() => {\n    // do not set tablejson here\n    const tempJson = currentModel?.schemaJson || {};\n    setCode(JSON.stringify(tempJson));\n  }, [currentModel?._id]);\n\n  React.useMemo(() => {\n    // do not set tablejson here\n    const tempJson = currentModel?.schemaJson || {};\n    // setCode(JSON.stringify(tempJson));\n    prepareTableView({\n      isMount: true, isAutoFocus: true, tCode: JSON.stringify(tempJson), tCustomSetting: currentModel?.customJson?.additionalSetting,\n    });\n  }, [currentModel?.schemaJson]);\n\n  function prepareCodeObj(params, customModelList = []) {\n    let obj = { ...params };\n    if ([TABLE_TYPES.BOOL, '_id'].includes(obj.type) && obj.default !== undefined && obj.default !== null) obj.default = obj.default === 'true';\n    else if (obj.filter === 'AS_DEFINED' || (dbType !== DB_TYPE.MONGODB && isNumberType(obj.type, TABLE_TYPES))) {\n      obj.default = obj.default ?? undefined;\n      // if (obj.type === TABLE_TYPES.NUMBER) obj.default = obj.default ? parseInt(obj.default) : undefined;\n      // else obj.default = obj.default || undefined;\n    } else if (obj.filter === 'NULL') {\n      obj.default = null;\n    } else obj.default = undefined;\n\n    if (obj.ref) {\n      if (isEmpty(customModelList)) {\n        obj.ref = modelList.find((m) => m._id === obj.ref)?.name;\n      } else {\n        // if already in current model with name exits with different case that time in ref name changes\n        const customModelName = customModelList.find((m) => m._id === obj.ref)?.name;\n        const createdModelName = modelList.find((m) => m.name.toLowerCase() === customModelName.toLowerCase())?.name;\n        obj.ref = createdModelName ?? customModelName;\n      }\n      delete obj.refName;\n    }\n\n    if (obj.type === TABLE_TYPES.VIRTUAL_RELATION && !obj.localField) {\n      obj.localField = '_id';\n    }\n\n    obj = {\n      ...obj,\n      minLength: obj.minLength ? parseInt(obj.minLength) : undefined,\n      maxLength: obj.maxLength ? parseInt(obj.maxLength) : undefined,\n      min: obj.min ? parseInt(obj.min) : undefined,\n      max: obj.max ? parseInt(obj.max) : undefined,\n    };\n\n    if (obj.type) {\n      // data type validation\n      const disable = getDisableField(obj.type, { isAutoIncrement: obj.isAutoIncrement }, dbType, {\n        currentApplicationCode,\n      });\n      Object.keys(obj).map((k) => {\n        if (disable[k] && (obj?.attr !== '_id' && obj.attr !== 'id')) { // to not remove disabled fields' value if attribute is '_id' or 'id'\n          delete obj[k];\n        }\n        return k;\n      });\n    }\n\n    obj = omit(obj, ['isExpand', 'key', 'filter', 'attr', 'rowKey']);\n\n    if (dbType !== DB_TYPE.MONGODB) {\n      // for sequelize\n      if (obj.type === TABLE_TYPES.DATE && dbType === DB_TYPE.POSTRAGSQL && obj.default) {\n      // convert DATE to TIMESTAMP for POSTRAGSQL DB\n        obj.default = getUnixTimestamp(obj.default);\n      } else if ((dbType === DB_TYPE.MYSQL || dbType === DB_TYPE.SQL) && (obj.type === TABLE_TYPES.DATE || obj.type === TABLE_TYPES.TIMESTAMP) && obj.default) {\n        obj.default = dateTimeFormatter(obj.default, dateTimeFormat);\n      } else if ((obj.type === TABLE_TYPES.DATEONLY) && obj.default) {\n        obj.default = dateTimeFormatter(obj.default, dateFormat);\n      }\n      obj.relType = obj.ref ? obj.relType : undefined;\n    } else if (dbType === DB_TYPE.MONGODB && obj.type === TABLE_TYPES.DATE && obj.default) {\n      // mongoose store in ISO format\n      obj.default = setDateToISO(obj.default);\n    }\n\n    // remove extra attribute from json\n    obj = getParsedKeys(obj, dbType);\n    obj.match = obj.match || undefined;\n    return filterObjectUndefinedValues(obj);\n  }\n\n  const tableToCodeViewParser = React.useCallback((options = {}) => {\n    // convert array to object\n    if (activeTab !== SCHEMA_TAB.TABLE_VIEW) return; // parser need only when TABLE_VIEW is active tab\n\n    const newTable = options?.tableArr ? cloneDeep(options?.tableArr) : cloneDeep(tableJson);\n    if (newTable?.length <= 0) return;\n    const parsedObj = {};\n    const tempSetting = {};\n\n    newTable.forEach((x) => {\n      const tempSubSetting = {};\n      const obj = { ...x };\n      if (!obj.attr) return; // attribute is required\n      if (dbType === DB_TYPE.MONGODB && (obj.type === TABLE_TYPES.JSON || obj.type === TABLE_TYPES.ARRAY)) {\n        // manage sub-rows\n        const tempArray = [];\n        const tempObj = {};\n\n        if (dbType === DB_TYPE.MONGODB && obj?.type === TABLE_TYPES.ARRAY) {\n          // eslint-disable-next-line no-debugger\n          if (!options?.isExcludeArrayId && !obj.subRows?.find((s) => s.type === '_id')) { // default value false of__id for type array only\n            let idArr = [];\n            // exclude _id if no sub-attr\n            idArr = [{\n              key: `rs${obj.subRows?.length ? obj.subRows.length - 1 : 0}`, attr: '_id', default: 'false', type: '_id', rowKey: obj.key,\n            }];\n            obj.subRows = extend(obj.subRows || [], idArr);\n          // eslint-disable-next-line no-prototype-builtins\n          } else if (options?.isExcludeArrayId && obj.subRows?.length === 1 && obj.subRows[0].hasOwnProperty('_id')) {\n            delete obj.subRows;\n          } else if (options?.isExcludeArrayId && obj.subRows?.length > 0) {\n            obj.subRows.push({ _id: false });\n            tempObj._id = false;\n          }\n        }\n\n        obj.subRows?.forEach((rs) => {\n          if (!rs.attr) return; // attribute is required\n          tempObj[rs.attr] = prepareCodeObj(rs, options?.customModelList);\n          if (tempObj[rs.attr]?.enum && tempObj[rs.attr]?.isEnum) {\n            // add if isenum is selected\n            tempSubSetting[rs.attr] = { enum: tempObj[rs.attr]?.enum, isEnum: true };\n          } else if (!tempObj?.[rs.attr]?.isEnum && tempSubSetting?.[rs.attr]?.enum) {\n            // remove if isenum is de-selected\n            delete tempSubSetting[rs.attr];\n          }\n          delete tempObj[rs.attr]?.enum;\n          delete tempObj[rs.attr]?.isEnum;\n\n          // Mark attribute as private\n          // if (tempObj[rs.attr]?.private) {\n          // // prepare obj\n          //   tempSubSetting[rs.attr] = extend(tempSubSetting[rs.attr], { private: true });\n          // } else if (tempSubSetting[rs.attr]?.private && !tempObj[rs.attr]?.private) {\n          // // remove from obj\n          //   delete tempSubSetting[rs.attr].private;\n          // }\n        });\n        if (obj.subRows?.length > 0 && !isEmpty(tempObj)) {\n          tempArray.push(tempObj);\n          parsedObj[x.attr] = obj.type === TABLE_TYPES.JSON ? tempObj : tempArray;\n          tempSetting[x.attr] = tempSubSetting; // GEN team are not managing array enum\n          // tempSetting[x.attr] = obj.type === TABLE_TYPES.JSON ? tempSubSetting : [tempSubSetting];\n        } else parsedObj[x.attr] = { type: obj.type };\n      } else {\n        delete obj.subRows;\n        parsedObj[x.attr] = prepareCodeObj(obj, options?.customModelList);\n        if (parsedObj[x.attr].enum && parsedObj[x.attr].isEnum) {\n          // add if isenum is selected\n          tempSetting[x.attr] = extend(tempSetting[x.attr] || {}, { enum: parsedObj[x.attr].enum, isEnum: true });\n        } else if (!parsedObj[x.attr].isEnum) {\n          // remove if isenum is de-selected\n          delete tempSetting[x.attr]?.enum;\n          delete tempSetting[x.attr]?.isEnum;\n        }\n        delete parsedObj[x.attr].enum;\n        delete parsedObj[x.attr].isEnum;\n\n        // Mark attribute as private\n        // if (parsedObj[x.attr]?.private === true) {\n        //   // prepare obj\n        //   tempSetting[x.attr] = extend(tempSetting[x.attr], { private: true });\n        // } else if (tempSetting[x.attr]?.private === true && !parsedObj[x.attr]?.private) {\n        //   // remove from obj\n        //   delete tempSetting[x.attr].private;\n        // }\n      }\n    });\n    // set state only when unequal\n    if (!isEqual(code, JSON.stringify(parsedObj))) {\n      // eslint-disable-next-line consistent-return\n      if (options?.isReturnJson) return parsedObj;\n      setCode(JSON.stringify(parsedObj));\n    }\n    // if (!isEqual(customSetting, tempSetting)) { commented because not getting updated customSetting\n    setCustomSetting(tempSetting);\n    // }\n    if (options?.isSave) {\n      requestAnimationFrame(() => {\n        saveJSON({\n          tDependency: options.tDependency, loaderCallBack: options.loaderCallBack, msg: options.msg, showMsg: true, tCode: JSON.stringify(parsedObj), tcustomSetting: tempSetting, indexes: options.indexes,\n        });\n      });\n    }\n  }, [modelList, tableJson, activeTab, saveJSON, customSetting, dbType, code]);\n\n  React.useMemo(() => {\n    prepareTableView({});\n  }, [code]);\n\n  React.useMemo(() => {\n    if (!dbType) return;\n    tableToCodeViewParser();\n  }, [tableJson, dbType]);\n\n  const handleTabSelect = React.useCallback((next, cur) => {\n    setMainActiveTab(next);\n    if (next === cur) return;\n    if (cur === TABS.SCHEMA_TAB && activeTab === SCHEMA_TAB.TABLE_VIEW) {\n      // tableToCodeViewParser();\n    }\n  }, [activeTab, tableToCodeViewParser]);\n\n  const value = {\n    code,\n    setCode,\n    tableJson,\n    setTableJson,\n    tableToCodeViewParser, // table to code view parser\n    prepareTableView, // code to table view parser\n    activeTab,\n    setActiveTab,\n    customSetting,\n    setCustomSetting,\n    modelList,\n    currentId,\n    currentModel,\n    hooks,\n    setHooks,\n    listRef,\n    handleTabSelect,\n    saveJSON,\n    handleAddRow,\n    mainActiveTab,\n    TABLE_TYPES,\n    dbType,\n    ormType,\n    setDependency,\n    dependency,\n    currentApplicationCode,\n  };\n  return <EditorContext.Provider value={value}>{children}</EditorContext.Provider>;\n});\n\nfunction useEditor() {\n  const context = React.useContext(EditorContext);\n  if (context === undefined) {\n    throw new Error('useEditor must be used within a EditorProvider');\n  }\n  return context;\n}\nEditorProvider.displayName = 'EditorProvider';\nexport { EditorProvider, useEditor };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/EditorTabs.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable radix */\nimport React from 'react';\n\nimport { useSelector } from 'react-redux';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport { isArray } from 'lodash';\nimport { TabCSs } from '../../../../assets/css/tab';\n\nimport {\n  DB_TYPE, HOOK_TAB_TITLE,\n} from '../../../../constant/model';\nimport { HookSetup } from '../HookSetup';\nimport TableView from './TableView';\nimport { useEditor } from './EditorProvider';\nimport { MongoIndexing } from '../Indexing/Mongodb/index';\nimport { SQLIndexing } from '../Indexing/SQLIndexing/index';\nimport { useIndex } from '../Indexing/SQLIndexing/IndexProvider';\n\nexport const EditorTabs = React.memo(React.forwardRef(({\n  jsonError, setJsonError,\n}, ref) => {\n  const {\n    code, activeTab, customSetting, hooks, tableToCodeViewParser,\n    handleTabSelect, mainActiveTab, dbType, dependency,\n  } = useEditor();\n  const { modelIndexList } = useIndex();\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n\n  React.useImperativeHandle(ref, () => ({\n    code, customSetting, hooks, tableToCodeViewParser, modelIndexList, activeTab, mainActiveTab, dependency,\n  }));\n\n  React.useMemo(() => {\n    if (isArray(hooks)) {\n      const isErr = hooks.find((x) => x.isErr)?.isErr;\n      if (isErr) {\n        setJsonError(isErr);\n      } else if (!isErr && jsonError?.isHookErr) {\n        setJsonError(false);\n      }\n    }\n  }, [hooks]);\n\n  return (\n    <>\n      <Tabs\n        selectedTabClassName={TabCSs.selectTab}\n        selectedTabPanelClassName=\"flex-grow h-0\"\n        className=\"relative flex-grow flex flex-col h-full\"\n        onSelect={handleTabSelect}\n      >\n        <TabList\n          className={`${TabCSs.tabHead} flex items-center justify-between pt-0 pr-5 modelTab relative flex-shrink-0`}\n        >\n          <div className=\"flex items-center\">\n            <Tab className={TabCSs.tabTitle}>\n              Schema\n            </Tab>\n            <Tab className={TabCSs.tabTitle}>{HOOK_TAB_TITLE[currentApplicationCode]}</Tab>\n            <Tab className={TabCSs.tabTitle}>Indexing</Tab>\n          </div>\n        </TabList>\n        <TabPanel>\n          <div className=\"h-full\">\n            <TableView />\n          </div>\n        </TabPanel>\n        <TabPanel>\n          <HookSetup\n            ref={{}}\n          />\n        </TabPanel>\n        <TabPanel>\n          {dbType === DB_TYPE.MONGODB ? <MongoIndexing /> : <SQLIndexing />}\n        </TabPanel>\n      </Tabs>\n\n    </>\n  );\n}));\nEditorTabs.displayName = 'EditorTabs';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/ModelHeader/index.js",
    "content": "/* eslint-disable no-param-reassign */\nimport React from 'react';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { useBoolean } from '../../../../../components/hooks';\nimport { setCurrentModelProperty, updateModelDependency } from '../../../../../redux/reducers/models';\nimport { InlineHeader } from '../../../../../components/InlineHeader';\nimport { updateModelApi } from '../../../../../api/models';\nimport {\n  DB_CONST, DB_TYPE,\n  //  MODEL_NAME_LENGTH,\n  mongoDbModalName, pluralizeTableName, SQL_MODEL_NAME_LENGTH,\n} from '../../../../../constant/model';\nimport { useToastNotifications } from '../../../../hooks';\nimport { nodeKeyRegex } from '../../../../../utils/regex';\n\nconst ModelHeader = React.memo(({\n  currentId, currentModel = {}, updateRef,\n}) => {\n  const dispatch = useDispatch();\n  const {\n    currentApplicationCode, dbType, applicationId,\n  } = useSelector(({ projects }) => ({\n    dbType: DB_CONST[projects.applicationDatabase.databaseType],\n    currentApplicationCode: projects.currentApplicationCode,\n    applicationId: projects.currentApplicationId,\n  }), shallowEqual);\n  const [edit, setShowEdit, setHideEdit] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const handleUpdate = React.useCallback((req = {}) => {\n    const modelName = req?.name || currentModel.name;\n\n    updateModelApi({\n      description: currentModel.description,\n      customJson: currentModel.customJson,\n      definitionType: currentApplicationCode,\n      ...req,\n      name: modelName,\n      tableName: pluralizeTableName(modelName, currentApplicationCode),\n    }, currentId).then((data) => {\n      dispatch(updateModelDependency({\n        response: data?.data, request: req, dbType, currentModel,\n      }));\n      addSuccessToast(data.message);\n    }).catch((err) => {\n      addErrorToast(err);\n    });\n  }, [currentModel, applicationId, currentId, currentApplicationCode]);\n\n  const handleModelProperty = React.useCallback((key, value, modelId) => {\n    handleUpdate({ [key]: value, ...(key === 'name' && { tableName: pluralizeTableName(value, currentApplicationCode) }) });\n    dispatch(setCurrentModelProperty({ modelId, key, value }));\n    if (key === 'name') { // set tableName value based on model name\n      dispatch(setCurrentModelProperty({ modelId, key: 'tableName', value: pluralizeTableName(value, currentApplicationCode) }));\n    }\n  }, [currentModel]);\n\n  React.useImperativeHandle(updateRef, () => ({ setHideEdit }));\n\n  return (\n    <InlineHeader\n      titleRegex={dbType === DB_TYPE.MONGODB ? mongoDbModalName : nodeKeyRegex}\n      defaultValue={currentModel}\n      currentId={currentId}\n      onBlurEvent={handleModelProperty}\n      edit={edit}\n      setShowEdit={setShowEdit}\n      setHideEdit={setHideEdit}\n      titlePlaceHolder=\"Model\"\n      titleLength={SQL_MODEL_NAME_LENGTH}\n      isDisableNameEdit={currentModel?.isDefault}\n      showTableName\n      dbType={dbType}\n      currentApplicationCode={currentApplicationCode}\n    />\n  );\n});\nModelHeader.displayName = 'ModelHeader';\nexport default ModelHeader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/ModelProvider.js",
    "content": "import React, { useState } from 'react';\nimport { flatten } from 'lodash';\nimport { useBoolean } from '../../../../components/hooks';\n\nexport const ModelContext = React.createContext();\n\nconst ModelProvider = React.memo(({ children }) => {\n  const [modelErrors, setModelErrors] = useState();\n  const [modelErrCount, setModelErrCount] = useState(0);\n  const [isJsonError, setIsJsonError] = useState(false);\n  const [isChangeInTable, setChangeInTable, setNoChangeInTable] = useBoolean(false);\n  const changeNextEvent = React.useRef();\n  const [isSaveWarning, setSaveWarning, hideSaveWarning] = useBoolean(false);\n\n  React.useEffect(() => {\n    if (!modelErrors) return;\n    const count = flatten(modelErrors.map((x) => x.error))?.length;\n    setModelErrCount(count);\n  }, [modelErrors]);\n\n  const isError = React.useCallback((name) => modelErrors?.find((x) => x.modelName === name), [modelErrors]);\n\n  const value = {\n    modelErrors,\n    setModelErrors,\n    modelErrCount,\n    setModelErrCount,\n    isError,\n    isJsonError,\n    setIsJsonError,\n    setChangeInTable,\n    setNoChangeInTable,\n    isChangeInTable,\n    setChangeNextEvent: (event) => {\n      changeNextEvent.current = event;\n    },\n    changeNextEvent, // when model some changes and do next event for store that\n    hideSaveWarning,\n    setSaveWarning,\n    isSaveWarning,\n  };\n  return <ModelContext.Provider value={value}>{children}</ModelContext.Provider>;\n});\n\nfunction useModel() {\n  const context = React.useContext(ModelContext);\n  if (context === undefined) {\n    throw new Error('useModel must be used within a ModelProvider');\n  }\n  return context;\n}\nModelProvider.displayName = 'ModelProvider';\nexport { ModelProvider, useModel };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/AddRelation/index.js",
    "content": "import React, { useState } from 'react';\nimport Popover from 'react-popover';\nimport { Icons } from '@dhiwise/icons';\nimport { TableViewCss } from '../../../../../../assets/css/tableViewCss';\nimport { Select } from '../../../../../../components';\nimport { RELATION_TYPE, SEQUELIZE_RELATION_TYPE } from '../../../../../../constant/model';\nimport { onSingleKeyDown } from '../../../../../../utils/domMethods';\nimport { useEditor } from '../../EditorProvider';\nimport { useModel } from '../../ModelProvider';\n\nconst FiledPosition = {\n  model: 1,\n  foreignField: 2, // isVirtual\n  refAttribute: 2, // isSql\n  relType: 3, // isSql\n};\n\nexport const AddRelation = React.memo(({\n  modelList, currentId, onInputChange, model, isVirtual, foreignKey, id, onKeyDown, CONST_VARIABLE,\n  isSql, type, row, disabled, ...otherProps\n}) => {\n  const { tableJson } = useEditor();\n  const { TABLE_TYPES } = CONST_VARIABLE;\n  const [isPopoverOpen, setIsPopoverOpen] = useState(false);\n  const [modelRef, setModelRef] = React.useState(null);\n  const [modelName, setModelName] = React.useState(null);\n  const [foreignKeys, setForeignKeys] = React.useState([]);\n  const [refAttrOptions, setRefAttrOptions] = React.useState([]);\n  const [foreignField, setForeignField] = React.useState(foreignKey);\n  const [refAttribute, setRefAttribute] = React.useState();\n  const [relType, setRelType] = React.useState(); // default \"hasMany\"\n  const { setChangeInTable } = useModel();\n\n  React.useEffect(() => setRefAttribute(otherProps?.refAttribute), [otherProps?.refAttribute]);\n  React.useEffect(() => setRelType(otherProps?.relType || RELATION_TYPE.HAS_MANY), [otherProps?.relType]);\n  const curModel = React.useMemo(() => modelList?.find((m) => m._id === currentId), [modelList, currentId]);\n\n  const onKeyDownHandle = (e, focusField) => {\n    if (!isVirtual && !isSql) return;\n    onSingleKeyDown(e, focusField, FiledPosition, 'relation');\n  };\n\n  React.useEffect(() => {\n  // added curModel dependency as update in model name\n    setModelRef(model);\n    setModelName(modelList?.find((m) => m._id === model)?.name);\n  }, [model, curModel]);\n\n  React.useMemo(() => {\n    const cmodel = modelList?.find((m) => m._id === modelRef);\n    // const curModel = modelList?.find((m) => m._id === currentId);\n    if (isVirtual && cmodel?.schemaJson) {\n      const fields = Object.keys(cmodel.schemaJson).filter((s) => (cmodel.schemaJson[s]?.ref === curModel?.name\n        && cmodel.schemaJson[s]?.type === TABLE_TYPES.OBJECTID));\n      if (fields?.length > 0) setForeignKeys(fields.map((x) => ({ id: x, name: x }))); // ff\n      else setForeignKeys([]);\n    }\n    if (isSql && cmodel?.schemaJson) {\n      // filter selected model attribute having same selected model-type ('String')\n      let fields = [];\n      if (modelRef === currentId) {\n        // same model relation - the same attribute should not be allowed\n        fields = tableJson?.filter((x) => x.attr !== row?.attr && x.type === type).map((x) => x.attr);\n      } else {\n        fields = Object.keys(cmodel.schemaJson).filter(\n          (s) => (type === cmodel.schemaJson[s]?.type),\n        );\n      }\n      if (fields?.length > 0) setRefAttrOptions(fields.map((x) => ({ id: x, name: x })));\n      else setRefAttrOptions([]);\n    }\n  }, [modelRef, currentId, tableJson, type, row?.attr]);\n\n  const showPopup = () => {\n    if (disabled) return;\n    setIsPopoverOpen(!isPopoverOpen);\n    onInputChange('ref', modelRef);\n    if (isVirtual) { onInputChange('foreignField', foreignField); }\n    if (isSql) {\n      onInputChange('refAttribute', refAttribute);\n      onInputChange('relType', relType);\n    }\n  };\n\n  const handleKeyDown = (e) => {\n    if (e?.keyCode === 27) {\n      showPopup(); // close modal on ESC\n      const ele = document.querySelector(`#${id}`);\n      ele?.focus();\n    }\n  };\n\n  React.useEffect(() => {\n    if (!isPopoverOpen) {\n      // onInputChange('ref', modelRef);\n      // onInputChange('foreignField', foreignField);\n    } else {\n      const nextfield = document.querySelector('#model-relation input');\n      nextfield?.focus();\n      window.addEventListener('keydown', handleKeyDown);\n    }\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown);\n    };\n  }, [isPopoverOpen]);\n\n  const handleChange = (val) => {\n    if (!val || refAttribute) setRefAttribute();\n    if (foreignField) setForeignField();\n    setModelRef(val);\n    const cmodel = modelList.find((m) => m._id === val);\n    setModelName(cmodel?.name);\n    if (isVirtual && cmodel.schemaJson) {\n      const fields = Object.keys(cmodel.schemaJson).filter((s) => (cmodel.schemaJson[s]?.type === TABLE_TYPES.OBJECTID));\n      if (fields?.length > 0) setForeignKeys(fields.map((x) => ({ id: x, name: x }))); // ff\n      else setForeignKeys([]);\n    }\n    setChangeInTable();\n  };\n\n  return (\n    <>\n      <Popover\n        body={[\n          <div key={id} id=\"model-relation\" className={`grid grid-cols-1 gap-5 w-56 ${(isVirtual || isSql) && 'grid-cols-2  w-96'}`}>\n            <Select\n              isClearable={false}\n              WrapClassName=\"w-full\"\n              placeholder=\"Select model\"\n              options={isVirtual ? modelList.filter((m) => m._id !== currentId) : modelList}\n              label=\"Model\"\n              value={modelRef}\n              onChange={handleChange}\n              valueKey=\"_id\"\n              labelKey=\"name\"\n              name=\"model\"\n              noOptionsMessage=\"Please create new model to give reference.\"\n              inputId={`relation${FiledPosition.model}`}\n              onKeyDown={(e) => {\n                if (e.ctrlKey || e.keyCode === 13) {\n                  onKeyDownHandle(e, 'model');\n                  if (e.ctrlKey) e.preventDefault();\n                }\n              }}\n            />\n            {\n              isVirtual && (\n                <Select\n                  WrapClassName=\"w-full\"\n                  placeholder=\"Select foreign field\"\n                  options={foreignKeys}\n                  label=\"Foreign field\"\n                  value={foreignField}\n                  onChange={setForeignField}\n                  disabled={!modelRef}\n                  valueKey=\"id\"\n                  labelKey=\"name\"\n                  name=\"foreignField\"\n                  inputId={`relation${FiledPosition.foreignField}`}\n                  onKeyDown={(e) => {\n                    if (e.ctrlKey || e.keyCode === 13) {\n                      onKeyDownHandle(e, 'foreignField');\n                      if (e.ctrlKey) e.preventDefault();\n                    }\n                  }}\n                />\n              )\n            }\n            {\n              isSql && (\n              <>\n                <Select\n                  WrapClassName=\"w-full\"\n                  placeholder=\"Select attribute\"\n                  options={refAttrOptions}\n                  label=\"Attribute\"\n                  value={refAttribute}\n                  onChange={setRefAttribute}\n                  disabled={!modelRef}\n                  valueKey=\"id\"\n                  labelKey=\"name\"\n                  name=\"refAttribute\"\n                  inputId={`relation${FiledPosition.refAttribute}`}\n                  onKeyDown={(e) => {\n                    if (e.ctrlKey || e.keyCode === 13) {\n                      onKeyDownHandle(e, 'refAttribute');\n                      if (e.ctrlKey) e.preventDefault();\n                    }\n                  }}\n                />\n                <div className=\"col-span-2\">\n                  <Select\n                    WrapClassName=\"w-full\"\n                    placeholder=\"Select type\"\n                    isClearable={false}\n                    options={SEQUELIZE_RELATION_TYPE}\n                    label=\"Type\"\n                    value={relType}\n                    onChange={setRelType}\n                    name=\"relType\"\n                    inputId={`relation${FiledPosition.relType}`}\n                    onKeyDown={(e) => {\n                      if (e.ctrlKey || e.keyCode === 13) {\n                        onKeyDownHandle(e, 'relType');\n                        if (e.ctrlKey) e.preventDefault();\n                      }\n                    }}\n                  />\n                </div>\n              </>\n              )\n            }\n          </div>,\n        ]}\n        isOpen={isPopoverOpen}\n        onOuterAction={showPopup}\n        refreshIntervalMs={10}\n        enterExitTransitionDurationMs={10}\n        tipSize={10}\n        className=\"popupCustom\"\n      >\n        <span\n          onClick={showPopup}\n          onKeyDown={(e) => {\n            onKeyDown(e, 'relation');\n            if (e.keyCode === 13) {\n              showPopup();\n            }\n          }}\n          tabIndex=\"0\"\n          className={`${TableViewCss.addValue}${disabled ? ' opacity-50 cursor-not-allowed' : ''}`}\n          id={id}\n        >\n\n          <div className=\"w-4 h-4 mr-2\">\n            <Icons.Add />\n          </div>\n          {\n            modelRef ? `Edit ${isVirtual ? 'virtual' : ''} relation - ${modelName}` : `Add ${isVirtual ? 'virtual' : ''} relation`\n          }\n        </span>\n      </Popover>\n    </>\n  );\n});\nAddRelation.displayName = 'AddRelation';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/Enum/SelectEnumValue.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport { isEmpty } from 'lodash';\nimport React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport {\n  Select,\n} from '../../../../../../components';\n\nexport const SelectEnumValue = ({\n  onInputChange, enumObj, disabled, id, onKeyDown, defaultValue,\n}) => {\n  const selectRef = React.useRef(null);\n  const [enumValue, setEnumValue] = React.useState();\n  const constantList = useSelector((state) => state.constants.constantList);\n  const [options, setOptions] = useState([]);\n\n  React.useMemo(() => {\n    if (!enumObj?.enumFile || !enumObj?.enumAttribute || !constantList) return;\n    const valOpt = [];\n    constantList.map((c) => {\n      if (c) {\n        if (c?.fileName === enumObj?.enumFile && c?.customJson) {\n        // Object.keys(c.customJson)?.map((y) => {\n          const attrArr = enumObj?.enumAttribute.split('.');\n          let obj = c.customJson || {};\n          attrArr.map((a) => {\n            obj = obj[a];\n            return a;\n          });\n\n          if (!isEmpty(obj)) {\n            Object.keys(obj).map((v) => {\n              valOpt.push({ id: obj[v], name: v });\n              return v;\n            });\n          }\n        }\n      }\n      return c;\n    });\n\n    setOptions(valOpt);\n  }, [enumObj?.enumFile, enumObj?.enumAttribute, constantList]);\n\n  React.useMemo(() => {\n    if (enumValue && !options?.find((x) => x.id === enumValue)) {\n      onInputChange('enum', {\n        ...enumObj, default: undefined,\n      });\n      onInputChange('default', '');\n    }\n  }, [constantList]);\n\n  // React.useEffect(() => { setEnumValue(row?.default); }, [row?.default]);\n  React.useEffect(() => { setEnumValue(defaultValue); }, [defaultValue]);\n\n  const handleChange = React.useCallback((value) => {\n    setEnumValue(value);\n    onInputChange('default', value);\n    onInputChange('enum', { ...enumObj, default: options.find((x) => x.id === value)?.name });\n  }, [onInputChange, enumObj, options]);\n\n  return (\n    <>\n      <Select\n        ref={selectRef}\n        disabled={disabled}\n        name=\"default\"\n        sizeSmall\n        placeholder=\"Select Default value\"\n        WrapClassName=\"w-full mt-1\"\n        options={options}\n        value={enumValue !== undefined && enumValue !== null && options?.find((x) => x.id === enumValue) ? enumValue : null}\n        onChange={handleChange}\n        inputId={id}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && selectRef?.current?.state?.menuIsOpen) {\n              return;\n            }\n            onKeyDown(e);\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/Enum/index.js",
    "content": "import React, { useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport Popover from 'react-popover';\nimport { Icons } from '@dhiwise/icons';\nimport { isArray, isEmpty, omit } from 'lodash';\nimport { listConstants } from '../../../../../../redux/thunks/constants';\nimport {\n  Checkbox, Heading, SelectTree, Select, IconBox,\n} from '../../../../../../components';\nimport { onSingleKeyDown } from '../../../../../../utils/domMethods';\n\nconst FiledPosition = {\n  enumFile: 1,\n  constAttr: 2,\n};\n\nexport const Enum = React.memo(({\n  row, onInputChange, disabled, id, onKeyDown,\n}) => {\n  const [isPopoverOpen, setIsPopoverOpen] = useState(false);\n  const [enumFile, setEnumFile] = React.useState();\n  const [isEnum, setIsEnum] = React.useState(row?.isEnum);\n  const [enumAttribute, setEnumAttribute] = React.useState();\n  const dispatch = useDispatch();\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const constantList = useSelector((state) => state.constants.constantList);\n  const attrOptions = React.useMemo(() => {\n    let tempJson = constantList?.find((c) => c?.fileName === enumFile)?.customJson || {};\n    if (!isEmpty(tempJson)) {\n      // enum attribute options value having type object only (user_type:{admin:1})\n      Object.keys(tempJson).forEach((x) => {\n        if (typeof tempJson?.[x] === 'object' && !isArray(tempJson[x])) {\n          // allow\n        } else {\n          tempJson = omit(tempJson, x);\n        }\n      });\n    }\n    return tempJson;\n  }, [constantList, enumFile]);\n\n  const fetchAllConstant = () => {\n    dispatch(listConstants({\n      applicationId,\n      isActiveDeactivateDisplay: true,\n    }));\n  };\n\n  React.useEffect(() => { if (isPopoverOpen) fetchAllConstant(); }, [isPopoverOpen]);\n\n  React.useEffect(() => { setEnumFile(row?.enum?.enumFile); }, [row?.enum?.enumFile]);\n  React.useEffect(() => { setEnumAttribute(row?.enum?.enumAttribute); }, [row?.enum?.enumAttribute]);\n  React.useMemo(() => { setIsEnum(row?.isEnum); }, [row?.isEnum]);\n  React.useMemo(() => {\n    if (enumFile && !constantList?.find((x) => x?.fileName === enumFile)) {\n      onInputChange('enum', {\n        ...row?.enum,\n        enumFile: null,\n      });\n    }\n    if (enumAttribute && attrOptions && !Object.keys(attrOptions)?.find((x) => x === enumAttribute)) {\n      onInputChange('enum', {\n        ...row?.enum,\n        enumAttribute: '',\n      });\n    }\n  }, [constantList]);\n\n  const showPopup = React.useCallback(() => {\n    if (isPopoverOpen && isEnum) {\n      // if popup is open and at a time closing\n      if (row?.enum?.enumAttribute !== enumAttribute) {\n        onInputChange('enum', {\n          ...row?.enum,\n          enumAttribute,\n          enumFile,\n        });\n      }\n    }\n    setIsPopoverOpen(!isPopoverOpen);\n  }, [isPopoverOpen, isEnum, row, onInputChange, enumAttribute]);\n\n  const onKeyDownHandle = (e, focusField) => {\n    onSingleKeyDown(e, focusField, FiledPosition, 'enum', { inputWithId: focusField === 'enumFile' });\n  };\n\n  const handleKeyDown = React.useCallback((e) => {\n    if (e?.keyCode === 27) {\n      showPopup(); // close modal on ESC\n      const ele = document.querySelector(`#${id}`);\n      ele?.focus();\n    }\n  }, [showPopup, id]);\n\n  React.useMemo(() => {\n    // if (!isPopoverOpen && isEnum) {\n    // commented for => if popup is open and at a time closing\n    //   if (row?.enum?.enumAttribute !== enumAttribute) {\n    //     onInputChange('enum', {\n    //       enumAttribute, enumFile,\n    //     });\n    //   }\n    // }\n\n    if (isPopoverOpen) {\n      // focus on first field\n      const nextfield = document.querySelector('#enum input');\n      nextfield?.focus();\n      window.addEventListener('keydown', handleKeyDown);\n    }\n    return () => {\n      window.removeEventListener('keydown', handleKeyDown);\n    };\n  }, [isPopoverOpen, isEnum]);\n\n  const handleChange = React.useCallback((value) => {\n    setEnumFile(value);\n    if (enumAttribute) setEnumAttribute();\n    // requestAnimationFrame(() => { //remove focus onBlur\n    //   onAutoFocus?.('enumFile', 'enum'); // manage auto focus\n    // });\n  }, [enumAttribute]);\n\n  const handleChangeAttr = React.useCallback((value) => {\n    setEnumAttribute(value?.currentSelectedNode?.fullName);\n  }, []);\n\n  const handleChangeEnum = React.useCallback((val) => {\n    onInputChange('isEnum', val);\n    setIsEnum(val);\n    setIsPopoverOpen(val);\n  }, []);\n\n  const WrapCheckbox = React.useCallback(() => (\n    <Checkbox\n      name=\"isEnum\"\n      checked={!!isEnum}\n      disabled={disabled}\n      onChange={handleChangeEnum}\n      id={id}\n      onKeyDown={(e) => {\n        if (e.keyCode === 13) {\n          handleChangeEnum(!e?.target?.checked);\n        }\n        onKeyDown(e);\n      }}\n    >\n      <span className={`ml-2 text-xs ${disabled ? ' cursor-not-allowed' : ''}`}>\n        Enum setup\n      </span>\n    </Checkbox>\n  ), [isEnum, disabled, id, onKeyDown, handleChangeEnum]);\n\n  const handleRefresh = () => {\n    fetchAllConstant();\n  };\n\n  return (\n    <>\n      <Popover\n        body={[\n          <div className=\"w-80\" id=\"enum\" key=\"enumKey\">\n            <div className=\"border-b border-gray-90 pb-3 flex items-center justify-between\">\n              <Heading variant=\"h5\">\n                Constant selection\n              </Heading>\n              <div className=\"flex items-center\">\n                <IconBox\n                  icon={<Icons.Plus color=\"#ffffff\" />}\n                  variant=\"primary\"\n                  tooltip=\"Add constant\"\n                  size=\"small\"\n                  onClick={() => {\n                    window.open('/node/constant');\n                  }}\n                />\n                <IconBox variant=\"outline\" tooltip=\"Refresh\" size=\"small\" className=\"ml-2\" icon={<Icons.Refresh />} onClick={handleRefresh} />\n              </div>\n            </div>\n            <div className=\"mt-4 grid grid-cols-1 gap-4\">\n              <Select\n                name=\"enumFile\"\n                isClearable={false}\n                label=\"Constant file\"\n                placeholder=\"Select constant file\"\n                labelKey=\"fileName\"\n                valueKey=\"fileName\"\n                options={constantList}\n                value={enumFile}\n                onChange={handleChange}\n                inputId={`enum${FiledPosition.enumFile}`}\n                onKeyDown={(e) => {\n                  if (e.ctrlKey || e.keyCode === 13) {\n                    if (e.ctrlKey) e.preventDefault();\n                    onKeyDownHandle(e, 'enumFile');\n                  }\n                }}\n              />\n\n              <SelectTree\n                id={`enum${FiledPosition.constAttr}`}\n                name=\"constAttr\"\n                label=\"Enum attribute\"\n                texts={{ placeholder: 'Select enum attribute' }}\n                placeholder=\"Select enum attribute\"\n                mode=\"radioSelect\"\n                disabled={!enumFile}\n                data={attrOptions}\n                defaultValue={enumAttribute ? [enumAttribute] : []} // set value in array as per package\n                handleChange={handleChangeAttr}\n                onKeyDown={(e) => {\n                  if (e.ctrlKey || e.keyCode === 13) {\n                    onKeyDownHandle(e, 'constAttr');\n                    if (e.ctrlKey) e.preventDefault();\n                  }\n                }}\n              />\n            </div>\n          </div>,\n        ]}\n        isOpen={isPopoverOpen}\n        onOuterAction={showPopup}\n        refreshIntervalMs={10}\n        enterExitTransitionDurationMs={10}\n        tipSize={10}\n        place={null}\n        className=\"popupCustom\"\n      >\n        {/* <div className=\"flex items-center\" id={`${row.key}isEnum`}> */}\n        <div className={`flex items-center${disabled ? ' opacity-50 cursor-not-allowed' : ''}`}>\n          <WrapCheckbox />\n          <div\n            className={`w-2.5 h-2.5 ml-2 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}\n            onClick={disabled ? null : showPopup}\n          >\n            <Icons.DownArrow />\n          </div>\n        </div>\n      </Popover>\n    </>\n  );\n});\nEnum.displayName = 'Enum';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/DeleteRow.js",
    "content": "import React from 'react';\nimport { isArray, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { TableViewCss } from '../../../../../../assets/css/tableViewCss';\nimport { ConfirmationAlert } from '../../../../../../components';\nimport { useToastNotifications } from '../../../../../hooks';\nimport { useEditor } from '../../EditorProvider';\nimport useBoolean from '../../../../../../components/hooks/useBoolean';\n\nexport const RowDeleteMessage = 'Row has been deleted successfully.';\nconst DeleteRow = React.memo(({ deleteObj, isSubRow, disabled }) => {\n  const {\n    tableJson, setTableJson, listRef, tableToCodeViewParser, currentModel, handleAddRow,\n    dependency,\n  } = useEditor();\n  const [isDelete, setIsDelete, hideIsDelete] = useBoolean(false);\n  const { addSuccessToast } = useToastNotifications();\n  const handleDeleteRow = React.useCallback(() => {\n    // delete row by key\n    let newTable = [...tableJson];\n    const index = newTable.findIndex((r) => r.key === deleteObj.key);\n    newTable = newTable.filter((r) => r.key !== deleteObj.key);\n    newTable.map((x, i) => {\n      // re-arrange keys\n      // eslint-disable-next-line no-param-reassign\n      x.key = `r${i}`;\n      return x;\n    });\n    const isExist = currentModel?.schemaJson && Object.keys(currentModel.schemaJson)?.find((x) => x === deleteObj.attr); // check for exist in db\n    if (isExist) {\n      tableToCodeViewParser({\n        isSave: true,\n        msg: RowDeleteMessage,\n        tableArr: newTable,\n        showMsg: true,\n        tDependency: dependency.map((x) => {\n          if (deleteObj.attr === x.oldKey) {\n            return { ...x, isDelete: true };\n          }\n          return x;\n        }),\n      });\n    } else {\n      addSuccessToast(RowDeleteMessage);\n      if (!newTable?.length) {\n        // if 0 length\n      } else if (last(newTable)?.attr?.length > 0) handleAddRow(newTable);\n      else setTableJson(newTable);\n    }\n    listRef?.current?.resetAfterIndex(index);\n  }, [tableJson, deleteObj, listRef?.current, tableToCodeViewParser, currentModel?.schemaJson]);\n\n  const isSubRowExist = (rowAttr) => {\n    if (currentModel?.schemaJson && rowAttr) {\n      const isRowExist = Object.keys(currentModel.schemaJson)?.find((x) => x === rowAttr);\n      if (isRowExist) {\n        let isSubExist;\n        if (isArray(currentModel.schemaJson[isRowExist])) {\n        // ARRAY type\n          isSubExist = Object.keys(currentModel.schemaJson[isRowExist][0])?.find((x) => x === deleteObj.attr);\n        } else {\n        // JSON type\n          isSubExist = Object.keys(currentModel.schemaJson[isRowExist])?.find((x) => x === deleteObj.attr);\n        }\n        if (isSubExist) return true;\n        return false;\n      }\n      return false;\n    } return false;\n  };\n\n  const handleDeleteSubRow = React.useCallback(() => {\n    // delete sub row by key\n    const newTable = [...tableJson];\n    const index = newTable.findIndex((r) => r.key === deleteObj.rowKey);\n    if (index < 0) return;\n    const newSubTable = newTable[index].subRows.filter(\n      (sr) => sr.key !== deleteObj.key,\n    );\n    newSubTable.map((x, i) => {\n      // re-arrange keys\n      // eslint-disable-next-line no-param-reassign\n      x.key = `rs${i}`;\n      return x;\n    });\n    newTable[index].subRows = newSubTable;\n\n    const isExist = !!deleteObj.attr; // blank row\n    if (isExist && isSubRowExist(newTable[index].attr)) {\n      tableToCodeViewParser({\n        isSave: true,\n        msg: RowDeleteMessage,\n        tableArr: newTable,\n        showMsg: true,\n        isDelete: true,\n        tDependency: dependency.map((x) => {\n          if (deleteObj.attr === x.oldKey) {\n            return { ...x, parentKey: newTable[index].attr, isDelete: true };\n          }\n          return x;\n        }),\n      });\n    } else {\n      setTableJson(() => newTable);\n      addSuccessToast(RowDeleteMessage);\n    }\n\n    listRef?.current?.resetAfterIndex(index);\n  }, [tableJson, deleteObj, listRef?.current, currentModel?.schemaJson]);\n\n  const handleDeleteModal = React.useCallback(() => {\n    if (isSubRow) handleDeleteSubRow();\n    else { handleDeleteRow(); }\n    hideIsDelete();\n  }, [isSubRow, handleDeleteRow, handleDeleteSubRow]);\n  return (\n    <>\n      { isDelete\n        ? (\n          <ConfirmationAlert\n            description=\"You want to delete this model attribute with all its references from relationships, routes, custom query and model permission permanently. Also, the deleted model attribute cannot be restored in the future.\"\n            isOpen={isDelete}\n            handleSubmit={handleDeleteModal}\n            handleClose={hideIsDelete}\n          />\n        )\n        : null}\n      <div\n        className={`${isSubRow ? TableViewCss.subTableClose : TableViewCss.tableClose}\n        ${(disabled) ? ' opacity-50 cursor-not-allowed' : ''}`}\n        onClick={() => {\n          if (disabled) { return; }\n          setIsDelete();\n        }}\n      >\n        <Icons.Close />\n      </div>\n    </>\n  );\n});\nexport { DeleteRow };\nDeleteRow.displayName = 'DeleteRow';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/RowSuspense.js",
    "content": "import React from 'react';\n\nconst RowSuspense = ({ children }) => <React.Suspense fallback={<div>Loading...</div>}>{children}</React.Suspense>;\nexport default React.memo(RowSuspense);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/Sortable.js",
    "content": "import React from 'react';\nimport { SortableHandle } from 'react-sortable-hoc';\nimport { Icons } from '@dhiwise/icons';\nimport { TableViewCss } from '../../../../../../assets/css/tableViewCss';\n\nexport const DragHandle = SortableHandle((props) => {\n  const { style } = props;\n  return (\n    <div className={TableViewCss.tableSequence} style={style}>\n      <Icons.Sequence />\n    </div>\n  );\n});\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/TableRow.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport {\n  isEmpty, last,\n} from 'lodash';\nimport { SortableContainer, SortableElement } from 'react-sortable-hoc';\nimport { Controller, useForm } from 'react-hook-form';\nimport { Icons } from '@dhiwise/icons';\nimport { TableViewCss } from '../../../../../../assets/css/tableViewCss';\nimport {\n  Input, Checkbox, Select,\n} from '../../../../../../components';\n// import { TableSubRow } from './TableSubRow';\nimport { DragHandle } from './Sortable';\nimport { AddRelation } from '../AddRelation';\nimport { getError } from '../../../../../../utils/validationMsgs';\nimport {\n  DEFAULT_OPTIONS, getDisableField, DEFAULT_VALUES,\n  getSubFieldPosition, SUB_FIELD_SEQ, getFieldPosition, util, DB_TYPE,\n  DEFAULT_TYPE_LENGTH, isNumberType, KEYS,\n} from '../../../../../../constant/model';\nimport {\n  LocalFields, InnerType, DateTime, NumberType,\n} from '../components/index';\nimport { Enum } from '../Enum';\nimport { SelectEnumValue } from '../Enum/SelectEnumValue';\nimport { useEditor } from '../../EditorProvider';\nimport { DeleteRow } from './DeleteRow';\nimport RowSuspense from './RowSuspense';\nimport { modelAttrRegex } from '../../../../../../utils/regex';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../../../constant/common';\nimport { ORM_TYPE } from '../../../../../../constant/Project/applicationStep';\nimport { useModel } from '../../ModelProvider';\n\nconst TableSubRow = React.lazy(() => new Promise((resolve) => resolve(import('./TableSubRow'))));\n\nconst SortableItem = SortableElement(({ subRow, rowIndex, ...otherProps }) => (\n  <RowSuspense>\n    <div className=\"relative mb-2\" id={subRow.key}>\n      <TableSubRow\n        index={rowIndex}\n        subRow={subRow}\n        {...otherProps}\n      />\n    </div>\n  </RowSuspense>\n));\nconst SortableList = SortableContainer(({ items, ...otherProps }) => (\n  <div>\n    {\n      items?.map((rs, index) => (\n        <SortableItem key={rs.key} subRow={rs} rowIndex={index} index={index} useDragHandle {...otherProps} />\n      ))\n    }\n  </div>\n));\n\nconst AllCheckBox = ({\n  cname, onInputChange, watch, control, disable, onKeyDownHandle, id,\n}) => (\n  <>\n    <Controller\n      control={control}\n      name={cname}\n      defaultValue={!!watch(cname)}\n      render={(controlProps) => (\n        <Checkbox\n          id={id}\n          {...controlProps}\n          checked={!!watch(cname)}\n          disabled={!!disable[cname]}\n          onKeyDown={(e) => {\n            if (e.keyCode === 13) {\n              // setValue(cname, !e?.target?.checked);\n              controlProps.onChange(!e?.target?.checked);\n              onInputChange(cname, !e?.target?.checked, id);\n              // requestAnimationFrame(() => {\n              //   onKeyDownHandle(e, cname);\n              // });\n            } else { onKeyDownHandle(e, cname); }\n          }}\n          onChange={(value) => {\n            controlProps.onChange(value);\n            onInputChange(cname, value);\n          }}\n        />\n      )}\n    />\n  </>\n);\n\nconst TableRow = React.memo((props) => {\n  const {\n    row, onAddSubRow, onSubSortEnd, onExpand, onChange, localRef, style, onSubRowChange, lengthOfData,\n    tableJson,\n  } = props;\n\n  const rowStyle = React.useMemo(() => ({\n    ...style,\n    overflowX: 'visible',\n  }), [style]);\n\n  const {\n    modelList, currentId, dbType, ormType, TABLE_TYPES, dependency, setDependency,\n  } = useEditor();\n  const { isExpand } = row;\n  const isMongoDb = React.useMemo(() => dbType === DB_TYPE.MONGODB, [dbType]);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const TYPE_OPTIONS = React.useMemo(() => util.getTypeOptions(dbType, currentApplicationCode), [dbType, currentApplicationCode]);\n  const CONST_VARIABLE = { TABLE_TYPES, TYPE_OPTIONS };\n\n  const {\n    getValues, control, errors, setValue, watch,\n  } = useForm({\n    shouldUnregister: false,\n  });\n  const { setChangeInTable } = useModel();\n  const disable = React.useMemo(() => getDisableField(watch('type'),\n    {\n      isAutoIncrement: watch('isAutoIncrement'), match: watch('match'), unique: watch('unique'), default: watch('default'), filter: watch('filter'),\n    }, dbType,\n    { // opts\n      attr: (watch('attr') === '_id' || watch('attr') === 'id') ? watch('attr') : '',\n      currentApplicationCode,\n    }),\n  [watch('type'), watch('isAutoIncrement'), dbType, watch('attr'), watch('match'), watch('default'), watch('unique'), watch('filter')]);\n  const { TOTAL_FIELDS, FIELD_SEQ, FiledPosition } = getFieldPosition(props.index, dbType, currentApplicationCode);\n\n  const handleAutoFocus = (focusId) => {\n    const ele = document.getElementById(focusId);\n    ele?.focus();\n  };\n\n  const onInputChange = React.useCallback((fieldName, value, focusId) => {\n    if (['enum', 'isEnum', 'refAttribute', 'innerDataType', 'relType'].includes(fieldName)) { setValue(fieldName, value); }\n    if (fieldName === 'default' && (row.type === TABLE_TYPES.DATE || row.type === TABLE_TYPES.DATEONLY || row.type === TABLE_TYPES.DATETIME || row.type === TABLE_TYPES.TIMESTAMP)) { setValue('default', value); }\n    if (fieldName === 'type') {\n      setValue('isAutoIncrement', undefined);\n      setValue('default', undefined);\n      setValue('unique', undefined);\n      row.default = undefined;\n      row.isAutoIncrement = undefined;\n      row.unique = undefined;\n    }\n    if (fieldName === 'attr') {\n      if (!isEmpty(value) && !row.type) {\n        setValue('type', ormType === ORM_TYPE.MONGOOSE ? 'String' : 'STRING');\n        onInputChange('type');\n      }\n    }\n    const fieldValue = (value === undefined || value === null) ? getValues(fieldName) : value;\n    if (fieldName === 'filter' && !fieldValue) { // clear default value if there are no options selected in default\n      setValue('default', undefined);\n      row.default = undefined;\n    }\n    if (fieldName === 'type' && (fieldValue === TABLE_TYPES.BOOL) && !row.default) {\n      setValue('default', 'true');\n      row.default = 'true';\n    }\n    if (fieldName === 'type' && (fieldValue === TABLE_TYPES.BOOL || (!isMongoDb && isNumberType(fieldValue, TABLE_TYPES)))) {\n      setValue('filter', undefined);\n      row.filter = undefined;\n    }\n    if (fieldName === 'required' && fieldValue && row.filter === 'NULL') {\n      setValue('filter', undefined);\n      row.filter = undefined;\n    }\n    if (fieldName === 'isEnum') {\n      // assign value for enum validation\n      if (fieldValue && isEmpty(row.enum)) {\n        row.enum = {};\n        setValue('enum', {});\n      } else if (!fieldValue) {\n        row.enum = undefined;\n        setValue('enum', undefined);\n      }\n      setValue('default', undefined);\n      row.default = undefined;\n    }\n    if (fieldName === 'type' && [TABLE_TYPES.ARRAY, TABLE_TYPES.JSON].includes(fieldValue) && isMongoDb) {\n      setValue('private', false);\n      row.private = false;\n    }\n\n    if (fieldName === KEYS.match && fieldValue) {\n      // pattern enable then remove other validation\n      [KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim].forEach((x) => {\n        row[x] = undefined;\n        setValue(x, undefined);\n      });\n    }\n\n    if (fieldValue !== row[fieldName]) {\n      setChangeInTable();\n      // on change only when value is updated\n      setDependency(dependency.map((x) => {\n        if (row[fieldName] === x.oldKey) {\n          return { ...x, newKey: fieldValue };\n        }\n        return x;\n      }));\n      row[fieldName] = fieldValue;\n      onChange?.({\n        key: fieldName, value: fieldValue, row, index: props.index,\n      });\n    }\n    // if (isNotFocus) return; // remove focus onBlur\n    if (focusId) {\n      requestAnimationFrame(() => {\n        handleAutoFocus(focusId);\n        // handleAutoFocus(fieldName, row.key, fieldValue, { index: props.index }); // manage auto focus\n      });\n    }\n  }, [row, props?.index, onChange, dependency]);\n\n  React.useEffect(() => {\n    if (row) {\n      const rowArr = Object.keys(row);\n      Object.keys(DEFAULT_VALUES).map((r) => {\n        setValue(r, row[r]);\n        return r;\n      });\n      if (rowArr.length === 1) {\n        // for blank row\n        Object.keys(DEFAULT_VALUES).map((x) => {\n          setValue(x, row[x]);\n          return x;\n        });\n      }\n    }\n  }, [row]);\n\n  const showSub = React.useCallback((str) => {\n    onExpand(row, str);\n  }, [row, onExpand]);\n\n  const handleRowToSubFocus = ({\n    focusField, prevRow, prevIndex, downIndex, downRow, ...opt\n  }) => {\n    // handle row to subrow focus\n\n    if (opt?.isDown) {\n      const subField = getSubFieldPosition(0); // 1st sub row\n      let focusIndex = subField.FiledPosition[focusField];\n      for (let nextIndex = 0; nextIndex <= downRow.subRows?.length; nextIndex += 1) {\n        if (focusField === 'subAttr') {\n          if (downRow.subRows[nextIndex]?.type === TABLE_TYPES.OBJECTID || downRow.subRows[nextIndex]?.type === TABLE_TYPES.VIRTUAL_RELATION) {\n            focusIndex = subField.FiledPosition.relation;\n          } else if (downRow.subRows[nextIndex]?.type === TABLE_TYPES.STRING || downRow.subRows[nextIndex]?.type === TABLE_TYPES.NUMBER) {\n            focusIndex = subField.FiledPosition.isEnum;\n          }\n        }\n        const field = document.querySelector(`#subrow${downIndex}${focusIndex - nextIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n    } else if (opt?.isUp) {\n      const subField = getSubFieldPosition(prevRow?.subRows?.length - 1);// last sub row\n      let focusIndex = subField.FiledPosition[focusField];\n      for (let nextIndex = prevRow.subRows?.length - 1; nextIndex >= 0; nextIndex -= 1) {\n        if (focusField === 'subAttr') {\n          if (prevRow.subRows[nextIndex]?.type === TABLE_TYPES.OBJECTID || prevRow.subRows[nextIndex]?.type === TABLE_TYPES.VIRTUAL_RELATION) {\n            focusIndex = subField.FiledPosition.relation;\n          } else if (prevRow.subRows[nextIndex]?.type === TABLE_TYPES.STRING || prevRow.subRows[nextIndex]?.type === TABLE_TYPES.NUMBER) {\n            focusIndex = subField.FiledPosition.isEnum;\n          }\n        }\n        const field = document.querySelector(`#subrow${prevIndex}${focusIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n    } else if (opt?.isPrev) {\n      const subField = getSubFieldPosition(prevRow?.subRows?.length - 1);// last sub row\n      const focusIndex = subField.FiledPosition.match;\n      for (let nextIndex = 0; nextIndex !== lengthOfData * TOTAL_FIELDS; nextIndex += 1) {\n        const field = document.querySelector(`#subrow${props.index - 1}${focusIndex - nextIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n    } else if (opt?.isNext) {\n      // next\n      const field = document.querySelector(`#subrow${props.index}${SUB_FIELD_SEQ.attr}`);\n      if (field?.disabled) {\n        let isFoc = false;\n        Object.keys(SUB_FIELD_SEQ).forEach((s) => {\n          const field1 = document.querySelector(`#subrow${props.index}${SUB_FIELD_SEQ[s]}`);\n          if (!field1?.disabled && field1?.focus && !isFoc) {\n            isFoc = true;\n            field1.focus();\n          }\n        });\n      } else { field?.focus(); }\n    }\n  };\n\n  const onKeyDownHandle = (e, focusField, defaultFocusIndex) => {\n    const focusIndex = defaultFocusIndex !== undefined ? defaultFocusIndex : FiledPosition[focusField];\n    switch (e.keyCode) {\n      case 38:\n      { // up\n        let isFocused = false;\n        if (isMongoDb && (tableJson[props.index - 1]?.type === TABLE_TYPES.ARRAY\n            || tableJson[props.index - 1]?.type === TABLE_TYPES.JSON)) {\n          // row => subrow\n          for (let nextIndex = props.index - 1; nextIndex >= 0; nextIndex -= 1) {\n            if (tableJson[nextIndex]?.isExpand) {\n              // row => subrow\n              isFocused = true;\n              handleRowToSubFocus({\n                isUp: true, focusField, prevRow: tableJson[nextIndex], prevIndex: nextIndex,\n              });\n              break;\n            }\n          }\n        }\n        if (!isFocused) {\n          for (let nextIndex = TOTAL_FIELDS; nextIndex < lengthOfData * TOTAL_FIELDS; nextIndex += TOTAL_FIELDS) {\n            const field = document.querySelector(`#row${focusIndex - nextIndex}`);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              break;\n            }\n          }\n        }\n        break;\n      }\n      case 40:\n      { // down\n        let isFocused = false;\n        if (isMongoDb && (tableJson[props.index]?.type === TABLE_TYPES.ARRAY\n            || tableJson[props.index]?.type === TABLE_TYPES.JSON)) {\n          // row => subrow\n          for (let nextIndex = props.index; nextIndex <= lengthOfData; nextIndex += 1) {\n            if (tableJson[nextIndex]?.isExpand) {\n              isFocused = true;\n              handleRowToSubFocus({\n                isDown: true, focusField, downIndex: nextIndex, downRow: tableJson[nextIndex],\n              });\n              break;\n            }\n          }\n        }\n        if (!isFocused) {\n          for (let nextIndex = TOTAL_FIELDS; nextIndex < lengthOfData * TOTAL_FIELDS; nextIndex += TOTAL_FIELDS) {\n            const field = document.querySelector(`#row${focusIndex + nextIndex}`);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              isFocused = true;\n              field?.focus();\n              break;\n            } else if (isMongoDb) {\n              // row=>sub-row: if row having sub-attribute and field is disabled\n              const index = (focusIndex - FIELD_SEQ[focusField]) / TOTAL_FIELDS;\n              for (let nextIndex1 = index; nextIndex1 <= lengthOfData; nextIndex1 += 1) {\n                if ((tableJson[nextIndex1]?.type === TABLE_TYPES.ARRAY\n                    || tableJson[nextIndex1]?.type === TABLE_TYPES.JSON) && tableJson[nextIndex1]?.isExpand) {\n                  // row => subrow\n                  isFocused = true;\n                  handleRowToSubFocus({\n                    isDown: true, focusField, downIndex: nextIndex1, downRow: tableJson[nextIndex1],\n                  });\n                  break;\n                }\n              }\n            }\n            if (isFocused) break;\n          }\n        }\n        break;\n      }\n      case 37:\n      { // left\n        if (e.ctrlKey) {\n          if (isMongoDb && tableJson[props.index - 1]?.isExpand && focusField === 'attr') {\n            // row => subrow\n            handleRowToSubFocus({ isPrev: true, prevRow: tableJson[props.index - 1] });\n          } else {\n            for (let nextIndex = 1; nextIndex !== lengthOfData * TOTAL_FIELDS; nextIndex += 1) {\n              const field = document.querySelector(`#row${focusIndex - nextIndex}`);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                break;\n              }\n            }\n          }\n        }\n        break;\n      }\n      case 39:\n      {\n        // right\n        if (e.ctrlKey) {\n          if (isMongoDb && focusField === 'subAttr' && tableJson[props.index].isExpand) {\n            // row => subrow\n            handleRowToSubFocus({ isNext: true });\n          } else {\n            for (let nextIndex = 1; nextIndex !== lengthOfData * TOTAL_FIELDS; nextIndex += 1) {\n              const field = document.querySelector(`#row${focusIndex + nextIndex}`);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                break;\n              }\n            }\n          }\n        }\n        break;\n      }\n      case 13:\n      {\n        // enter\n        if (isMongoDb && focusField === 'subAttr' && !tableJson[props.index].isExpand) {\n          // focus on sub-row\n          showSub('sub-attr');\n          requestAnimationFrame(() => {\n            handleRowToSubFocus({ isNext: true });\n          });\n        } else {\n          if (isMongoDb && focusField === 'subAttr' && tableJson[props.index].isExpand) {\n            // collapse subattr\n            showSub('sub-attr');\n          }\n          for (let nextIndex = 1; nextIndex !== lengthOfData * TOTAL_FIELDS; nextIndex += 1) {\n            const field = document.querySelector(`#row${focusIndex + nextIndex}`);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              break;\n            }\n          }\n        }\n        break;\n      }\n\n      default:\n        break;\n    }\n  };\n\n  const handleSubrowFocus = (opt) => {\n    // sub-row to row focus\n    if (opt?.isPrev) {\n      // prev\n      onKeyDownHandle(opt.e, 'default');\n    } else if (opt?.isUp) {\n      // up (index * total) + colseq\n      for (let nextIndex = props.index; nextIndex >= 0; nextIndex -= 1) {\n        const fIndex = (nextIndex * TOTAL_FIELDS) + (FIELD_SEQ[opt.focusField]);\n        if (fIndex < 0) break;\n        if (tableJson[nextIndex - 1]?.isExpand && disable[opt.focusField]) {\n          // expanded sub row and move subrow=>subrow\n          handleRowToSubFocus({\n            isUp: true, focusField: opt.focusField, prevRow: tableJson[nextIndex - 1], prevIndex: nextIndex - 1,\n          });\n          break;\n        } else {\n          // is not expanded\n          const field = document.querySelector(`#row${fIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            break;\n          }\n        }\n      }\n    } else if (opt?.isDown) {\n      // down (index+1 * total) + colseq\n      for (let nextIndex = props.index + 1; nextIndex < lengthOfData; nextIndex += 1) {\n        const fIndex = (nextIndex * TOTAL_FIELDS) + (FIELD_SEQ[opt.focusField]);\n        if (fIndex < 0) break;\n        if (tableJson[nextIndex]?.isExpand && disable[opt.focusField]) {\n          // expanded sub row and move subrow=>subrow\n          handleRowToSubFocus({\n            isDown: true, focusField: opt.focusField, downRow: tableJson[nextIndex], downIndex: nextIndex,\n          });\n          break;\n        } else {\n          // is not expanded\n          const field = document.querySelector(`#row${fIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            break;\n          }\n        }\n      }\n    } else {\n      // next\n      const calcIndex = (props.index + 1) * TOTAL_FIELDS;\n      let fIndex;\n      if (opt.focusField === 'attr') { fIndex = calcIndex + 1; }\n      if (fIndex < 0) return;\n      const field = document.querySelector(`#row${fIndex}`);\n      field?.focus();\n    }\n  };\n\n  const checkboxProps = {\n    onInputChange, watch, control, setValue, disable, onKeyDownHandle,\n  };\n\n  const RequiredCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"required\" id={`row${FiledPosition.required}`} {...checkboxProps} />\n  ), [row, disable, watch('required')]);\n\n  const UniqueCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"unique\" id={`row${FiledPosition.unique}`} {...checkboxProps} />\n  ), [row, disable, watch('unique')]);\n\n  const AutoIncCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"isAutoIncrement\" id={`row${FiledPosition.isAutoIncrement}`} {...checkboxProps} />\n  ), [row, disable, watch('isAutoIncrement')]);\n\n  const LowerCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"lowercase\" id={`row${FiledPosition.lowercase}`} {...checkboxProps} />\n  ), [row, disable, watch('lowercase')]);\n\n  const TrimCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"trim\" id={`row${FiledPosition.trim}`} {...checkboxProps} />\n  ), [row, disable, watch('trim')]);\n\n  const PrimaryCheckBox = React.useCallback(() => (\n    <AllCheckBox cname=\"primary\" id={`row${FiledPosition.primary}`} {...checkboxProps} />\n  ), [row, disable, watch('primary')]);\n\n  // const TinyCheckBox = React.useCallback(() => (\n  //   <AllCheckBox cname=\"tiny\" id={`row${FiledPosition.tiny}`} {...checkboxProps} />\n  // ), [row, disable, watch('tiny')]);\n\n  const PrivateCheckbox = React.useCallback(() => (\n    <AllCheckBox cname=\"private\" id={`row${FiledPosition.private}`} {...checkboxProps} />\n  ), [row, disable, watch('private')]);\n\n  // const IndexCheckBox = React.useCallback(() => (\n  //   <AllCheckBox cname=\"index\" {...checkboxProps} />\n  // ), [row, disable, watch('index')]);\n\n  return (\n    <>\n      <div className=\"border-t border-gray-200 py-2\" id={row.key} style={rowStyle}>\n        {\n           (\n             <div className=\"relative\">\n               <div className=\"relative pl-8\">\n                 <tr className={`${TableViewCss.tableRow}`}>\n                   <DragHandle />\n                   { isMongoDb\n                    && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.JSON)\n                     ? (\n                       <>\n                         {isExpand\n                           ? (\n                             <div className={TableViewCss.tableCollapse} onClick={showSub}>\n                               <Icons.DownArrow />\n                             </div>\n                           )\n                           : (\n                             <div className={TableViewCss.tableCollapse} onClick={() => showSub('sub-attr')}>\n                               <Icons.RightArrow />\n                             </div>\n                           )}\n                       </>\n                     )\n                     : null}\n\n                   <DeleteRow\n                     deleteObj={row}\n                     disabled={(lengthOfData === 1 && Object.keys(tableJson)?.length <= 2) || (dbType === DB_TYPE.MONGODB && watch('attr') === '_id') || (dbType !== DB_TYPE.MONGODB && watch('attr') === 'id')}\n                   />\n                   <td className=\"relative pl-12\">\n                     <div className=\"tableInputSelect\">\n                       <Controller\n                         defaultValue={row.attr || ''}\n                         control={control}\n                         name=\"attr\"\n                         render={(controlProps) => (\n                           <Input\n                             {...controlProps}\n                             id={`row${FiledPosition.attr}`}\n                             size=\"small\"\n                             placeholder=\"Attributes\"\n                             WrapClassName=\"w-full\"\n                             maxLength={MAX_INPUT_FIELD_LIMIT.title}\n                             customRegex={modelAttrRegex}\n                             disabled={disable.attr}\n                             onBlur={() => onInputChange('attr', controlProps.value)}\n                             onKeyDown={(e) => onKeyDownHandle(e, 'attr')}\n                             error={getError(errors, 'attr', 'Attribute')}\n                           />\n                         )}\n                       />\n                     </div>\n                   </td>\n                   <td className=\"\">\n                     <div className={`tableInputSelect ${watch('type') === TABLE_TYPES.VIRTUAL_RELATION && ''}`}>\n                       <Controller\n                         defaultValue={row.type || ''}\n                         control={control}\n                         name=\"type\"\n                         render={(controlProps) => (\n                           <Select\n                             sizeSmall\n                             inputId={`row${FiledPosition.type}`}\n                             {...controlProps}\n                             isClearable={false}\n                             placeholder=\"Data type\"\n                             options={TYPE_OPTIONS.filter((x) => x.id !== TABLE_TYPES.POINT)}\n                             disabled={disable.type}\n                             onChange={(value) => {\n                               controlProps.onChange(value);\n                               onInputChange('type');\n                             }}\n                             onKeyDown={(e) => {\n                               if (e.ctrlKey || e.keyCode === 13) {\n                                 if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                                   return;\n                                 }\n                                 onKeyDownHandle(e, 'type');\n                                 if (e.ctrlKey) e.preventDefault();\n                               }\n                             }}\n                           />\n                         )}\n                       />\n\n                       {isMongoDb && watch('type') === TABLE_TYPES.VIRTUAL_RELATION && (\n                       <>\n                         <LocalFields\n                           disabled={disable.localField}\n                           id={`row${FiledPosition.localField}`}\n                           rowObj={row}\n                           localField={row.localField}\n                           localRef={localRef}\n                           onInputChange={onInputChange}\n                           onKeyDown={onKeyDownHandle}\n                         />\n                       </>\n                       )}\n                     </div>\n                   </td>\n                   <td className=\"\">\n                     <div className=\"tableInputSelect\">\n                       {((!isMongoDb && watch('type') === TABLE_TYPES.ENUM)\n                        || (isMongoDb && (watch('type') === TABLE_TYPES.STRING || watch('type') === TABLE_TYPES.NUMBER)))\n                        && (\n                          <Enum\n                            disabled={disable.isEnum}\n                            onInputChange={onInputChange}\n                            row={row}\n                            id={`row${FiledPosition.isEnum}`}\n                            onKeyDown={(e) => onKeyDownHandle(e, 'isEnum')}\n                          />\n                        )}\n\n                       {isMongoDb && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.JSON) && (\n                       <span\n                         id={`row${FiledPosition.subAttr}`}\n                         name=\"sub-attr\"\n                         tabIndex=\"0\"\n                          //  onKeyDown={(e) => onKeyDownHandle(e, 'sub-attr')}\n                         onClick={() => showSub('sub-attr')}\n                         onKeyDown={(e) => {\n                           onKeyDownHandle(e, 'subAttr');\n                         }}\n                         className={TableViewCss.addValue}\n                       >\n                         <div className=\"w-4 h-4 mr-2\">\n                           <Icons.Add />\n                         </div>\n                         Add sub attributes\n                       </span>\n                       )}\n                       {isMongoDb && (watch('type') === TABLE_TYPES.OBJECTID || watch('type') === TABLE_TYPES.VIRTUAL_RELATION)\n                        && (\n                          <AddRelation\n                            currentId={currentId}\n                            modelList={modelList}\n                            onInputChange={onInputChange}\n                            model={row.ref}\n                            foreignKey={row.foreignField}\n                            isVirtual={watch('type') === TABLE_TYPES.VIRTUAL_RELATION}\n                            id={`row${FiledPosition.relation}`}\n                            onKeyDown={(e) => onKeyDownHandle(e, 'relation')}\n                            CONST_VARIABLE={CONST_VARIABLE}\n                          />\n                        )}\n                       {\n                        !isMongoDb && row.type && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.RANGE)\n                        && (\n                          <InnerType\n                            disabled={disable.innerDataType}\n                            id={`row${FiledPosition.innerDataType}`}\n                            TYPE_OPTIONS={TYPE_OPTIONS}\n                            innerDataType={row.innerDataType}\n                            onInputChange={onInputChange}\n                            onKeyDown={onKeyDownHandle}\n                          />\n                        )\n                      }\n                       {isMongoDb && row.type && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.JSON\n                        || watch('type') === TABLE_TYPES.OBJECTID || watch('type') === TABLE_TYPES.VIRTUAL_RELATION\n                        || watch('type') === TABLE_TYPES.STRING || watch('type') === TABLE_TYPES.NUMBER) ? <></>\n                         : !isMongoDb && row.type && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.RANGE\n                          || watch('type') === TABLE_TYPES.ENUM) ? <></> : <>-</>}\n                     </div>\n                   </td>\n\n                   <td className=\"\">\n                     <div className={`tableInputSelect ${watch('filter') === 'AS_DEFINED'\n                      && watch('type') !== TABLE_TYPES.BOOL\n                      && (!isNumberType(watch('type'), TABLE_TYPES) || (isMongoDb)) ? '' : '-mt-1'}`}\n                     >\n                       {watch('type') !== TABLE_TYPES.BOOL\n                        && ((!isMongoDb && !isNumberType(watch('type'), TABLE_TYPES)) || (isMongoDb))\n                         ? (\n                           <Controller\n                             defaultValue={row.filter || ''}\n                             control={control}\n                             name=\"filter\"\n                             render={(controlProps) => (\n                               <Select\n                                 inputId={`row${FiledPosition.filter}`}\n                                 sizeSmall\n                                 {...controlProps}\n                                 placeholder=\"Default\"\n                                 options={DEFAULT_OPTIONS}\n                                 isOptionDisabled={(option) => option.id === 'NULL' && row.required}\n                                 disabled={disable.filter}\n                                 onChange={(value) => {\n                                   controlProps.onChange(value);\n                                   onInputChange('filter');\n                                 }}\n                                 onKeyDown={(e) => {\n                                   if (e.ctrlKey || e.keyCode === 13) {\n                                     if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                                       return;\n                                     }\n                                     onKeyDownHandle(e, 'filter');\n                                     if (e.ctrlKey) e.preventDefault();\n                                   }\n                                 }}\n                               />\n                             )}\n                           />\n                         )\n                         : null}\n\n                       {watch('type') === TABLE_TYPES.BOOL\n                         ? (\n                           <span className=\"text-center\">\n                             <Controller\n                               defaultValue={row.default || ''}\n                               control={control}\n                               name=\"default\"\n                               render={(controlProps) => (\n                                 <Select\n                                   sizeSmall\n                                   {...controlProps}\n                                   WrapClassName=\"mt-1\"\n                                   placeholder=\"Default value\"\n                                   options={[{ id: 'true', name: 'TRUE' }, { id: 'false', name: 'FALSE' }]}\n                                   disabled={disable.default}\n                                   onChange={(value) => {\n                                     controlProps.onChange(value);\n                                     onInputChange('default');\n                                   }}\n                                   inputId={`row${FiledPosition.default}`}\n                                   onKeyDown={(e) => {\n                                     if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                                       return;\n                                     }\n                                     if (e.ctrlKey || e.keyCode === 13) {\n                                       onKeyDownHandle(e, 'default');\n                                       if (e.ctrlKey) e.preventDefault();\n                                     }\n                                   }}\n                                 />\n                               )}\n                             />\n                           </span>\n                         )\n                         : ((!isMongoDb && isNumberType(watch('type'), TABLE_TYPES))\n                          || (isMongoDb && watch('filter') === 'AS_DEFINED' && !watch('isEnum')\n                            && (watch('type') === TABLE_TYPES.NUMBER || watch('type') === TABLE_TYPES.DECIMAL || watch('type') === TABLE_TYPES.PERCENT)))\n                           ? (\n                             <NumberType\n                               TABLE_TYPES={TABLE_TYPES}\n                               type={watch('type')}\n                               disabled={disable.default}\n                               id={`row${FiledPosition.default}`}\n                               defaultValue={row.default}\n                               onInputChange={onInputChange}\n                               onKeyDown={onKeyDownHandle}\n                             />\n                           ) : watch('filter') === 'AS_DEFINED' ? (\n                             <>\n                               {watch('isEnum')\n                                && [TABLE_TYPES.STRING, TABLE_TYPES.ENUM, TABLE_TYPES.NUMBER].includes(row.type) ? (\n                                  <SelectEnumValue\n                                    defaultValue={row?.default}\n                                    isEnum={watch('isEnum')}\n                                    enumObj={watch('enum')}\n                                    row={row}\n                                    disabled={disable.default}\n                                    onInputChange={onInputChange}\n                                    id={`row${FiledPosition.default}`}\n                                    onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                                  />\n                                 )\n                                 : (watch('type') === TABLE_TYPES.DATE || watch('type') === TABLE_TYPES.DATEONLY || watch('type') === TABLE_TYPES.DATETIME || watch('type') === TABLE_TYPES.TIMESTAMP)\n                                   ? (\n                                     <DateTime\n                                       showTimeSelect={watch('type') === TABLE_TYPES.DATE || watch('type') === TABLE_TYPES.DATETIME || watch('type') === TABLE_TYPES.TIMESTAMP}\n                                       disabled={disable.default}\n                                       id={`row${FiledPosition.default}`}\n                                       defaultValue={row.default}\n                                       WrapClassName=\"w-full mt-1\"\n                                       onInputChange={onInputChange}\n                                       onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                                     />\n                                   ) : (watch('type') === TABLE_TYPES.TINYSTRING\n                                    || watch('type') === TABLE_TYPES.STRING\n                                    || watch('type') === TABLE_TYPES.TEXT\n                                    || watch('type') === TABLE_TYPES.CHAR) ? (\n                                      <Controller\n                                        defaultValue={row.default || ''}\n                                        control={control}\n                                        name=\"default\"\n                                        render={(controlProps) => (\n                                          <Input\n                                            {...controlProps}\n                                            maxLength={DEFAULT_TYPE_LENGTH.STRING}\n                                            size=\"small\"\n                                            placeholder=\"Default value\"\n                                            WrapClassName=\"w-full mt-1\"\n                                            disabled={disable.default}\n                                            onBlur={() => onInputChange('default', controlProps.value)}\n                                            id={`row${FiledPosition.default}`}\n                                            onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                                          />\n                                        )}\n                                      />\n                                     )\n                                     : isMongoDb ? (\n                                       <Controller\n                                         defaultValue={row.default || ''}\n                                         control={control}\n                                         name=\"default\"\n                                         render={(controlProps) => (\n                                           <Input\n                                             {...controlProps}\n                                             size=\"small\"\n                                             placeholder=\"Default value\"\n                                             WrapClassName=\"w-full mt-1\"\n                                             disabled={disable.default}\n                                             onBlur={() => onInputChange('default', controlProps.value)}\n                                             id={`row${FiledPosition.default}`}\n                                             onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                                           />\n                                         )}\n                                       />\n                                     ) : null}\n                             </>\n                           ) : null}\n                     </div>\n                   </td>\n                   {\n                     !isMongoDb && (\n                     <td className=\"\">\n                       <div className=\"tableInputSelect\">\n                         { (watch('type') === TABLE_TYPES.STRING || watch('type') === TABLE_TYPES.INTEGER || watch('type') === TABLE_TYPES.UnsignedBigInt)\n                           ? (\n                             <AddRelation\n                               isSql\n                               refAttribute={row.refAttribute}\n                               relType={row.relType}\n                               currentId={currentId}\n                               modelList={modelList}\n                               onInputChange={onInputChange}\n                               model={row.ref}\n                               id={`row${FiledPosition.relation}`}\n                               onKeyDown={(e) => onKeyDownHandle(e, 'relation')}\n                               CONST_VARIABLE={CONST_VARIABLE}\n                               type={watch('type')}\n                               row={row}\n                               tableJson={tableJson}\n                               disabled={watch('attr') === '_id' || watch('attr') === 'id'}\n                               currentApplicationCode={currentApplicationCode}\n                             />\n                           )\n                           : '-'}\n                       </div>\n                     </td>\n                     )\n                   }\n\n                   <td className={`check ${TableViewCss.tableCheckBox}`}>\n                     <span className=\"text-center tableCheck\">\n                       <PrivateCheckbox />\n                     </span>\n                     {!isMongoDb && (\n                     <span className=\"text-center tableCheck\">\n                       <PrimaryCheckBox />\n                     </span>\n                     )}\n                     {/* { !isMongoDb && (\n                     <span className=\"text-center tableCheck\">\n                       <TinyCheckBox />\n                     </span>\n                     ) } */}\n                     <span className=\"text-center tableCheck\">\n                       <RequiredCheckBox />\n                     </span>\n                     <span className=\"text-center tableCheck\">\n                       <UniqueCheckBox />\n                     </span>\n                     <span className=\"text-center tableCheck\">\n                       <AutoIncCheckBox />\n                     </span>\n                   </td>\n                   <td className=\"\">\n                     <div className=\"smallInput\">\n                       <div className=\"smallInput\">\n                         {isNumberType(watch('type'), TABLE_TYPES)\n                           ? (\n                             <Controller\n                               defaultValue={row.min || ''}\n                               control={control}\n                               name=\"min\"\n                               render={(controlProps) => (\n                                 <Input.Number\n                                   {...controlProps}\n                                   allowInteger\n                                   size=\"small\"\n                                   placeholder=\"Min\"\n                                   disabled={disable.min}\n                                   onBlur={() => onInputChange('min', controlProps.value)}\n                                   id={`row${FiledPosition.minimum}`}\n                                   onKeyDown={(e) => onKeyDownHandle(e, 'minimum')}\n                                 />\n\n                               )}\n                             />\n                           )\n                           : (\n                             <Controller\n                               defaultValue={row.minLength || ''}\n                               control={control}\n                               name=\"minLength\"\n                               render={(controlProps) => (\n                                 <Input.Number\n                                   {...controlProps}\n                                   size=\"small\"\n                                   placeholder=\"MinLength\"\n                                   disabled={disable.minLength}\n                                   onBlur={() => onInputChange('minLength', controlProps.value)}\n                                   id={`row${FiledPosition.minimum}`}\n                                   onKeyDown={(e) => onKeyDownHandle(e, 'minimum')}\n                                 />\n                               )}\n                             />\n                           )}\n                       </div>\n                     </div>\n                   </td>\n                   <td className=\"\">\n                     <div className=\"smallInput\">\n                       {isNumberType(watch('type'), TABLE_TYPES)\n                         ? (\n                           <Controller\n                             defaultValue={row.max || ''}\n                             control={control}\n                             name=\"max\"\n                             render={(controlProps) => (\n                               <Input.Number\n                                 size=\"small\"\n                                 {...controlProps}\n                                 allowInteger\n                                 placeholder=\"Max\"\n                                 disabled={disable.max}\n                                 onBlur={() => onInputChange('max', controlProps.value)}\n                                 id={`row${FiledPosition.maximum}`}\n                                 onKeyDown={(e) => onKeyDownHandle(e, 'maximum')}\n                               />\n                             )}\n                           />\n                         )\n                         : (\n                           <Controller\n                             defaultValue={row.maxLength || ''}\n                             control={control}\n                             name=\"maxLength\"\n                             render={(controlProps) => (\n                               <Input.Number\n                                 size=\"small\"\n                                 {...controlProps}\n                                 placeholder=\"MaxLength\"\n                                 disabled={disable.maxLength}\n                                 onBlur={() => onInputChange('maxLength', controlProps.value)}\n                                 id={`row${FiledPosition.maximum}`}\n                                 onKeyDown={(e) => onKeyDownHandle(e, 'maximum')}\n                               />\n                             )}\n                           />\n                         )}\n\n                     </div>\n                   </td>\n\n                   <td className={`check ${TableViewCss.tableCheckBox}`}>\n                     <span className=\"text-center tableCheck\">\n                       <LowerCheckBox />\n                     </span>\n                     {dbType === DB_TYPE.MONGODB && (\n                     <span className=\"text-center tableCheck\">\n                       <TrimCheckBox />\n                     </span>\n                     )}\n                   </td>\n                   <td className=\"\">\n                     <div className=\"smallInput\">\n                       <Controller\n                         defaultValue={row.match || ''}\n                         control={control}\n                         name=\"match\"\n                         render={(controlProps) => (\n                           <Input\n                             {...controlProps}\n                             placeholder=\"Pattern\"\n                             size=\"small\"\n                             disabled={disable.match}\n                             onBlur={() => onInputChange('match', controlProps.value)}\n                             id={`row${FiledPosition.match}`}\n                             onKeyDown={(e) => onKeyDownHandle(e, 'match')}\n                           />\n                         )}\n                       />\n                     </div>\n                   </td>\n                 </tr>\n               </div>\n               {isMongoDb && isExpand && (watch('type') === TABLE_TYPES.ARRAY || watch('type') === TABLE_TYPES.JSON)\n                && (\n                  <div className={TableViewCss.subTable}>\n                    <>\n                      {\n                        row?.subRows\n                          ? (\n                            <SortableList\n                              useDragHandle\n                              items={row.subRows}\n                              onSortEnd={(ev) => onSubSortEnd(ev, row)}\n                              currentId={currentId}\n                              modelList={modelList}\n                              localRef={localRef}\n                              onAddSubRow={(opt) => {\n                                if (opt?.isAdd) onAddSubRow(row, false, opt);\n                                else if (last(row.subRows).attr?.length > 0) onAddSubRow(row);\n                              }}\n                              onChange={(d) => onSubRowChange({ ...d, rowIndex: props.index })}\n                              lengthOfData={row.subRows?.length}\n                              onRowKeyDown={handleSubrowFocus}\n                              indexOfRow={props.index}\n                              rowObj={row}\n                              CONST_VARIABLE={CONST_VARIABLE}\n                              dbType={dbType}\n                            />\n                          )\n                          : null\n                      }\n                      <div className={TableViewCss.addValue} onClick={() => onAddSubRow(row, true)}>\n                        <div className=\"w-4 h-4 mr-2\">\n                          <Icons.Add />\n                        </div>\n                        Add row\n                      </div>\n                    </>\n                  </div>\n                )}\n             </div>\n          )\n        }\n      </div>\n    </>\n  );\n});\nexport default TableRow;\nTableRow.displayName = 'TableRow';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/TableSubRow.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { isEmpty } from 'lodash';\nimport { Controller, useForm } from 'react-hook-form';\nimport { TableViewCss } from '../../../../../../assets/css/tableViewCss';\nimport { Input, Checkbox, Select } from '../../../../../../components';\nimport { DragHandle } from './Sortable';\nimport { getError } from '../../../../../../utils/validationMsgs';\nimport {\n  SUB_TOTAL_FIELDS,\n  DEFAULT_OPTIONS,\n  getDisableField, DEFAULT_VALUES,\n  getSubFieldPosition,\n  KEYS,\n} from '../../../../../../constant/model';\nimport { AddRelation } from '../AddRelation';\nimport { LocalFields, NumberType, DateTime } from '../components/index';\nimport { Enum } from '../Enum';\nimport { SelectEnumValue } from '../Enum/SelectEnumValue';\nimport { DeleteRow } from './DeleteRow';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../../../constant/common';\nimport { modelAttrRegex } from '../../../../../../utils/regex';\nimport { useEditor } from '../../EditorProvider';\nimport { ORM_TYPE } from '../../../../../../constant/Project/applicationStep';\nimport { useModel } from '../../ModelProvider';\n\nconst AllCheckBox = ({\n  cname, onInputChange, watch, control, disable, onKeyDownHandle, id,\n}) => (\n  <>\n    <Controller\n      defaultValue={!!watch(cname)}\n      control={control}\n      name={cname}\n      render={(controlProps) => (\n        <Checkbox\n          {...controlProps}\n          checked={!!watch(cname)}\n          disabled={disable[cname]}\n          id={id}\n          onKeyDown={(e) => {\n            if (e.keyCode === 13) {\n              // setValue(cname, !e?.target?.checked);\n              controlProps.onChange(!e?.target?.checked);\n              onInputChange(cname, !e?.target?.checked, id);\n              // requestAnimationFrame(() => {\n              //   onKeyDownHandle(e, cname);\n              // });\n            } else { onKeyDownHandle(e, cname); }\n          }}\n          onChange={(value) => {\n            controlProps.onChange(value);\n            onInputChange(cname, value);\n          }}\n        />\n      )}\n    />\n  </>\n);\n\nconst TableSubRow = React.memo((props) => {\n  const {\n    subRow, modelList, currentId, localRef, onAddSubRow, onChange, lengthOfData, onRowKeyDown,\n    indexOfRow, rowObj, CONST_VARIABLE, dbType,\n  } = props;\n\n  const {\n    dependency, setDependency, ormType,\n  } = useEditor();\n  const { setChangeInTable } = useModel();\n  const { TABLE_TYPES, TYPE_OPTIONS } = CONST_VARIABLE;\n  const {\n    getValues, control, errors, setValue, watch,\n  } = useForm({\n    shouldUnregister: false,\n  });\n  const { FiledPosition } = getSubFieldPosition(props.index);\n\n  const dataTypeOptions = TYPE_OPTIONS.filter((x) => {\n    const condi = ![TABLE_TYPES.VIRTUAL_RELATION, TABLE_TYPES.OBJECTID, TABLE_TYPES.JSON,\n      TABLE_TYPES.MIXED, TABLE_TYPES.BUFFER, TABLE_TYPES.MAP].includes(x.id);\n    // (x.id !== TABLE_TYPES.VIRTUAL_RELATION);\n    if (rowObj.type !== TABLE_TYPES.JSON) {\n      // if type is not JSON\n      return condi && x.id !== TABLE_TYPES.POINT;\n    }\n    const isTypePointExist = rowObj.subRows.find((s) => s.type === TABLE_TYPES.POINT);\n    if (isTypePointExist && isTypePointExist?.key !== subRow.key) {\n      // exclude type Point if selected once\n      return condi && x.id !== TABLE_TYPES.POINT;\n    }\n    return condi; // if type is JSON include POINT\n  });\n\n  React.useEffect(() => {\n    if (rowObj.type !== TABLE_TYPES.JSON && (subRow.type === TABLE_TYPES.POINT)) {\n      // reset type field if point is selected\n      subRow.type = undefined;\n      setValue('type', undefined);\n    }\n  }, [rowObj.type]);\n\n  const onKeyDownHandle = (e, focusField) => {\n    const focusIndex = FiledPosition[focusField];\n\n    switch (e.keyCode) {\n      case 38:\n      { // up\n        let isFocused = false;\n        for (let nextIndex = SUB_TOTAL_FIELDS; nextIndex < lengthOfData * SUB_TOTAL_FIELDS; nextIndex += SUB_TOTAL_FIELDS) {\n          const field = document.querySelector(`#subrow${indexOfRow}${focusIndex - nextIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            isFocused = true;\n            break;\n          }\n        }\n        if (!isFocused && props.index === 0) {\n          // move to ROW focus\n          onRowKeyDown?.({ isUp: true, e, focusField });\n          break;\n        }\n        break; }\n      case 40:\n      { // down\n        let isFocused = false;\n        for (let nextIndex = SUB_TOTAL_FIELDS; nextIndex < lengthOfData * SUB_TOTAL_FIELDS; nextIndex += SUB_TOTAL_FIELDS) {\n          const field = document.querySelector(`#subrow${indexOfRow}${focusIndex + nextIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            isFocused = true;\n            break;\n          }\n        }\n        if (!isFocused && props.index === lengthOfData - 1) {\n          // move to ROW focus\n          onRowKeyDown?.({ isDown: true, e, focusField });\n          break;\n        }\n        break; }\n      case 37:\n      { // left\n        if (e.ctrlKey) {\n          let isFocused = false;\n          for (let nextIndex = 1; nextIndex !== lengthOfData * SUB_TOTAL_FIELDS; nextIndex += 1) {\n            const field = document.querySelector(`#subrow${indexOfRow}${focusIndex - nextIndex}`);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              isFocused = true;\n              break;\n            }\n          }\n          if (!isFocused && props.index === 0 && focusField === 'attr') {\n            // move to ROW focus\n            onRowKeyDown?.({ isPrev: true, e });\n            break;\n          }\n        }\n        break; }\n      case 39:\n      {\n        // right\n        if (e.ctrlKey) {\n          let isFocused = false;\n          for (let nextIndex = 1; nextIndex !== lengthOfData * SUB_TOTAL_FIELDS; nextIndex += 1) {\n            const field = document.querySelector(`#subrow${indexOfRow}${focusIndex + nextIndex}`);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              isFocused = true;\n              break;\n            }\n          }\n          if (!isFocused && props.index === lengthOfData - 1) {\n            // move to ROW focus\n            onRowKeyDown?.({ isNext: true, focusField: 'attr' });\n            break;\n          }\n        }\n        break; }\n      case 13:\n      {\n        // enter\n        let isFocused = false;\n        for (let nextIndex = 1; nextIndex !== lengthOfData * SUB_TOTAL_FIELDS; nextIndex += 1) {\n          const field = document.querySelector(`#subrow${indexOfRow}${focusIndex + nextIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            isFocused = true;\n            break;\n          }\n        }\n        if (!isFocused && props.index === lengthOfData - 1) {\n          // move to ROW focus\n          onRowKeyDown?.({ isNext: true, focusField: 'attr' });\n          break;\n        }\n        break; }\n\n      default:\n        break;\n    }\n  };\n\n  const handleAutoFocus = (focusId) => {\n    const ele = document.getElementById(focusId);\n    ele?.focus();\n  };\n\n  const onInputChange = React.useCallback((fieldName, value, focusId) => {\n    if (['enum', 'isEnum'].includes(fieldName)) { setValue(fieldName, value); }\n    if (value && value !== subRow[fieldName]) {\n      setChangeInTable();\n    }\n\n    if (fieldName === 'type' || fieldName === 'isEnum') {\n      setValue('isAutoIncrement', undefined);\n      setValue('default', undefined);\n      subRow.default = undefined;\n      subRow.isAutoIncrement = undefined;\n    }\n    if (fieldName === 'attr') {\n      if (!isEmpty(value) && !subRow.type) {\n        setValue('type', ormType === ORM_TYPE.MONGOOSE ? 'String' : 'STRING');\n        onInputChange('type');\n      }\n    }\n    const fieldValue = (value === undefined || value === null) ? getValues(fieldName) : value;\n    if (fieldName === 'type' && fieldValue === TABLE_TYPES.BOOL) {\n      setValue('filter', undefined);\n      subRow.filter = undefined;\n    }\n    if (fieldName === 'required' && fieldValue && subRow.filter === 'NULL') {\n      setValue('filter', undefined);\n      subRow.filter = undefined;\n    }\n    if (fieldName === 'isEnum') {\n      // assign value for enum validation\n      if (fieldValue && isEmpty(subRow.enum)) {\n        subRow.enum = {};\n        setValue('enum', {});\n      } else if (!fieldValue) {\n        subRow.enum = undefined;\n        setValue('enum', undefined);\n      }\n      setValue('default', undefined);\n      subRow.default = undefined;\n    }\n\n    if (fieldName === KEYS.match && fieldValue) {\n      // pattern enable then remove other validation\n      [KEYS.minLength, KEYS.maxLength, KEYS.lowercase, KEYS.trim].forEach((x) => {\n        subRow[x] = undefined;\n        setValue(x, undefined);\n      });\n    }\n\n    if (fieldValue !== subRow[fieldName]) {\n      // on change only when value is updated\n      if (dependency) {\n        setDependency(dependency.map((x) => {\n          if (subRow[fieldName] === x.oldKey) {\n            return { ...x, newKey: fieldValue };\n          }\n          return x;\n        }));\n      }\n      subRow[fieldName] = fieldValue;\n      if (fieldName === 'type' && subRow[fieldName] === TABLE_TYPES.POINT) {\n        // If type point is selected then add default row having attribute name coordinates and type Array\n        if (rowObj.subRows.find((s) => s.type !== TABLE_TYPES.ARRAY)) {\n          onAddSubRow({\n            isAdd: true,\n            dataObj: { type: TABLE_TYPES.ARRAY, attr: 'coordinates' },\n          });\n          if (props.index + 1 >= rowObj.subRows.length) {\n            // if empty row is not added\n            requestAnimationFrame(() => onAddSubRow());\n          }\n        }\n      }\n      onChange?.({\n        key: fieldName, value: fieldValue, index: props.index,\n      });\n      if (fieldName === 'attr') onAddSubRow();\n    }\n    if (focusId) {\n      requestAnimationFrame(() => {\n        handleAutoFocus(focusId);\n      });\n    }\n    // if (isNotFocus) return;\n    // requestAnimationFrame(() => {\n    //   onAutoFocus?.(fieldName, subRow.key, fieldValue, { index: props.index, isSubRow: true }); // manage auto focus\n    // });\n  }, [subRow, props?.index, onChange, onAddSubRow, rowObj, dependency]);\n\n  React.useEffect(() => {\n    if (subRow) {\n      const subRowArr = Object.keys(subRow);\n      subRowArr.map((r) => {\n        setValue(r, subRow[r]);\n        return r;\n      });\n      if (subRowArr.length === 2) {\n        // length 2 for new row (key and rowKey)\n        Object.keys(DEFAULT_VALUES).map((x) => {\n          setValue(x, subRow[x]);\n          return x;\n        });\n      }\n    }\n  }, [subRow]);\n\n  const disable = React.useMemo(() => getDisableField(watch('type'), { isAutoIncrement: watch('isAutoIncrement'), match: watch('match') }, dbType), [watch('type'), watch('isAutoIncrement'), dbType, watch('match')]);\n\n  const checkboxProps = {\n    onInputChange, watch, control, setValue, disable, onKeyDownHandle,\n  };\n\n  const RequiredCheckBox = React.useCallback(() => (\n    <AllCheckBox {...checkboxProps} cname=\"required\" id={`subrow${indexOfRow}${FiledPosition.required}`} />\n  ), [subRow, disable, watch('required')]);\n\n  const UniqueCheckBox = React.useCallback(() => (\n    <AllCheckBox {...checkboxProps} cname=\"unique\" id={`subrow${indexOfRow}${FiledPosition.unique}`} />\n  ), [subRow, disable, watch('unique')]);\n\n  const AutoIncCheckBox = React.useCallback(() => (\n    <AllCheckBox {...checkboxProps} cname=\"isAutoIncrement\" id={`subrow${indexOfRow}${FiledPosition.isAutoIncrement}`} />\n  ), [subRow, disable, watch('isAutoIncrement')]);\n\n  const LowerCheckBox = React.useCallback(() => (\n    <AllCheckBox {...checkboxProps} cname=\"lowercase\" id={`subrow${indexOfRow}${FiledPosition.lowercase}`} />\n  ), [subRow, disable, watch('lowercase')]);\n\n  const TrimCheckBox = React.useCallback(() => (\n    <AllCheckBox {...checkboxProps} cname=\"trim\" id={`subrow${indexOfRow}${FiledPosition.trim}`} />\n  ), [subRow, disable, watch('trim')]);\n\n  const PrivateCheckbox = React.useCallback(() => (\n    <AllCheckBox cname=\"private\" id={`subrow${indexOfRow}${FiledPosition.private}`} {...checkboxProps} />\n  ), [subRow, disable, watch('private')]);\n\n  // const IndexCheckBox = React.useCallback(() => (\n  //   <AllCheckBox {...checkboxProps} cname=\"index\" />\n  // ), [subRow, disable, watch('index')]);\n\n  return (\n    <>\n      <tr className={TableViewCss.subTableRow}>\n        <DragHandle style={{ zIndex: 1, left: '0px' }} />\n        <DeleteRow deleteObj={subRow} isSubRow />\n        <td className=\"flex items-center relative pl-12\">\n          <div className=\"tableInputSelect\">\n            <Controller\n              defaultValue={subRow.attr || ''}\n              control={control}\n              name=\"attr\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Input\n                  size=\"small\"\n                  dark\n                  {...controlProps}\n                  placeholder=\"Attributes\"\n                  WrapClassName=\"w-full\"\n                  id={`subrow${indexOfRow}${FiledPosition.attr}`}\n                  maxLength={MAX_INPUT_FIELD_LIMIT.title}\n                  customRegex={modelAttrRegex}\n                  disabled={watch('type') === '_id'}\n                  onBlur={() => onInputChange('attr', controlProps.value)}\n                  onKeyDown={(e) => onKeyDownHandle(e, 'attr')}\n                  error={getError(errors, 'attr', 'Attribute')}\n                />\n              )}\n            />\n          </div>\n        </td>\n        <td className=\"\">\n          <div className={`tableInputSelect ${watch('type') === TABLE_TYPES.VIRTUAL_RELATION && ''}`}>\n            <Controller\n              defaultValue={subRow.type || null}\n              control={control}\n              name=\"type\"\n              render={(controlProps) => (\n                <Select\n                  sizeSmall\n                  dark\n                  {...controlProps}\n                  isClearable={false}\n                  placeholder=\"Data type\"\n                  options={dataTypeOptions}\n                  disabled={disable.type}\n                  onChange={(value) => {\n                    controlProps.onChange(value);\n                    onInputChange('type');\n                  }}\n                  inputId={`subrow${indexOfRow}${FiledPosition.type}`}\n                  onKeyDown={(e) => {\n                    if (e.ctrlKey || e.keyCode === 13) {\n                      if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                        return;\n                      }\n                      onKeyDownHandle(e, 'type');\n                      if (e.ctrlKey) e.preventDefault();\n                    }\n                  }}\n                />\n\n              )}\n            />\n            {watch('type') === TABLE_TYPES.VIRTUAL_RELATION && (\n              <LocalFields\n                rowObj={subRow}\n                localField={subRow.localField}\n                localRef={localRef}\n                onInputChange={onInputChange}\n                id={`subrow${indexOfRow}${FiledPosition.localField}`}\n                onKeyDown={onKeyDownHandle}\n              />\n            )}\n          </div>\n        </td>\n        <td className=\"\">\n          <div className=\"tableInputSelect\">\n            {(watch('type') === TABLE_TYPES.STRING || watch('type') === TABLE_TYPES.NUMBER) && (\n              <Enum\n                disabled={disable.isEnum}\n                onInputChange={onInputChange}\n                row={subRow}\n                id={`subrow${indexOfRow}${FiledPosition.isEnum}`}\n                onKeyDown={(e) => onKeyDownHandle(e, 'isEnum')}\n              />\n            )}\n            {(watch('type') === TABLE_TYPES.OBJECTID || watch('type') === TABLE_TYPES.VIRTUAL_RELATION) ? (\n              <>\n                <AddRelation\n                  currentId={currentId}\n                  modelList={modelList}\n                  onInputChange={onInputChange}\n                  model={subRow.ref}\n                  foreignKey={subRow.foreignField}\n                  isVirtual={watch('type') === TABLE_TYPES.VIRTUAL_RELATION}\n                  id={`subrow${indexOfRow}${FiledPosition.relation}`}\n                  onKeyDown={(e) => onKeyDownHandle(e, 'relation')}\n                  CONST_VARIABLE={CONST_VARIABLE}\n                />\n              </>\n            ) : null}\n            {(watch('type') === TABLE_TYPES.OBJECTID || watch('type') === TABLE_TYPES.VIRTUAL_RELATION\n              || watch('type') === TABLE_TYPES.STRING || watch('type') === TABLE_TYPES.NUMBER) ? <></> : <>-</>}\n          </div>\n        </td>\n        <td className=\"\">\n          <div className={`tableInputSelect ${watch('filter') === 'AS_DEFINED' && ![TABLE_TYPES.BOOL, '_id'].includes(watch('type')) ? '' : '-mt-1'}`}>\n            { ![TABLE_TYPES.BOOL, '_id'].includes(watch('type'))\n              ? (\n                <Controller\n                  defaultValue={subRow.filter || null}\n                  control={control}\n                  name=\"filter\"\n                  render={(controlProps) => (\n                    <Select\n                      dark\n                      sizeSmall\n                      {...controlProps}\n                      placeholder=\"Default\"\n                      options={DEFAULT_OPTIONS}\n                      disabled={disable.filter}\n                      isOptionDisabled={(option) => option.id === 'NULL' && subRow.required}\n                      onChange={(value) => {\n                        controlProps.onChange(value);\n                        onInputChange('filter');\n                      }}\n                      inputId={`subrow${indexOfRow}${FiledPosition.filter}`}\n                      onKeyDown={(e) => {\n                        if (e.ctrlKey || e.keyCode === 13) {\n                          if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                            return;\n                          }\n                          onKeyDownHandle(e, 'filter');\n                          if (e.ctrlKey) e.preventDefault();\n                        }\n                      }}\n                    />\n\n                  )}\n                />\n              ) : null}\n\n            { ([TABLE_TYPES.BOOL, '_id'].includes(watch('type')))\n              ? (\n                <span className=\"text-center\">\n                  <Controller\n                    defaultValue={subRow.default || null}\n                    control={control}\n                    name=\"default\"\n                    render={(controlProps) => (\n                      <Select\n                        dark\n                        sizeSmall\n                        {...controlProps}\n                        WrapClassName=\"mt-1\"\n                        placeholder=\"Default value\"\n                        options={[{ id: 'true', name: 'TRUE' }, { id: 'false', name: 'FALSE' }]}\n                        isClearable={watch('type') !== '_id'}\n                        disabled={disable.default}\n                        onChange={(value) => {\n                          controlProps.onChange(value);\n                          onInputChange('default');\n                        }}\n                        inputId={`subrow${indexOfRow}${FiledPosition.default}`}\n                        onKeyDown={(e) => {\n                          if (e.ctrlKey || e.keyCode === 13) {\n                            if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                              return;\n                            }\n                            onKeyDownHandle(e, 'default');\n                            if (e.ctrlKey) e.preventDefault();\n                          }\n                        }}\n                      />\n                    )}\n                  />\n                </span>\n              )\n              : null}\n\n            {watch('filter') === 'AS_DEFINED'\n              && (\n              <>\n                {\n                      (watch('type') === TABLE_TYPES.NUMBER || watch('type') === TABLE_TYPES.PERCENT\n                      || watch('type') === TABLE_TYPES.DECIMAL) ? watch('isEnum') ? (\n                        <SelectEnumValue\n                          defaultValue={subRow?.default}\n                          enumObj={watch('enum')}\n                          row={subRow}\n                          disabled={disable.default}\n                          onInputChange={onInputChange}\n                          id={`subrow${indexOfRow}${FiledPosition.default}`}\n                          onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                        />\n                        ) : (\n                          <NumberType\n                            TABLE_TYPES={TABLE_TYPES}\n                            type={watch('type')}\n                            disabled={disable.default}\n                            id={`subrow${indexOfRow}${FiledPosition.default}`}\n                            defaultValue={subRow.default || ''}\n                            onInputChange={onInputChange}\n                            onKeyDown={onKeyDownHandle}\n                          />\n                        ) : watch('type') === TABLE_TYPES.STRING && watch('isEnum') ? (\n                          <SelectEnumValue\n                            defaultValue={subRow?.default}\n                            enumObj={watch('enum')}\n                            row={subRow}\n                            disabled={disable.default}\n                            onInputChange={onInputChange}\n                            id={`subrow${indexOfRow}${FiledPosition.default}`}\n                            onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                          />\n                        ) : (watch('type') === TABLE_TYPES.DATE)\n                          ? (\n                            <DateTime\n                              showTimeSelect\n                              disabled={disable.default}\n                              id={`subrow${indexOfRow}${FiledPosition.default}`}\n                              defaultValue={subRow.default}\n                              WrapClassName=\"w-full mt-1\"\n                              onInputChange={onInputChange}\n                              onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                            />\n                          ) : (\n                            <Controller\n                              defaultValue={subRow.default || ''}\n                              control={control}\n                              name=\"default\"\n                              render={(controlProps) => (\n                                <Input\n                                  {...controlProps}\n                                  size=\"small\"\n                                  placeholder=\"Default value\"\n                                  WrapClassName=\"w-full mt-1\"\n                                  disabled={disable.default}\n                                  onBlur={() => onInputChange('default', controlProps.value)}\n                                  id={`subrow${indexOfRow}${FiledPosition.default}`}\n                                  onKeyDown={(e) => onKeyDownHandle(e, 'default')}\n                                />\n                              )}\n                            />\n                          )\n                    }\n              </>\n              )}\n          </div>\n        </td>\n        <td className={TableViewCss.subTableCheckBox}>\n          <span className=\"text-center tableCheck\">\n            <PrivateCheckbox />\n          </span>\n          <span className=\"text-center tableCheck\">\n            <RequiredCheckBox />\n          </span>\n          <span className=\"text-center tableCheck\">\n            <UniqueCheckBox />\n          </span>\n          <span className=\"text-center tableCheck\">\n            <AutoIncCheckBox />\n          </span>\n        </td>\n        <td className=\"\">\n          <div className=\"smallInput\">\n            { (watch('type') === TABLE_TYPES.NUMBER || watch('type') === TABLE_TYPES.DECIMAL)\n              ? (\n                <Controller\n                  defaultValue={subRow.min || ''}\n                  control={control}\n                  name=\"min\"\n                  render={(controlProps) => (\n                    <Input.Number\n                      size=\"small\"\n                      dark\n                      {...controlProps}\n                      allowInteger\n                      placeholder=\"Min\"\n                      disabled={disable.min}\n                      onBlur={() => onInputChange('min', controlProps.value)}\n                      id={`subrow${indexOfRow}${FiledPosition.minimum}`}\n                      onKeyDown={(e) => onKeyDownHandle(e, 'minimum')}\n                    />\n\n                  )}\n                />\n              )\n              : (\n                <Controller\n                  defaultValue={subRow.minLength || ''}\n                  control={control}\n                  name=\"minLength\"\n                  render={(controlProps) => (\n                    <Input.Number\n                      size=\"small\"\n                      dark\n                      {...controlProps}\n                      placeholder=\"MinLength\"\n                      disabled={disable.minLength}\n                      onBlur={() => onInputChange('minLength', controlProps.value)}\n                      id={`subrow${indexOfRow}${FiledPosition.minimum}`}\n                      onKeyDown={(e) => onKeyDownHandle(e, 'minimum')}\n                    />\n\n                  )}\n                />\n              )}\n          </div>\n        </td>\n        <td className=\"\">\n          <div className=\"smallInput\">\n            {(watch('type') === TABLE_TYPES.NUMBER || watch('type') === TABLE_TYPES.DECIMAL) ? (\n              <Controller\n                defaultValue={subRow.max || ''}\n                control={control}\n                name=\"max\"\n                render={(controlProps) => (\n                  <Input.Number\n                    {...controlProps}\n                    allowInteger\n                    dark\n                    size=\"small\"\n                    placeholder=\"Max\"\n                    disabled={disable.max}\n                    onBlur={() => onInputChange('max', controlProps.value)}\n                    id={`subrow${indexOfRow}${FiledPosition.maximum}`}\n                    onKeyDown={(e) => onKeyDownHandle(e, 'maximum')}\n                  />\n\n                )}\n              />\n            )\n              : (\n                <Controller\n                  defaultValue={subRow.maxLength || ''}\n                  control={control}\n                  name=\"maxLength\"\n                  render={(controlProps) => (\n                    <Input.Number\n                      dark\n                      size=\"small\"\n                      {...controlProps}\n                      placeholder=\"MaxLength\"\n                      disabled={disable.maxLength}\n                      onBlur={() => onInputChange('maxLength', controlProps.value)}\n                      id={`subrow${indexOfRow}${FiledPosition.maximum}`}\n                      onKeyDown={(e) => onKeyDownHandle(e, 'maximum')}\n                    />\n\n                  )}\n                />\n              )}\n          </div>\n        </td>\n        <td className={TableViewCss.subTableCheckBox}>\n          <span className=\"text-center tableCheck\">\n            <LowerCheckBox />\n          </span>\n          <span className=\"text-center tableCheck\">\n            <TrimCheckBox />\n          </span>\n          {/*\n          <span className=\"text-center tableCheck\">\n            <IndexCheckBox />\n          </span> */}\n        </td>\n        <td className=\"\">\n          <div className=\"smallInput\">\n            <Controller\n              defaultValue={subRow.match || ''}\n              control={control}\n              name=\"match\"\n              render={(controlProps) => (\n                <Input\n                  size=\"small\"\n                  dark\n                  {...controlProps}\n                  placeholder=\"Pattern\"\n                  disabled={disable.match}\n                  onBlur={() => onInputChange('match', controlProps.value)}\n                  id={`subrow${indexOfRow}${FiledPosition.match}`}\n                  onKeyDown={(e) => onKeyDownHandle(e, 'match')}\n                />\n              )}\n            />\n          </div>\n        </td>\n      </tr>\n    </>\n  );\n});\nexport default TableSubRow;\nTableSubRow.displayName = 'TableSubRow';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/sqlTableRow.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 1)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          speed={2}\n          key={d}\n          width=\"100%\"\n          height=\"50px\"\n          viewBox=\"0 0 100% 50px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"15\" rx=\"3\" ry=\"3\" width=\"4%\" height=\"6\" />\n          <rect x=\"5%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"9%\" height=\"40\" />\n          <rect x=\"15.5%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"9%\" height=\"40\" />\n          <rect x=\"26%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"9%\" height=\"40\" />\n          <rect x=\"36%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"9%\" height=\"40\" />\n          <rect x=\"47%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"9%\" height=\"40\" />\n          <rect x=\"58.4%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"61.5%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"64.4%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"67.4%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"70.4%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n\n          <rect x=\"73%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"40\" />\n          <rect x=\"81%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"40\" />\n\n          <rect x=\"89%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n\n          <rect x=\"92%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"40\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableData/tableRow.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 1)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          speed={2}\n          key={d}\n          width=\"100%\"\n          height=\"50px\"\n          viewBox=\"0 0 100% 50px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"15\" rx=\"3\" ry=\"3\" width=\"4%\" height=\"6\" />\n          <rect x=\"5%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"30\" />\n          <rect x=\"13%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"30\" />\n          <rect x=\"22%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"30\" />\n          <rect x=\"30%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"30\" />\n\n          <rect x=\"40%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"43%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"46%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"49%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n\n          <rect x=\"52%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"6.5%\" height=\"30\" />\n          <rect x=\"60%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"6.5%\" height=\"30\" />\n\n          <rect x=\"68%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n          <rect x=\"71%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"24\" height=\"24\" />\n\n          <rect x=\"74%\" y=\"0\" rx=\"3\" ry=\"3\" width=\"7%\" height=\"30\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/TableHead.js",
    "content": "import React from 'react';\nimport ReactTooltip from 'react-tooltip';\nimport { Icons } from '@dhiwise/icons';\nimport { TableViewCss } from '../../../../../assets/css/tableViewCss';\nimport { IconBox } from '../../../../../components';\nimport { DB_TYPE } from '../../../../../constant/model';\n\nexport const TableHead = ({\n  onAddRow, dbType,\n  // onUpdateJson, tableJson\n}) => (\n  <div className={`${TableViewCss.tableHead} tableHead`}>\n    <tr>\n      <td className=\"pl-10\">\n        <div data-tip data-for=\"React-tooltip\" className=\"left-3 top-1.5 absolute\">\n          <IconBox icon={<Icons.Plus color=\"#fff\" />} tooltip=\"Add row\" variant=\"primary\" shape=\"rounded\" size=\"small\" onClick={() => onAddRow(undefined, true)} />\n        </div>\n        <div className=\"tableInputSelect\">Attributes</div>\n      </td>\n      <td className=\"\">\n        <div className=\"tableInputSelect\">Data type</div>\n      </td>\n      <td className=\"\">\n        <div className=\"tableInputSelect\">Value</div>\n      </td>\n      <td className=\"\">\n        <div className=\"tableInputSelect\">Default</div>\n      </td>\n      {dbType !== DB_TYPE.MONGODB\n        && (\n        <td className=\"\">\n          <div className=\"tableInputSelect\">Relation</div>\n        </td>\n        )}\n      <td className=\"check flex\">\n        <span data-tip data-for=\"Private\" className=\"text-center tableCheck\">\n          Private\n          <ReactTooltip id=\"Private\" place=\"bottom\" type=\"dark\">Private marked attribute will not be included in default API response</ReactTooltip>\n        </span>\n        {dbType !== DB_TYPE.MONGODB && (\n        <span data-tip data-for=\"primary\" className=\"text-center tableCheck\">\n          P\n          <ReactTooltip id=\"primary\" place=\"bottom\" type=\"dark\">Primary</ReactTooltip>\n        </span>\n        )}\n\n        <span data-tip data-for=\"require\" className=\"text-center tableCheck\">\n          R\n          <ReactTooltip id=\"require\" place=\"bottom\" type=\"dark\">Require</ReactTooltip>\n        </span>\n        <span data-tip data-for=\"unique\" className=\"text-center tableCheck\">\n          U\n          <ReactTooltip id=\"unique\" place=\"bottom\" type=\"dark\">Unique</ReactTooltip>\n        </span>\n\n        <span data-tip data-for=\"auto-increment\" className=\"text-center tableCheck\">\n          AI\n          <ReactTooltip id=\"auto-increment\" place=\"bottom\" type=\"dark\">Auto increment</ReactTooltip>\n        </span>\n      </td>\n      <td className=\"\">\n        <div className=\"smallInput\">Minimum</div>\n      </td>\n      <td className=\"\">\n        <div className=\"smallInput\">Maximum</div>\n      </td>\n      <td className=\"check flex\">\n        <span data-tip data-for=\"Lowercase\" className=\"text-center tableCheck\">\n          Low.\n          <ReactTooltip id=\"Lowercase\" place=\"bottom\" type=\"dark\">Lowercase</ReactTooltip>\n        </span>\n        {dbType === DB_TYPE.MONGODB\n        && (\n        <span data-tip data-for=\"Trim\" className=\"text-center tableCheck\">\n          Trim\n          <ReactTooltip id=\"Trim\" place=\"bottom\" type=\"dark\">Trim</ReactTooltip>\n        </span>\n        )}\n\n      </td>\n      <td className=\"\">\n        <div className=\"smallInput\">\n          Pattern\n        </div>\n      </td>\n\n    </tr>\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/components/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport { uniqBy } from 'lodash';\nimport React, { useEffect } from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport {\n  Select, Datepicker, Input,\n} from '../../../../../../components';\n\nexport const LocalFields = ({\n  localField, localRef, onInputChange, rowObj, onKeyDown, id, disabled,\n}) => {\n  const {\n    control, setValue, watch,\n  } = useForm({\n    shouldUnregister: false,\n  });\n  const [options, setOptions] = React.useState([]);\n\n  useEffect(() => {\n    const temp = [{ id: '_id', name: '_id' }];\n    localRef.map((x) => {\n      if (x !== rowObj?.attr) temp.push({ id: x, name: x });\n      return x;\n    });\n    setOptions(temp);\n  }, [localRef, rowObj]);\n\n  useEffect(() => setValue('localField', localField || '_id'), [localField]);\n\n  return (\n    <>\n\n      <Controller\n        control={control}\n        name=\"localField\"\n        render={(controlProps) => (\n          <Select\n            WrapClassName=\"mt-1\"\n            sizeSmall\n            {...controlProps}\n            isClearable={false}\n            placeholder=\"Select local field\"\n            options={uniqBy(options, 'id')}\n            onChange={(value) => {\n              controlProps.onChange(value);\n              onInputChange('localField', watch('localField'));\n            }}\n            onKeyDown={(e) => {\n              if (e.ctrlKey || e.keyCode === 13) {\n                if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                  return;\n                }\n                onKeyDown(e, 'localField');\n                if (e.ctrlKey) e.preventDefault();\n              }\n            }}\n            inputId={id}\n            disabled={disabled}\n          />\n\n        )}\n      />\n    </>\n  );\n};\n\nexport const InnerType = ({\n  innerDataType, TYPE_OPTIONS, onInputChange, onKeyDown, id, disabled,\n}) => {\n  const {\n    control, setValue, watch,\n  } = useForm({\n    shouldUnregister: false,\n  });\n\n  useEffect(() => setValue('innerDataType', innerDataType), [innerDataType]);\n\n  return (\n    <>\n      <Controller\n        control={control}\n        name=\"innerDataType\"\n        render={(controlProps) => (\n          <Select\n            WrapClassName=\"mt-1\"\n            sizeSmall\n            {...controlProps}\n            isClearable\n            placeholder=\"Select inner type\"\n            options={TYPE_OPTIONS || []}\n            onChange={(value) => {\n              controlProps.onChange(value);\n              onInputChange('innerDataType', watch('innerDataType'));\n            }}\n            onKeyDown={(e) => {\n              if (e.ctrlKey || e.keyCode === 13) {\n                if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                  return;\n                }\n                onKeyDown(e, 'innerDataType');\n                if (e.ctrlKey) e.preventDefault();\n              }\n            }}\n            inputId={id}\n            disabled={disabled}\n          />\n        )}\n      />\n    </>\n  );\n};\n\nexport const DateTime = ({\n  defaultValue, onInputChange, onKeyDown, id, disabled, showTimeSelect,\n}) => {\n  const { control, setValue } = useForm({\n    shouldUnregister: false,\n  });\n\n  useEffect(() => setValue('default', defaultValue), [defaultValue]);\n\n  return (\n    <>\n      <Controller\n        control={control}\n        name=\"default\"\n        render={(controlProps) => (\n          <Datepicker\n            showTimeSelect={showTimeSelect}\n            WrapClassName=\"mt-1\"\n            sizeSmall\n            {...controlProps}\n            isClearable\n            size=\"small\"\n            placeholder=\"Select date\"\n            onChange={(value) => {\n              controlProps.onChange(value);\n              onInputChange('default', value);\n            }}\n            onKeyDown={(e) => {\n              if (e.ctrlKey || e.keyCode === 13) {\n                if (e.keyCode === 13 && controlProps.ref?.current?.state?.menuIsOpen) {\n                  return;\n                }\n                onKeyDown(e, 'default');\n                if (e.ctrlKey) e.preventDefault();\n              }\n            }}\n            id={id}\n            disabled={disabled}\n          />\n        )}\n      />\n    </>\n  );\n};\n\nexport const NumberType = ({\n  onInputChange, onKeyDown, id, disabled, defaultValue, type, TABLE_TYPES,\n}) => {\n  const { control, setValue } = useForm({\n    shouldUnregister: false,\n  });\n\n  useEffect(() => setValue('default', defaultValue), [defaultValue]);\n\n  const inputProps = {\n    size: 'small',\n    placeholder: 'Default value',\n    WrapClassName: 'w-full mt-1',\n    disabled,\n    id,\n    onKeyDown: (e) => onKeyDown(e, 'default'),\n  };\n\n  return (\n    <>\n      <Controller\n        control={control}\n        name=\"default\"\n        render={(controlProps) => (([TABLE_TYPES.FLOAT, TABLE_TYPES.DOUBLE, TABLE_TYPES.DECIMAL,\n          TABLE_TYPES.REAL].includes(type)) ? (\n            <Input.Decimal\n              {...inputProps}\n              allowPosNeg\n              value={controlProps.value ? controlProps.value.toString() : ''}\n              onChange={(val) => controlProps?.onChange(val === undefined ? undefined : Number(val))}\n              onBlur={() => onInputChange('default', controlProps.value === undefined ? undefined : Number(controlProps.value))}\n              fixLength={20}\n            />\n          ) : (\n            <Input.Number\n              {...inputProps}\n              allowInteger\n              value={controlProps.value || controlProps.value === 0 ? controlProps.value.toString() : ''}\n              onChange={(val) => controlProps?.onChange(val === undefined ? undefined : Number(val))}\n              onBlur={() => onInputChange('default', controlProps.value === undefined ? undefined : Number(controlProps.value))}\n            />\n          ))}\n      />\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/TableView/index.js",
    "content": "/* eslint-disable no-plusplus */\n/* eslint-disable react/jsx-props-no-spreading */\n/* eslint-disable radix */\nimport React, { useState } from 'react';\nimport memoize from 'memoize-one';\nimport arrayMove from 'array-move';\nimport {\n  last, cloneDeep, extend,\n} from 'lodash';\nimport { VariableSizeList as List } from 'react-window';\nimport { SortableContainer, SortableElement } from 'react-sortable-hoc';\nimport InfiniteLoader from 'react-window-infinite-loader';\nimport AutoSizer from 'react-virtualized-auto-sizer';\nimport { TableHead } from './TableHead';\nimport { useEditor } from '../EditorProvider';\nimport TableRow from './TableData/TableRow';\n// import { Loader } from '../../../../../components';\nimport Spinner from './TableData/tableRow.loader';\nimport SpinnerSql from './TableData/sqlTableRow.loader';\nimport { DB_TYPE } from '../../../../../constant/model';\n\nconst LOADING = 1;\nconst LOADED = 2;\n// const itemStatusMap = {};\n\n// const isItemLoaded = (index) => !!itemStatusMap[index];\n// const loadMoreItems = (startIndex, stopIndex) => {\n//   for (let index = startIndex; index <= stopIndex; index++) {\n//     itemStatusMap[index] = LOADING;\n//   }\n//   return new Promise((resolve) => setTimeout(() => {\n//     for (let index = startIndex; index <= stopIndex; index++) {\n//       itemStatusMap[index] = LOADED;\n//     }\n//     resolve();\n//   }, 500));\n// };\n\n// const TableRow = React.lazy(() => new Promise((resolve) => resolve(import('./TableData/TableRow'))));\n\nconst createItemData = memoize(({ items, ...otherProps }) => ({\n  items,\n  ...otherProps,\n}));\n\nconst SortableItem = SortableElement(({\n  row, mainRowId, index, rowIndex, itemStatusMap, ...otherProps\n}) => (row ? (\n  <>\n    {\n        itemStatusMap[rowIndex] === LOADED\n          ? (\n            <TableRow\n              row={row}\n              index={rowIndex}\n              {...otherProps}\n            />\n          )\n          : (\n            <div className=\"border-t border-gray-200 py-2\" id={row.key} style={otherProps.style}>\n              {\n                otherProps?.dbType === DB_TYPE.MONGODB ? <Spinner /> : <SpinnerSql />\n              }\n            </div>\n          )\n      }\n  </>\n) : null));\n\nconst getSize = (index, items, TABLE_TYPES, dbType) => {\n  const isMongoDb = dbType === DB_TYPE.MONGODB;\n  const r = items?.[index];\n  let size = 48;\n  if (r) {\n    const subRow = isMongoDb && r.isExpand && (r.type === TABLE_TYPES.ARRAY || r.type === TABLE_TYPES.JSON);\n    const doubleRow = (r?.filter === 'AS_DEFINED' || (isMongoDb && r.type === TABLE_TYPES.VIRTUAL_RELATION));\n    if (doubleRow) size *= 2; // row having double fields\n    if (subRow) {\n    // row having sub-attributes\n      size += (30 + 21); // for add sub-row text and padding\n      if (r?.subRows?.length > 0) {\n        const subDbRow = r.subRows.filter((x) => x.filter === 'AS_DEFINED');\n        if (subDbRow?.length > 0) {\n          size += ((48 * 2)) * subDbRow?.length;\n          size += (48 * (r?.subRows?.length - subDbRow.length));\n        } else { size += (48 * r?.subRows?.length); }\n      }\n      return size;\n    }\n  }\n  return size; // single row\n};\n\nconst Row = ({\n  index, style, data,\n}) => {\n  const { items, itemStatusMap, ...otherProps } = data;\n  const r = items[index];\n  if (!r) return null;\n  return (\n    <SortableItem\n      row={r}\n      index={index}\n      rowIndex={index}\n      useDragHandle\n      style={style}\n      itemStatusMap={itemStatusMap}\n      tableJson={items}\n      {...otherProps}\n    />\n  );\n};\n\nconst SortableList = SortableContainer((props) => {\n  const { TABLE_TYPES } = useEditor();\n  const { items, listRef, ...otherProps } = props;\n  const [itemStatusMap, setItemMap] = useState({});\n  const itemData = createItemData({ items, itemStatusMap, ...otherProps });\n\n  return (\n    <div className=\"h-full\">\n      <AutoSizer style={{ height: '100%', width: '100%' }}>\n        {({ height }) => (\n          <InfiniteLoader\n            isItemLoaded={(index) => !!itemStatusMap[index]}\n            itemCount={items.length}\n            loadMoreItems={(startIndex, stopIndex) => {\n              for (let index = startIndex; index <= stopIndex; index++) {\n                setItemMap((old) => {\n                  const newObj = { ...old };\n                  newObj[index] = LOADING;\n                  return newObj;\n                });\n              }\n              return new Promise((resolve) => setTimeout(() => {\n                for (let index = startIndex; index <= stopIndex; index++) {\n                  setItemMap((old) => {\n                    const newObj = { ...old };\n                    newObj[index] = LOADED;\n                    return newObj;\n                  });\n                }\n                resolve();\n              }, 500));\n            }}\n          >\n            {({ onItemsRendered, ref }) => (\n              <List\n                ref={(list) => {\n                  ref(list);\n                  listRef.current = list;\n                }}\n                height={height} // total height calc height \"tableScroll\"\n                // width={calcWidthPixel}\n                style={{ overflowX: 'hidden' }}\n                itemCount={items.length} // as new row will be added\n                itemData={itemData}\n                itemSize={(index) => getSize(index, items, TABLE_TYPES, otherProps.dbType)}\n                onItemsRendered={onItemsRendered}\n                useDragHandle\n                useIsScrolling\n                itemKey={(idx, data) => {\n                  const { key } = data.items[idx];\n                  return key;\n                }}\n              >\n                {Row}\n              </List>\n            )}\n          </InfiniteLoader>\n        )}\n      </AutoSizer>\n    </div>\n  );\n});\n\nconst TableView = () => {\n  const {\n    tableJson, setTableJson,\n    tableToCodeViewParser, listRef, dbType, TABLE_TYPES, currentApplicationCode,\n  } = useEditor();\n\n  // const editorLoader = useSelector((state) => state.models.editorLoader);\n\n  // const dispatch = useDispatch();\n  const [localRef, setLocalRef] = useState([]);\n  // const [loading, setLoading] = useState(false);\n  // const [loader, setLoader, hideLoader] = useBoolean(false);\n\n  const handleCurEleFocus = React.useCallback((key) => {\n    // handle new row focus\n    requestAnimationFrame(() => {\n      const nextfield = document.querySelector(`#${key} input[name=\"attr\"]`);\n      nextfield?.focus();\n    });\n  }, []);\n\n  const handleAddRow = React.useCallback((tableArr, isAutoFocus) => {\n    // add new row\n    const newTable = tableArr ? cloneDeep(tableArr) : [...tableJson];\n    const obj = {\n      key: `r${newTable.length}`,\n    };\n    newTable.push(obj);\n    setTableJson(newTable);\n    // setLoading(false);\n    requestAnimationFrame(() => {\n      listRef?.current?.scrollToItem?.(newTable.length - 1); // add new row from head\n    });\n    if (isAutoFocus) {\n      setTimeout(() => {\n        handleCurEleFocus(obj.key);\n      }, 1000);\n    }\n  }, [tableJson, listRef?.current, handleCurEleFocus]);\n\n  const handleAddSubRow = React.useCallback((row, isAutoFocus, opt) => {\n    // add new sub row\n    const newTable = [...tableJson];\n    const index = newTable.findIndex((r) => r.key === row.key);\n    if (index > -1) {\n      const newSubTable = newTable[index].subRows\n        ? [...newTable[index].subRows]\n        : [];\n      let obj = {\n        key: `rs${newSubTable.length}`,\n        rowKey: row.key,\n      };\n      if (opt?.isAdd) {\n        obj = extend(obj, opt.dataObj);\n      }\n      newSubTable.push(obj);\n      newTable[index].subRows = newSubTable;\n      setTableJson(newTable);\n      listRef?.current?.resetAfterIndex?.(index);\n      if (isAutoFocus) {\n        handleCurEleFocus(obj.key);\n      }\n    }\n  }, [tableJson, listRef?.current]);\n\n  const handleSortEnd = React.useCallback(({ oldIndex, newIndex }, row) => {\n    if (oldIndex === newIndex) return;\n    let newTable = [...tableJson];\n    if (row?.subRows) {\n      // sub row sorting\n      const newSubTable = row.subRows ? [...row.subRows] : [];\n      const index = newTable.findIndex((r) => r.key === row.key);\n      if (index < 0) return;\n      newTable[index].subRows = arrayMove(newSubTable, oldIndex, newIndex);\n    } else newTable = arrayMove(newTable, oldIndex, newIndex);\n    setTableJson(newTable);\n  }, [tableJson, listRef?.current]);\n\n  const handleExpand = React.useCallback((row, str) => {\n    const newTable = [...tableJson];\n    const index = newTable.findIndex((r) => r.key === row.key);\n    if (index < 0) return;\n    newTable[index].isExpand = !newTable[index].isExpand;\n    if ((!newTable[index].subRows || newTable[index].subRows?.length === 0) && str === 'sub-attr') {\n      // add sub row for empty\n      newTable[index].subRows = [{ key: `rs${newTable[index].subRows?.length || 0}`, rowKey: row.key }];\n      handleCurEleFocus('rs0');\n    } else if (newTable[index].isExpand && newTable[index].subRows?.length > 0 && last(newTable[index].subRows)?.attr?.length > 0) {\n      // add sub row for existing on expand\n      newTable[index].subRows.push({ key: `rs${newTable[index].subRows.length}`, rowKey: row.key });\n    }\n    setTableJson(newTable);\n    listRef?.current?.resetAfterIndex?.(index); // to reset virtual scroll height\n  }, [tableJson, listRef?.current, handleCurEleFocus]);\n\n  React.useEffect(() => {\n    setLocalRef(tableJson?.map((x) => x.attr));\n  }, [tableJson]);\n\n  const handleChangeInput = React.useCallback(({ key, index, value }) => {\n    let forceUpdate = true;\n    if (key === 'attr') {\n      setLocalRef(tableJson.map((x) => x.attr));\n      if (last(tableJson).attr?.length > 0) {\n        forceUpdate = false;\n        handleAddRow();\n      } else tableToCodeViewParser();\n    }\n\n    if (key === 'isEnum') {\n      const tableData = tableJson.map((x) => x);\n      setTableJson(tableData);\n    }\n    if (key === 'isEnum' || (key === 'filter' || (key === 'type'))) {\n    // to reset virtual scroll height\n      listRef?.current?.resetAfterIndex?.(index);\n    }\n    if (key === 'type' && value === TABLE_TYPES.ARRAY && dbType === DB_TYPE.MONGODB) {\n      const tableData = tableJson.map((x) => x);\n      if (!tableData[index].subRows?.find((x) => x.type === '_id')) {\n        // default value false of__id\n        tableData[index].subRows = extend(tableData[index].subRows || [], [{\n          key: `rs${tableData[index].subRows?.length ? tableData[index].subRows.length - 1 : 0}`,\n          attr: '_id',\n          default: 'false',\n          type: '_id',\n          rowKey: tableData[index].key,\n        }]);\n        setTableJson(tableData);\n      }\n    } else if (key === 'type' && value === TABLE_TYPES.JSON && dbType === DB_TYPE.MONGODB) {\n      // default value false of__id\n      const tableData = tableJson.map((x) => x);\n      tableData[index].subRows = tableData[index].subRows?.filter((x) => x.type !== '_id');\n      setTableJson(tableData);\n    }\n    if (key !== 'attr') { tableToCodeViewParser(); }\n    if (forceUpdate && (key === 'attr' || key === 'type') && dbType !== DB_TYPE.MONGODB) {\n      // for SQL databse force-render table\n      const tableData = tableJson.map((x) => x);\n      setTableJson(tableData);\n    }\n  }, [tableJson, tableToCodeViewParser, listRef?.current, handleAddRow, dbType]);\n\n  const handleSubRowChange = React.useCallback(({ key, rowIndex }) => {\n    if ((key === 'filter')) {\n    // to reset virtual scroll height\n      listRef?.current?.resetAfterIndex?.(rowIndex);\n    }\n    tableToCodeViewParser();\n  }, [tableJson, tableToCodeViewParser, listRef?.current]);\n\n  return (\n    <div className=\"tableAuto\" style={{ overflowY: 'hidden' }}>\n      {\n      //  loader\n      //    ? (\n      //      <Loader\n      //        style={{ minHeight: '100%' }}\n      //      />\n      //    )\n      //    : (\n        <table className=\"tableScroll flex flex-col sm:p-0\">\n          <TableHead onAddRow={handleAddRow} dbType={dbType} currentApplicationCode={currentApplicationCode} />\n          <div className=\"h-0 flex-grow\">\n            {/* <React.Suspense fallback={<p>loading</p>}> */}\n            <SortableList\n              useDragHandle\n              items={tableJson}\n              onSortEnd={handleSortEnd}\n              onAddSubRow={handleAddSubRow}\n              onSubSortEnd={handleSortEnd}\n              onExpand={handleExpand}\n              onChange={handleChangeInput}\n              onSubRowChange={handleSubRowChange}\n              localRef={localRef}\n              listRef={listRef}\n              lengthOfData={tableJson?.length}\n              dbType={dbType}\n            />\n            {/* </React.Suspense> */}\n          </div>\n        </table>\n            }\n    </div>\n  );\n};\nexport default TableView;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Editor/index.js",
    "content": "/* eslint-disable no-param-reassign */\n/* eslint-disable no-nested-ternary */\n/* eslint-disable radix */\nimport React, { useState } from 'react';\nimport {\n  cloneDeep, isArray, isEmpty, omit,\n} from 'lodash';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport omitDeep from 'omit-deep-lodash';\nimport { useHistory } from 'react-router';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Button, MessageNotify, Error, Loader, ConfirmationAlert,\n} from '../../../../components';\nimport ModelHeader from './ModelHeader';\nimport { updateModel } from '../../../../redux/reducers/models';\nimport { useBoolean } from '../../../../components/hooks';\nimport { API_URLS, apiClient } from '../../../../api';\n// import DeleteModel from '../DeleteModel';\nimport useToastNotifications from '../../../hooks/useToastNotifications';\nimport {\n  ERROR_MSG, getParsedType, getParsedKeys, parsedKeys,\n  DB_TYPE, util, isNumberType, KEYS, DB_CONST, pluralizeTableName,\n} from '../../../../constant/model';\nimport { EditorProvider } from './EditorProvider';\nimport { EditorTabs } from './EditorTabs';\nimport {\n  emailRegex, isRegExp, modelAttrRegex, URLRegex,\n} from '../../../../utils/regex';\nimport { useModel } from './ModelProvider';\nimport { IndexProvider } from '../Indexing/SQLIndexing/IndexProvider';\nimport { checkDuplicate, SQL_INDEX, findDuplicate } from '../../../../constant/modelIndexing';\nimport { RedirectUrl } from '../../../../constant/Nodecrud';\n\nexport const NoModelData = 'Create at least one model. You can\\'t proceed further as further steps are dependent on the models.';\nconst jsonLint = require('jsonlint');\n\nconst ErrorNotify = () => (\n  <div className=\"p-2\">\n    <MessageNotify size=\"small\" messageType=\"alert\" isAlert>\n      This model will be not included in generated code. Please resolve\n      error first\n    </MessageNotify>\n  </div>\n);\n\nconst Editor = React.memo(({ currentId, saveRef, loaderRef }) => {\n  const {\n    modelErrors, modelErrCount, isError, setModelErrors, setIsJsonError, setNoChangeInTable, isSaveWarning, hideSaveWarning, changeNextEvent,\n  } = useModel();\n  const history = useHistory();\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const dispatch = useDispatch();\n\n  const {\n    modelList, currentApplicationCode, dbType, detailFetching,\n  } = useSelector(({ models, projects }) => ({\n    dbType: DB_CONST[projects.applicationDatabase.databaseType],\n    modelList: models.modelList,\n    currentApplicationCode: projects.currentApplicationCode,\n    detailFetching: models.detailFetching,\n  }), shallowEqual);\n\n  const TABLE_TYPES = React.useMemo(() => util.getTableTypes(dbType), [dbType]);\n  const currentModel = React.useMemo(() => modelList.find((model) => model._id === currentId), [currentId, modelList]);\n\n  const [jsonError, setJsonError] = useState(false);\n  // const [showError, setShowError] = useBoolean(false);\n  const [showError, setShowError, setHideError] = useBoolean(false);\n  const [isSaveLoading, setSaveLoading, hideSaveLoading] = useBoolean(false); // for save warning popup loading\n  // Remove\n  // const [, setSaveLoader, hideSaveLoader] = useBoolean(false);\n  // saveLoader,\n\n  const tabRef = React.useRef();\n  const updateRef = React.useRef();\n  React.useEffect(() => setIsJsonError(!!jsonError?.isCustom), [jsonError]);\n  React.useEffect(() => {\n    if (modelErrCount && jsonError) setJsonError(false);\n  }, [modelErrCount]);\n\n  const handleShowError = () => {\n    setShowError();\n  };\n\n  const isCustomErr = React.useCallback((parseCode, isKey, mainAttrObj, options) => {\n    let errorFlag = false;\n    if (!parseCode) return errorFlag;\n    Object.keys(parseCode).every((x) => {\n      if (x === '_id') return x; // don't check for validation\n      if (!isKey && (parseCode[x] === null || (typeof parseCode[x] === 'string' && !parseCode[x])\n      || (typeof parseCode[x] === 'object' && Object.entries(parseCode[x]).length === 0))) {\n        // do not update json if value contains [{},'',null]\n        errorFlag = { name: 'Error', message: `${x}: Expecting value, got empty`, isCustom: true };\n        if (errorFlag) return errorFlag;\n      }\n\n      // sub-attr logic starts\n      let isSubAttr = false;\n      if (dbType === DB_TYPE.MONGODB && typeof parseCode[x] === 'object' && Array.isArray(parseCode[x])) {\n        isSubAttr = true;\n      } else if (dbType === DB_TYPE.MONGODB && parseCode[x] && typeof parseCode[x] === 'object' && Object.keys(parseCode[x])?.length > 0) {\n        // type object\n        if (Object.values(parseCode[x]).some((v) => typeof v === 'object' && v)) {\n          // if any value has type object\n          isSubAttr = true;\n        }\n      }\n      if (isSubAttr) {\n        if (!errorFlag) {\n          errorFlag = isCustomErr(Array.isArray(parseCode[x]) ? parseCode[x][0] : parseCode[x],\n            false,\n            { parseCode, attribute: x, isSubAttr },\n            options);\n        }\n        if (errorFlag) return errorFlag;\n      }\n      // sub-attr logic ends\n\n      if (typeof x === 'string' && !modelAttrRegex.test(x)) {\n        // attribute name validation\n        errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.attrName}`, isCustom: true };\n        if (errorFlag) return errorFlag;\n      }\n\n      if (dbType === DB_TYPE.MONGODB && typeof parseCode[x] === 'object' && !isArray(parseCode[x]) && parseCode[x] && Object.entries(parseCode[x])?.length > 0) {\n        if (!errorFlag) errorFlag = isCustomErr(parseCode[x], true, { parseCode, attribute: x }, options);\n        if (errorFlag) return errorFlag;\n      }\n      if (typeof parseCode[x] === 'object' && !isEmpty(parseCode[x]) && !(Array.isArray(parseCode[x])\n      || (Object.keys(parseCode[x])?.length > 0\n      && typeof parseCode[x][Object.keys(parseCode[x])?.[0]] === 'object'))\n       && !getParsedType(parseCode[x]?.type, dbType)) {\n        errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.type}`, isCustom: true };\n        if (errorFlag) return errorFlag;\n      }\n      if (parseCode[x]?.min > parseCode[x]?.max) {\n        errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.minMax}`, isCustom: true };\n        if (errorFlag) return errorFlag;\n      }\n      if (parseCode[x]?.minLength > parseCode[x]?.maxLength) {\n        errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.minMaxLength}`, isCustom: true };\n        if (errorFlag) return errorFlag;\n      }\n      if (parseCode[x] && isNumberType(parseCode[x].type, TABLE_TYPES)) {\n        // default value validation\n        if (parseCode[x].default && parseCode[x].min && parseCode[x].default < parseCode[x].min) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.min}`, isCustom: true };\n        } else if (parseCode[x].default && parseCode[x].max && parseCode[x].default > parseCode[x].max) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.max}`, isCustom: true };\n        }\n        if (errorFlag) return errorFlag;\n      }\n      if (parseCode[x]) {\n        // default value validation\n        if (parseCode[x]?.type === TABLE_TYPES.EMAIL && parseCode[x]?.default && !emailRegex.test(parseCode[x].default)) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.email}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        }\n        if (parseCode[x]?.type === TABLE_TYPES.URL && parseCode[x]?.default && !URLRegex.test(parseCode[x].default)) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.url}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        }\n        if (parseCode[x].default && parseCode[x].minLength && parseCode[x].default?.length < parseInt(parseCode[x].minLength)) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.minLength}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        } if (parseCode[x].default && parseCode[x].maxLength && parseCode[x].default?.length > parseInt(parseCode[x].maxLength)) {\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.maxLength}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        }\n        if (!isKey && dbType === DB_TYPE.MONGODB && !parseCode[x]?.ref\n           && [TABLE_TYPES.OBJECTID, TABLE_TYPES.VIRTUAL_RELATION].includes(parseCode[x]?.type)) {\n          // ref validaion (select model)\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.ref}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        }\n        if (!isKey && dbType === DB_TYPE.MONGODB && parseCode[x].type === TABLE_TYPES.VIRTUAL_RELATION) {\n          // manage virtual realtionship\n          if (!parseCode[x].ref || !parseCode[x].foreignField || !parseCode[x].localField) {\n            const msg = `${!parseCode[x].foreignField ? 'foreignField' : ''}\n            ${!parseCode[x].ref ? 'ref' : ''} ${!parseCode[x].localField ? 'ref' : ''} `;\n            errorFlag = { name: 'Error', message: `${x}: Select ${msg}`, isCustom: true };\n            if (errorFlag) return errorFlag;\n            // cErrors.push(err);\n          }\n        }\n        if ((!isEmpty(options?.customSetting?.[x]) || (mainAttrObj?.isSubAttr\n           && !isEmpty(options?.customSetting?.[mainAttrObj.attribute]?.[x])))\n          && ((dbType === DB_TYPE.MONGODB && (parseCode[x]?.type === TABLE_TYPES.NUMBER\n            || parseCode[x]?.type === TABLE_TYPES.STRING)) || parseCode[x]?.type === TABLE_TYPES.ENUM)\n        ) {\n          // manage ENUM type\n\n          // eslint-disable-next-line no-inner-declarations\n          function enumValidation(eObj) {\n            // return if undefined or have sub-attribute\n            if (!eObj || !eObj?.isEnum || (Object.values(parseCode[x]).some((v) => typeof v === 'object' && v))) { return; }\n            let enumKeys = '';\n            if (!eObj.enum) enumKeys = 'enumFile, enumAttribute, default';\n            else {\n              if (!eObj.enum?.enumFile) enumKeys += 'enumFile';\n              if (!eObj.enum?.enumAttribute) enumKeys += ', enumAttribute';\n              if (!eObj.enum?.default) enumKeys += ', default value';\n            }\n            if (enumKeys) {\n              errorFlag = {\n                name: 'Error', message: `${x}: Select ${enumKeys}`, isCustom: true,\n              };\n            }\n          }\n\n          if (mainAttrObj?.attribute) {\n            // for subattr\n            const o = isArray(options?.customSetting?.[mainAttrObj.attribute]) ? options?.customSetting?.[mainAttrObj.attribute]?.[0] : options?.customSetting?.[mainAttrObj.attribute]?.[x];\n            enumValidation(o);\n          } else { enumValidation(options?.customSetting?.[x]); }\n          if (errorFlag) return errorFlag;\n        }\n        if (dbType === DB_TYPE.MONGODB && isKey && mainAttrObj && parseCode[x].type === TABLE_TYPES.POINT) {\n          // manage POINT type\n          const isExist = Object.keys(parseCode).find((s) => parseCode[s]?.type === TABLE_TYPES.ARRAY);\n          if (!isExist) {\n            errorFlag = {\n              name: 'Error', message: `${mainAttrObj?.attribute}: ${ERROR_MSG.point}`, isCustom: true,\n            };\n            if (errorFlag) return errorFlag;\n          }\n          if (dbType === DB_TYPE.MONGODB && x !== 'type') {\n            // Attribute name must be 'type' for type 'Point'\n            errorFlag = {\n              name: 'Error', message: `${mainAttrObj?.attribute}: ${ERROR_MSG.pointAttr}`, isCustom: true,\n            };\n            if (errorFlag) return errorFlag;\n          }\n        }\n        if (parseCode[x].match && !isKey) {\n          if (!isRegExp(parseCode[x].match)) {\n            errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.match}`, isCustom: true };\n            if (errorFlag) return errorFlag;\n          }\n          const regex = RegExp(parseCode[x].match.slice(1, -1));\n          if (parseCode[x].default && !regex.test(parseCode[x].default)) {\n            // validate default value as per regex\n            errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.matchRegex}`, isCustom: true };\n            if (errorFlag) return errorFlag;\n          }\n        }\n        if (dbType !== DB_TYPE.MONGODB && parseCode[x].ref && !isKey) {\n          if (!parseCode[x].refAttribute) {\n            errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.refAttr}`, isCustom: true };\n          } else if (!parseCode[x].relType) {\n            errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.relType}`, isCustom: true };\n          }\n          if (errorFlag) return errorFlag;\n        }\n        if (dbType === DB_TYPE.MONGODB && parseCode[x]?.type === TABLE_TYPES.PERCENT && (parseCode[x]?.default < 0 || parseCode[x]?.default > 100)) {\n          // Default value between 0 to 100\n          errorFlag = { name: 'Error', message: `${x}: ${ERROR_MSG.percentage}`, isCustom: true };\n          if (errorFlag) return errorFlag;\n        }\n      }\n      return x;\n    });\n    return errorFlag;\n  }, []);\n\n  const saveJSON = React.useCallback(({\n    isInSaveWarning = false, showMsg, tCode, tcustomSetting, indexes, tHooks, msg, isRedirect = false, tDependency,\n  }) => {\n  // Remove\n  // isRedirect= if step remove ,remove await and async\n    try {\n      if (jsonError && !jsonError?.isCustom && !modelErrCount) {\n        // if error then open error popup\n        if (isInSaveWarning) hideSaveWarning();\n        handleShowError();\n        return;\n      }\n      if (!tabRef || !tabRef.current) return;\n      const data = tCode || tabRef?.current?.code;\n      const dependency = tDependency || tabRef?.current?.dependency;\n      const schema = jsonLint.parse(data);\n      let hooks = tHooks || tabRef?.current?.hooks;\n      let customSetting = tcustomSetting || tabRef?.current?.customSetting;\n      let modelIndexes = cloneDeep(indexes) || cloneDeep(tabRef?.current?.modelIndexList) || [];\n      if (isEmpty(currentModel?.schemaJson) && isEmpty(schema)) {\n        if (isRedirect && modelList.findIndex((m) => !isEmpty(m.schemaJson)) >= 0) {\n          history.push(RedirectUrl[currentApplicationCode].model.nextUrl);\n        }\n        return;\n      }\n      if (hooks?.length > 0) {\n        hooks = hooks.map((x) => omit(x, ['isExist']));\n      }\n      let indexErrors = false;\n      if (modelIndexes?.length > 0) {\n        const isDuplicateName = findDuplicate(modelIndexes.map((f) => f.name));\n        if (isDuplicateName) {\n          indexErrors = { name: 'Indexing error', message: `${isDuplicateName}: ${ERROR_MSG.indexName}`, isCustom: true };\n        }\n        if (!indexErrors) {\n          modelIndexes = modelIndexes.filter((x) => x.name).map((x) => {\n            if (dbType !== DB_TYPE.MONGODB) {\n              // sql indexing\n              if (!x.indexType) {\n                indexErrors = { name: 'Indexing error', message: `${x.name}: ${ERROR_MSG.indexType}`, isCustom: true };\n              }\n              if (x.indexType === SQL_INDEX.TYPE.GIN) {\n                x.operator = x.indexFields?.[0]?.operator;\n                x.indexFields = [];\n              }\n              if ([SQL_INDEX.TYPE.BTREE].includes(x?.indexType)) {\n                x.fields = [];\n              }\n            }\n\n            if (dbType !== DB_TYPE.MONGODB && (x.indexType === SQL_INDEX.TYPE.PARTIAL\n              || x.indexType === SQL_INDEX.TYPE.UNIQUE) && (!x.fields || x.fields?.length === 0)) {\n              // sql multiple attr validation\n              indexErrors = {\n                name: 'Indexing error',\n                message: `${x.name}: Please select attributes`,\n                isCustom: true,\n              };\n            }\n\n            if (x.indexFields?.length > 0 && !indexErrors) {\n              if (checkDuplicate(x.indexFields.map((f) => f.attribute))) {\n                indexErrors = { name: 'Indexing error', message: `${x.name}: ${ERROR_MSG.attribute}`, isCustom: true };\n              }\n              x.indexFields = x.indexFields.filter((f) => f.attribute);\n              if (dbType === DB_TYPE.MONGODB) {\n                // model indexing\n                if (x.indexFields.length === 0) indexErrors = { name: 'Indexing error', message: `${x.name}: ${ERROR_MSG.requiredSubIndex}`, isCustom: true };\n                if (x.ttl && !x.expireAfterSeconds) indexErrors = { name: 'Indexing error', message: `${x.name}: ${ERROR_MSG.ttl}`, isCustom: true };\n\n                const tempFields = {};\n                x.indexFields.forEach((f) => {\n                  if (!f.attribute || !f.type) {\n                    indexErrors = {\n                      name: 'Indexing error',\n                      message: `${x.name}: ${!f.attribute ? ERROR_MSG.requiredAttr : ERROR_MSG.requiredIndexType}`,\n                      isCustom: true,\n                    };\n                  }\n                  if (!indexErrors) { tempFields[f.attribute] = f.type; }\n                });\n                x.indexFields = tempFields;\n              } else {\n                // sql indexing validation\n                if (x.indexFields.length === 0) indexErrors = { name: 'Indexing error', message: `${x.name}: ${ERROR_MSG.requiredSqlSubIndex}`, isCustom: true };\n\n                if (!indexErrors) {\n                  x.indexFields.forEach((f) => {\n                    if (x.indexType === SQL_INDEX.TYPE.BTREE && (schema?.[f?.attribute]?.type === 'STRING') && (!f.attribute || !f.length)) { // check for length validation only if the attribute type is \"STRING\"\n                      indexErrors = {\n                        name: 'Indexing error',\n                        message: `${x.name}: Please input ${!f.attribute ? 'attribute' : 'length'}`,\n                        isCustom: true,\n                      };\n                    }\n                    if (x.indexType === SQL_INDEX.TYPE.PARTIAL && (!f.attribute || !f.operator || !f.value)) {\n                      indexErrors = {\n                        name: 'Indexing error',\n                        message: `${x.name}: Please input ${!f.attribute ? 'attribute' : !f.operator ? 'operator' : 'value'}`,\n                        isCustom: true,\n                      };\n                    }\n                  });\n                }\n              }\n            }\n\n            if (dbType === DB_TYPE.MONGODB) { x.options = { expireAfterSeconds: x.ttl ? x.expireAfterSeconds : undefined, unique: x.unique }; }\n\n            x = omit(x, ['isExpanded', 'ttl', 'expireAfterSeconds', 'unique']);\n            x = omitDeep(x, ['isExist']);\n            return x;\n          });\n        }\n      }\n\n      if (indexErrors) {\n        setJsonError(indexErrors);\n        // hideSaveLoader();\n        return;\n      }\n\n      let errorFlag = false;\n      const primaryKeys = [];\n      const allSchemaAttr = [];\n      const parentAttrs = []; // attribute name having sub-atrributes\n\n      if (schema && typeof schema === 'object') {\n        // check for duplicate schema attribute\n        const isDuplicateAttr = findDuplicate(Object.keys(schema).map((f) => f.toLowerCase()));\n        if (isDuplicateAttr) {\n          errorFlag = { name: 'Error', message: `${isDuplicateAttr}: ${ERROR_MSG.duplicateAttr}`, isCustom: true };\n        }\n        if (errorFlag) {\n          if (isInSaveWarning) hideSaveWarning();\n          setJsonError(errorFlag);\n          return;\n        }\n\n        Object.keys(schema)?.map((x) => {\n          if (!x) return x;\n          if (!schema[x]) return x;\n          let isSubAttr = false;\n          if (dbType === DB_TYPE.MONGODB && typeof schema[x] === 'object' && Array.isArray(schema[x])) {\n            // Add value false for \"_id\" {_id:false} => exclude _id if no sub-attr\n            // eslint-disable-next-line no-prototype-builtins\n            if (Object.keys(schema[x][0]).length === 1 && schema[x][0].hasOwnProperty('_id')) {\n              isSubAttr = false;\n              schema[x] = { type: TABLE_TYPES.ARRAY };\n            } else { isSubAttr = true; }\n          } else if (dbType === DB_TYPE.MONGODB && typeof schema[x] === 'object' && Object.keys(schema[x])?.length > 0) {\n          // type object\n            if (Object.values(schema[x]).some((v) => typeof v === 'object' && v)) {\n              // if any value has type object\n              isSubAttr = true;\n            } else {\n            // eslint-disable-next-line no-lonely-if\n              if (Object.keys(schema[x]).includes('type') && parsedKeys(schema[x], dbType)?.isSub) {\n                isSubAttr = true;\n              } else {\n                isSubAttr = false;\n              }\n            }\n          }\n\n          if (isSubAttr && dbType === DB_TYPE.MONGODB) {\n          // manage sub-rows\n            const tempSub = Array.isArray(schema[x]) ? schema[x][0] : schema[x];\n            // check for duplicate schema attribute\n            const isDuplicateSubAttr = findDuplicate(Object.keys(tempSub).map((f) => f.toLowerCase()));\n            if (isDuplicateSubAttr) {\n              errorFlag = { name: 'Error', message: `${isDuplicateSubAttr}: ${ERROR_MSG.duplicateAttr}`, isCustom: true };\n            }\n\n            Object.keys(tempSub).map((y) => {\n              if (tempSub[y]) {\n                if (typeof tempSub[y] === 'string') {\n                  const newAttr = {};\n                  newAttr.type = tempSub[y];\n                  tempSub[y] = newAttr;\n                }\n                if (tempSub[y].type) {\n                  tempSub[y].type = getParsedType(tempSub[y].type, dbType);\n                }\n                if (dbType === DB_TYPE.MONGODB && Array.isArray(schema[x]) && y === '_id') {\n                  // Add value false for \"_id\" {_id:false}\n                  tempSub[y] = tempSub[y].default || false;\n                } else { tempSub[y] = getParsedKeys(tempSub[y], dbType); }\n                if (tempSub[y]?.type === TABLE_TYPES.POINT) {\n                // type point then add index\n                  const isIndexExist = modelIndexes?.find((mi) => mi.indexFields?.[x] === '2dsphere');\n                  if (!isIndexExist) {\n                    modelIndexes.push({\n                      name: `${[x]}_default`,\n                      indexFields: { [x]: '2dsphere' },\n                      options: { unique: false },\n                    });\n                  }\n                }\n                allSchemaAttr.push(`${x}.${y}`);\n              }\n              if (tempSub[y]?.private === true) {\n                // prepare obj\n                customSetting = {\n                  ...customSetting,\n                  [x]: {\n                    ...customSetting[x],\n                    [y]: {\n                      ...customSetting[x][y],\n                      private: true,\n                    },\n                  },\n                };\n              }\n              delete tempSub[y].private; // remove private key from schema\n              return y;\n            });\n            schema[x] = Array.isArray(schema[x]) ? [tempSub] : tempSub;\n            parentAttrs.push(x);\n          } else {\n            if (typeof schema[x] === 'string') {\n              const newAttr = {};\n              newAttr.type = schema[x];\n              schema[x] = newAttr;\n            }\n            if (schema[x].type) {\n              schema[x].type = getParsedType(schema[x].type, dbType);\n            }\n            schema[x] = getParsedKeys(schema[x], dbType);\n            if (dbType !== DB_TYPE.MONGODB && schema[x][KEYS.primary]) {\n              primaryKeys.push(x); // store all selected primary keys\n            }\n            allSchemaAttr.push(x);\n            if (schema[x]?.private === true) {\n              // prepare obj\n              customSetting = {\n                ...customSetting,\n                [x]: {\n                  ...customSetting[x],\n                  private: true,\n                },\n              };\n            }\n            delete schema[x].private; // remove private key from schema\n          }\n          return x;\n        });\n      }\n      if (errorFlag) {\n        if (isInSaveWarning) hideSaveWarning();\n        setJsonError(errorFlag);\n        return;\n      }\n      // error handler, to read data we'll have to parse twice due to backslash escaping\n      errorFlag = isCustomErr(schema, null, null, { customSetting });\n      if (errorFlag) {\n        if (isInSaveWarning) hideSaveWarning();\n\n        setJsonError(errorFlag);\n        // setShowError();\n        // hideSaveLoader();\n        return;\n      }\n\n      if (customSetting && typeof customSetting === 'object' && Object.entries(customSetting)?.length > 0) {\n        customSetting = omitDeep(customSetting, ['isEnum', 'isMarkedAsPrivate']);\n        Object.keys(customSetting).forEach((x) => {\n          // filter empty object\n          if (isEmpty(customSetting[x])) delete customSetting[x];\n        });\n      }\n\n      // if (dbType !== DB_TYPE.MONGODB) {\n      //   // SQL: Primary composition for indexes\n      //   const isIndexExist = modelIndexes?.findIndex((mi) => mi.name === 'PRIMARY' && mi.isDefault);\n      //   let indexFields = [];\n      //   primaryKeys.map((x) => {\n      //     indexFields.push({\n      //       attribute: x,\n      //       collate: 'en_US',\n      //       order: 'ASC',\n      //       length: 1,\n      //     });\n      //     return x;\n      //   });\n      //   indexFields = uniqBy(indexFields, 'attribute');\n      //   const indexObj = {\n      //     isDefault: true,\n      //     name: 'PRIMARY',\n      //     indexType: SQL_INDEX.TYPE.BTREE,\n      //     indexFields,\n      //   };\n      //   if (isIndexExist < 0) {\n      //     // to add new entry of PRIMARY keys\n      //     if (indexFields?.length > 0) { modelIndexes.push(indexObj); }\n      //   } else if (indexFields?.length > 0) modelIndexes[isIndexExist] = indexObj; // update existing one\n      //   else modelIndexes.splice(isIndexExist, 1); // remove existing one\n      // }\n\n      if (modelIndexes?.length > 0) {\n        // filter by update and deleted model attr\n        modelIndexes.forEach((x) => {\n          if (dbType === DB_TYPE.MONGODB) {\n            Object.keys(x.indexFields).forEach((f) => {\n              // ignore error checking for attribute having sub-attribute\n              if (f && !allSchemaAttr.includes(f) && !parentAttrs.includes(f)) {\n                indexErrors = {\n                  name: 'Indexing error',\n                  message: `${x.name}: ${ERROR_MSG.requiredAttr}`,\n                  isCustom: true,\n                };\n              }\n            });\n          } else {\n            x.indexFields.forEach((f) => {\n              if (f.attribute && !allSchemaAttr.includes(f.attribute)) {\n                indexErrors = {\n                  name: 'Indexing error',\n                  message: `${x.name}: ${ERROR_MSG.requiredAttr}`,\n                  isCustom: true,\n                };\n              }\n            });\n          }\n        });\n      }\n\n      if (indexErrors) {\n        setJsonError(indexErrors);\n        return;\n      }\n\n      const customHook = [];\n      const hookError = false;\n      hooks.map((x) => {\n        // if (!x.code) hookError = { name: 'Error', message: `Hook ${x.hookType}: code is required`, isCustom: true };\n        if (!x.isErr && x.code) { customHook.push(omit(x, ['index', '_id', 'hookType', 'isErr'])); }\n        return x;\n      });\n      if (hookError) {\n        setJsonError(hookError);\n        // hideSaveLoader();\n        return;\n      }\n      // setSaveLoader();\n\n      let customJson;\n      if (currentModel.customJson) {\n        customJson = { ...currentModel.customJson };\n      }\n      customJson = {\n        additionalSetting: customSetting,\n        dependencySetting: dependency.filter((x) => x.newKey || x.isDelete),\n      };\n      if (jsonError) setJsonError(false);\n      if (showError) setHideError();\n\n      // loaderCallBack({ isHidePopup: false });\n      if (isInSaveWarning) { setSaveLoading(); } else {\n        loaderRef.current?.setLoader();\n      }\n\n      apiClient(`${API_URLS.schema.update}/${currentId}`, {\n        customJson,\n        schemaJson: schema,\n        name: currentModel.name,\n        tableName: pluralizeTableName(currentModel.name, currentApplicationCode),\n        description: currentModel.description,\n        hooks: customHook,\n        modelIndexes,\n        definitionType: currentApplicationCode,\n      }, 'PUT', null, null, {\n        isHandleCatch: true,\n      }).then((res) => {\n        if (res?.code === 'E_BAD_REQUEST') {\n          // manage multiple errors\n          if (isInSaveWarning) hideSaveLoading();\n          else loaderRef.current?.setLoader();\n\n          if (res.data?.length > 0) { setModelErrors(res.data); }\n          // hideSaveLoader();\n          addErrorToast(res.message);\n        } else if (res?.code === 'OK') {\n          if (modelErrors?.length > 0) setModelErrors?.(modelErrors.filter((x) => x?.modelName !== currentModel?.name));\n          dispatch(updateModel(res?.data));\n          if (showMsg) addSuccessToast(msg || res.message);\n          // hideSaveLoader();\n          // if (tableRef?.current && res?.message) addSuccessToast(res.message);\n          // setCode(JSON.stringify(res?.data?.schemaJson || {}));\n          setNoChangeInTable(); // when direct save that\n          if (isInSaveWarning) {\n            changeNextEvent.current();\n            hideSaveLoading();\n\n            hideSaveWarning();\n          } else {\n            loaderRef.current?.setLoader();\n          }\n\n          // loaderCallBack({ isHidePopup: true });\n          if (isRedirect) {\n            history.push(RedirectUrl[currentApplicationCode].model.nextUrl);\n          }\n        }\n      }).catch((err) => {\n        // hideSaveLoader();\n        addErrorToast(err);\n        if (isInSaveWarning) {\n          hideSaveLoading();\n          hideSaveWarning();\n        } else {\n          loaderRef.current?.setLoader();\n        }\n      });\n      updateRef.current?.setHideEdit();\n    } catch (err) {\n      setJsonError(err);\n      // hideSaveLoader();\n      // setShowError();\n    }\n  }, [currentModel, tabRef, modelErrors, jsonError, showError, dbType, handleShowError]);\n\n  const handleSave = React.useCallback(({ isRedirect = false }) => {\n    if ((isEmpty(modelList) || modelList.findIndex((m) => !isEmpty(m.schemaJson)) < 0) && (isEmpty(currentModel?.schemaJson) && isEmpty(JSON.parse(tabRef?.current?.code)))) {\n      addErrorToast(NoModelData);\n      return;\n    }\n    saveJSON({ showMsg: true, isRedirect });\n  }, [saveJSON]);\n  React.useImperativeHandle(saveRef, () => ({ handleSave }));\n\n  return (\n    <>\n      {\n        detailFetching ? <Loader />\n          : (\n            <>\n              <div className=\"headTop\">\n                <div className=\"flex items-start p-3 pb-0 pr-5 pb-2\">\n                  <ModelHeader\n                    currentId={currentId}\n                    currentModel={currentModel}\n                    // onUpdate={handleUpdate}\n                    updateRef={updateRef}\n                  />\n                  <div className=\"w-4/12 xxl:w-6/12 flex justify-end items-center\">\n                    <Button\n                      onClick={handleShowError}\n                      className=\"ml-2\"\n                      variant=\"secondary\"\n                      shape=\"rounded\"\n                      size=\"small\"\n                      isIcon\n                      label={`${modelErrCount + (jsonError ? 1 : 0) || 0} error`}\n                      icon={modelErrCount > 0 || !!jsonError ? <Icons.Alert color=\"#E24C4B\" /> : <Icons.Alert />}\n                    />\n                  </div>\n                </div>\n                {!!isError?.(currentModel?.name) || !!jsonError ? (\n                  <ErrorNotify />\n                ) : null}\n              </div>\n\n              <EditorProvider saveJSON={saveJSON}>\n                <IndexProvider>\n                  <EditorTabs\n                    ref={tabRef}\n                    jsonError={jsonError}\n                    setJsonError={setJsonError}\n                  />\n                </IndexProvider>\n              </EditorProvider>\n            </>\n          )\n      }\n\n      {\n        showError\n          ? (\n            <Error\n              isModelTab\n              isOpen={showError}\n              error={jsonError}\n              jsonErrCount={jsonError ? 1 : 0}\n              modelErrCount={modelErrCount}\n              modelErrors={modelErrors}\n              handleCancel={setHideError}\n            />\n          ) : null\n      }\n      <ConfirmationAlert\n        description=\" Do you wish to save your data before continuing ?\"\n        handleSubmit={() => saveJSON({ isInSaveWarning: true })}\n        variant=\"primary\"\n        title={(\n          <div className=\"flex justify-center items-center mb-5\">\n            <div className=\"w-5 h-5 mr-3\">\n              <Icons.Warring />\n            </div>\n            New changes detected\n          </div>\n)}\n        isOpen={isSaveWarning}\n        okText=\"Save\"\n        isLoading={isSaveLoading}\n        handleClose={() => { changeNextEvent.current(); hideSaveWarning(); setNoChangeInTable(); }}\n      />\n\n    </>\n  );\n});\nEditor.displayName = 'Editor';\nexport default Editor;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/HookSetup/HookEditor.js",
    "content": "import React, { useState } from 'react';\nimport { debounce } from 'lodash';\nimport { CodeEditor } from '../../../../components';\nimport { HOOK_TAB_TITLE } from '../../../../constant/model';\n\nexport const HookEditor = React.memo(({\n  currentHook, onChangeCode, currentModel, currentApplicationCode,\n}) => {\n  const [code, setCode] = useState(currentHook?.code);\n\n  React.useMemo(() => {\n    setCode(currentHook?.code);\n  }, [currentHook?._id]);\n\n  React.useMemo(() => {\n    const isExist = currentModel?.hooks?.find((hook) => (currentHook?._id === (`${hook.type}-${hook.operation}`)));\n    if (isExist) { setCode(isExist?.code); } else setCode('');\n  }, [currentModel?.hooks]);\n\n  const debounceSave = debounce(onChangeCode, 1000);\n\n  return (\n    <>\n      <CodeEditor\n        className=\"w-full h-full flex-grow\"\n        language=\"javascript\"\n        defaultValue=\"\"\n        value={code}\n        onChange={(tcode) => {\n          try {\n            setCode(tcode);\n            debounceSave(tcode);\n          } catch (err) {\n            if (err) {\n              // setHErr(true);\n            }\n          }\n        }}\n        onValidate={(errors) => {\n          if (errors?.length <= 0) {\n            if (currentHook?.code !== code || currentHook?.isErr) { debounceSave(code, false); }\n          } else {\n            debounceSave(code, {\n              name: `${HOOK_TAB_TITLE[currentApplicationCode]} error`, message: `${currentHook?.hookType}: parse error ${errors[0]?.message}`, isCustom: true, isHookErr: true,\n            });\n          }\n        }}\n      />\n    </>\n  );\n});\nHookEditor.displayName = 'HookEditor';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/HookSetup/HookList.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { Icons } from '@dhiwise/icons';\nimport { SidebarList } from '../../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../../../components';\nimport { HOOK_TAB_TITLE } from '../../../../constant/model';\n\nexport const HookList = React.memo(({\n  hooks, onAddHook, setCurrentHook, currentHook, currentApplicationCode,\n  // isHideAdd,\n}) => {\n  // const [hook, setHook] = React.useState();\n  const [hookId, setHookId] = React.useState();\n\n  React.useMemo(() => {\n    if (hooks?.length <= 0 || !hookId) return;\n    const h = hooks.find((x) => x._id === hookId);\n    setCurrentHook(h);\n  }, [hookId, hooks]);\n\n  return (\n    <>\n      <div className=\"w-56 h-full\">\n        <SidebarList\n          style={{ width: '100%' }}\n          sidebarClass=\"xl:h-full xxl:h-full\"\n          // isAddButton={!isHideAdd}\n          title={(HOOK_TAB_TITLE[currentApplicationCode]?.split(' ')?.[0]) ?? 'Hook'}\n          addClick={onAddHook}\n          tooltip=\"Add hook\"\n        >\n          <Menu iconShape=\"square\" className=\"px-2\">\n            <SidebarMenuList\n              mainMenuList={hooks || []}\n              titleKey=\"hookType\"\n              initialSelectedId={currentHook?._id}\n              // initialSelectedId={hooks?.[0]?._id}\n              onClick={setHookId}\n              Icon={<Icons.Check />}\n              IconError={<Icons.Check color=\"#FF340D\" />}\n              IconActive={<Icons.Check color=\"#fff\" />}\n              // onIconClick={setHook}\n            />\n          </Menu>\n        </SidebarList>\n      </div>\n      {/* {!!hook\n        && (\n          <ConfirmationAlert\n            isOpen={!!hook}\n            description=\"do you want to delete this hook?\"\n            handleSubmit={() => {\n              onDelete(hook);\n              setHook();\n            }}\n            handleClose={() => setHook()}\n          />\n        )} */}\n    </>\n  );\n});\nHookList.displayName = 'HookList';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/HookSetup/index.js",
    "content": "import React, { useState } from 'react';\nimport { cloneDeep } from 'lodash';\nimport { useSelector } from 'react-redux';\nimport { HookEditor } from './HookEditor';\nimport { HookList } from './HookList';\nimport { useEditor } from '../Editor/EditorProvider';\nimport { CodeEditor } from '../../../../components';\nimport { getHookFooter, getHookHeader } from '../../../../constant/model';\n\nexport const HookSetup = ({\n  onHookError,\n}) => {\n  const {\n    hooks, currentModel, setHooks, dbType,\n    // saveJSON,\n  } = useEditor();\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n\n  const [currentHook, setCurrentHook] = useState();\n  const typeRef = React.useRef(null);\n\n  React.useMemo(() => {\n    typeRef.current = hooks.map((x) => x.hookType);\n    if (!currentHook) { setCurrentHook(hooks[0]); }\n  }, [hooks]);\n\n  const handleChangeCode = React.useCallback((code, isErr) => {\n    const newData = cloneDeep(hooks);\n    const index = newData.findIndex((x) => x._id === currentHook?._id);\n    if (index > -1) {\n      newData[index].code = code;\n      newData[index].isErr = isErr;\n      setCurrentHook(newData[index]);\n    }\n    setHooks(newData);\n  }, [hooks, currentHook]);\n\n  const header = React.useMemo(() => {\n    if (!currentHook || !currentModel || !dbType || !currentApplicationCode) return '';\n    return getHookHeader({\n      dbType, modelName: currentModel.name, currentApplicationCode, ...currentHook,\n    });\n  }, [dbType, currentModel?.name, currentHook?.hookType]);\n\n  const footer = React.useMemo(() => getHookFooter({ dbType, currentApplicationCode }), [dbType]);\n\n  return (\n    <>\n      <div className=\"w-full flex h-full\">\n        <HookList\n          currentModel={currentModel}\n          hooks={hooks}\n          currentHook={currentHook}\n          setCurrentHook={setCurrentHook}\n          currentApplicationCode={currentApplicationCode}\n        />\n\n        <div style={{ width: 'calc(100% - 14rem)' }} className=\"xl:h-full xxl:h-full flex flex-col\">\n          <>\n            <CodeEditor\n              readOnly\n              language=\"javascript\"\n              height={100}\n              lineNumbers={false}\n              className=\"sm:h-auto flex-shrink-0 smallEditor\"\n              value={header}\n              isShowError={false}\n              loading={false}\n              scrollbar={{\n                vertical: 'hidden',\n                handleMouseWheel: false,\n              }}\n            />\n            <HookEditor currentModel={currentModel} onHookError={onHookError} onChangeCode={handleChangeCode} currentHook={currentHook} currentApplicationCode={currentApplicationCode} />\n            <CodeEditor\n              readOnly\n              language=\"javascript\"\n              height={100}\n              lineNumbers={false}\n              className=\"sm:h-auto flex-shrink-0 smallEditor\"\n              defaultValue={footer}\n              loading={false}\n              scrollbar={{\n                vertical: 'hidden',\n                handleMouseWheel: false,\n              }}\n            />\n          </>\n        </div>\n      </div>\n\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/Draggable/useDraggable.js",
    "content": "// import React from 'react';\nimport { useDrag } from 'react-dnd';\n\nconst DND_ITEM_TYPE = 'row';\nexport const useDraggable = ({ index, type }) => {\n  const [{ isDragging }, drag, preview] = useDrag({\n    item: { type: type || DND_ITEM_TYPE, index },\n    collect: (monitor) => ({\n      isDragging: monitor.isDragging(),\n    }),\n  });\n\n  return {\n    isDragging, preview, drag,\n  };\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/Draggable/useDroppable.js",
    "content": "import React from 'react';\nimport { useDrop } from 'react-dnd';\n\nconst DND_ITEM_TYPE = 'row';\nexport const useDroppable = ({ index, moveRow, type }) => {\n  const dropRef = React.useRef(null);\n\n  const [, drop] = useDrop({\n    accept: type || DND_ITEM_TYPE,\n    hover(item, monitor) {\n      if (!dropRef.current) {\n        return;\n      }\n      const dragIndex = item.index;\n      const hoverIndex = index;\n      if (dragIndex === hoverIndex) {\n        return;\n      }\n      const hoverBoundingRect = dropRef.current.getBoundingClientRect();\n      const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;\n      const clientOffset = monitor.getClientOffset();\n      const hoverClientY = clientOffset.y - hoverBoundingRect.top;\n      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {\n        return;\n      }\n      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {\n        return;\n      }\n      moveRow(dragIndex, hoverIndex);\n      // eslint-disable-next-line no-param-reassign\n      item.index = hoverIndex;\n    },\n  });\n\n  return { drop, dropRef };\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/ModelIndexProvider.js",
    "content": "import React from 'react';\nimport { cloneDeep } from 'lodash';\nimport { useSelector } from 'react-redux';\nimport { useBoolean } from '../../../../components/hooks';\n\nexport const ModelIndexContext = React.createContext();\n\nexport const MODEL_INDEX_ACTION_TYPES = {\n  FETCH_LIST: 'fetchModelIndexsList',\n  ADD: 'addModelIndex',\n  EDIT: 'editModelIndex',\n  REMOVE: 'removeModelIndex',\n  EDIT_DATA: 'editModelIndexData',\n  RESET_EDIT_DATA: 'resetEditModelIndexData',\n};\n\nfunction modelIndexReducer(state, { type, payload = {} }) {\n  switch (type) {\n    case MODEL_INDEX_ACTION_TYPES.FETCH_LIST: {\n      // to fetch model index list\n      return { ...state, modelIndexList: payload };\n    }\n    case MODEL_INDEX_ACTION_TYPES.ADD: {\n      // to add new model index\n      const { modelIndexList } = state;\n      modelIndexList.unshift({ ...payload });\n      return { ...state, modelIndexList };\n    }\n    case MODEL_INDEX_ACTION_TYPES.EDIT: {\n      // to edit model index data\n      const modelIndexList = state?.modelIndexList?.map((modelIndex) => {\n        if (modelIndex?.name === payload?.prevName) {\n          // eslint-disable-next-line no-param-reassign\n          delete payload?.prevName;\n          return payload;\n        }\n        return modelIndex;\n      });\n      return { ...state, modelIndexList };\n    }\n    case MODEL_INDEX_ACTION_TYPES.REMOVE: {\n      // to remove model index from list\n      return { ...state, modelIndexList: state?.modelIndexList?.filter((modelIndex) => modelIndex?.name !== payload?.name) };\n    }\n    case MODEL_INDEX_ACTION_TYPES.EDIT_DATA: {\n      // selected model index data\n      return { ...state, editModelIndexData: payload };\n    }\n    case MODEL_INDEX_ACTION_TYPES.RESET_EDIT_DATA: {\n      // to reset selected model index data\n      return { ...state, editModelIndexData: {} };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\n\nconst ModelIndexProvider = ({ children }) => {\n  const currentId = useSelector((state) => state.models.currentId);\n  const modelList = useSelector((state) => state.models.modelList) || [];\n  const currentModel = React.useMemo(() => modelList.find((model) => model._id === currentId), [currentId, modelList]);\n\n  const [stateData, dispatch] = React.useReducer(modelIndexReducer, { modelIndexList: [], editModelIndexData: {} });\n  const [modelIndexLoader, showModelIndexLoader, hideModelIndexLoader] = useBoolean(false);\n\n  React.useEffect(() => {\n    if (currentModel?.modelIndexes?.length > 0) {\n      let temp = [...currentModel.modelIndexes];\n      temp = temp.map((x, i) => ({ ...x, index: i, isExist: true }));\n      dispatch({ type: MODEL_INDEX_ACTION_TYPES.FETCH_LIST, payload: cloneDeep(temp) });\n    } else { dispatch({ type: MODEL_INDEX_ACTION_TYPES.FETCH_LIST, payload: [] }); }\n  }, [currentModel?.modelIndexes]);\n\n  const value = {\n    dispatch,\n    modelIndexLoader,\n    showModelIndexLoader,\n    hideModelIndexLoader,\n    modelIndexList: stateData.modelIndexList,\n    editModelIndexData: stateData.editModelIndexData,\n  };\n\n  return <ModelIndexContext.Provider value={value}>{children}</ModelIndexContext.Provider>;\n};\n\nfunction useModelIndex() {\n  const context = React.useContext(ModelIndexContext);\n  if (context === undefined) {\n    throw new Error('useModelIndex must be used within a ModelIndexProvider');\n  }\n  return context;\n}\n\nexport { ModelIndexProvider, useModelIndex };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/Mongodb/SubRow.js",
    "content": "/* eslint-disable no-unused-expressions */\n/* eslint-disable no-nested-ternary */\n/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { DndProvider } from 'react-dnd';\nimport HTML5Backend from 'react-dnd-html5-backend';\nimport { useTable } from 'react-table';\nimport '../../../../../assets/css/Table.css';\nimport { cloneDeep, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport ReactTooltip from 'react-tooltip';\nimport { DragHandle } from '../../Editor/TableView/TableData/Sortable';\nimport { EditableCell } from '../SQLIndexing/EditableCells';\nimport { DeleteIndex } from '../SQLIndexing/DeleteIndex';\nimport { useDraggable } from '../Draggable/useDraggable';\nimport { useDroppable } from '../Draggable/useDroppable';\nimport { MODEL_INDEX_ACTION_TYPES, useIndex } from '../SQLIndexing/IndexProvider';\nimport { MONGO_INDEX } from '../../../../../constant/modelIndexing';\n\nconst Row = React.memo(({\n  row, index, moveRow, mainRow,\n}) => {\n  const dragRef = React.useRef(null);\n\n  const { drag, isDragging, preview } = useDraggable({ index, type: 'sub-row' });\n  const { drop, dropRef } = useDroppable({ index, moveRow, type: 'sub-row' });\n\n  const opacity = isDragging ? 0.5 : 1;\n\n  preview(drop(dropRef));\n  drag(dragRef);\n\n  return (\n    <>\n      <tr {...row.getRowProps()} className=\"relative\" ref={dropRef} style={{ opacity }}>\n        <td>\n          <div className=\"flex justify-start\" ref={dragRef}>\n            <DragHandle style={{\n              left: '0', position: 'relative', margin: '0', top: '0',\n            }}\n            />\n            <DeleteIndex deleteObj={row} mainRow={mainRow} />\n          </div>\n        </td>\n        {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n      </tr>\n    </>\n  );\n});\nRow.displayName = 'Row';\nconst Table = React.memo(({\n  columns, data, onInputChange, moveRow, onAddRow, mainRow, maxAllowedSubRows,\n}) => {\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    visibleColumns,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn: {\n      Cell: EditableCell,\n    },\n    onInputChange,\n    moveRow,\n    onAddRow,\n    mainRow,\n  });\n  // Render the UI for your table\n  return (\n    <DndProvider backend={HTML5Backend}>\n      <table {...getTableProps()}>\n        <thead>\n          {headerGroups.map((headerGroup, i) => (\n            <tr {...headerGroup.getHeaderGroupProps()} className=\"relative\" key={`sub-header${i}`}>\n              <th> </th>\n              {headerGroup.headers.map((column, ci) => (\n                <th {...column.getHeaderProps()} key={`sub-col${i}${ci}`}>{column.render('Header')}</th>\n              ))}\n            </tr>\n          ))}\n        </thead>\n        <tbody {...getTableBodyProps()}>\n          {rows.map((row, index) => prepareRow(row) || (\n            <Row\n              key={`sub-row${index}`}\n              index={index}\n              row={row}\n              moveRow={moveRow}\n              visibleColumns={visibleColumns}\n              mainRow={mainRow}\n              rowProps={() => row.getRowProps()}\n              {...row.getRowProps()}\n            />\n          ))}\n        </tbody>\n        <td colSpan=\"5\">\n          <div\n            data-tip\n            data-for=\"info\"\n          >\n            <div\n              className={`ml-20 pb-2 text-sm text-gray-white flex underline items-center cursor-pointer labelGroup focus:outline-none focus:text-primary-dark ${(rows?.length >= maxAllowedSubRows) && 'cursor-not-allowed opacity-50'}`}\n            >\n              <div\n                className=\"w-4 h-4 mr-2\"\n                onClick={() => {\n                  rows?.length >= maxAllowedSubRows ? undefined : onAddRow();\n                }}\n              >\n                <Icons.Add />\n              </div>\n              <span onClick={() => {\n                rows?.length >= maxAllowedSubRows ? undefined : onAddRow();\n              }}\n              >\n                Add row\n              </span>\n            </div>\n            {(rows?.length >= maxAllowedSubRows)\n            && <ReactTooltip place=\"bottom\" id=\"info\" type=\"dark\">{`There can be no more than ${maxAllowedSubRows} fields in a compound index.`}</ReactTooltip>}\n          </div>\n        </td>\n      </table>\n    </DndProvider>\n  );\n});\nTable.displayName = 'Table';\nexport function SubRows({\n  //   row,data\n  row, rowProps,\n}) {\n  const {\n    modelIndexList, dispatch, handleAddRow, handleAutoFocus,\n  } = useIndex();\n\n  const columns = React.useMemo(() => ([\n    { key: 'attribute', Header: 'Attribute', accessor: 'attribute' },\n    { key: 'type', Header: 'Index type', accessor: 'type' },\n  ]), []);\n\n  const handleAddSubRow = () => {\n    dispatch({\n      type: MODEL_INDEX_ACTION_TYPES.ADD_SUB_ROW,\n      payload: { indexFields: row?.original?.indexFields, mainRow: row },\n    });\n    requestAnimationFrame(() => {\n    // auto focus on add new sub-row\n      handleAutoFocus({ mainRow: row, idPrefix: `srcell${row.index}`, focusField: 'attribute' });\n    });\n  };\n  const moveRow = (dragIndex, hoverIndex) => dispatch({\n    type: MODEL_INDEX_ACTION_TYPES.MOVE_SUB_ROW,\n    payload: { dragIndex, hoverIndex, mainRow: row },\n  });\n\n  const onInputChange = (rowIndex, columnId, value) => {\n    let newData = cloneDeep(modelIndexList);\n    let tempFields = [...newData[row.index]?.indexFields];\n    tempFields = tempFields.map((srow, index) => {\n      if (index === rowIndex) {\n        return {\n          ...tempFields[rowIndex],\n          [columnId]: value,\n        };\n      }\n      return srow;\n    });\n    newData[row.index].indexFields = tempFields;\n    if (columnId === 'attribute') {\n      if (last(newData[row.index].indexFields)?.[columnId] && !(newData[row?.index]?.indexFields?.length >= MONGO_INDEX.MAX_SUB_ROWS_ALLOWED)) {\n        newData = handleAddRow({ mainRow: row, indexList: newData });\n      }\n    }\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n  };\n  const subRows = row?.original?.indexFields || handleAddSubRow;\n\n  return (\n    <>\n      <tr {...rowProps}>\n        <td colSpan=\"4\" className=\"subRow text-left\">\n          <Table\n            columns={columns}\n            data={subRows}\n            onInputChange={onInputChange}\n            moveRow={moveRow}\n            onAddRow={handleAddSubRow}\n            mainRow={row}\n            maxAllowedSubRows={MONGO_INDEX.MAX_SUB_ROWS_ALLOWED}\n          />\n        </td>\n      </tr>\n    </>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/Mongodb/index.js",
    "content": "/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { DndProvider } from 'react-dnd';\nimport HTML5Backend from 'react-dnd-html5-backend';\nimport { useTable } from 'react-table';\nimport '../../../../../assets/css/Table.css';\nimport { cloneDeep, isEmpty, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { IconBox } from '../../../../../components';\nimport { DragHandle } from '../../Editor/TableView/TableData/Sortable';\nimport { EditableCell } from '../SQLIndexing/EditableCells';\nimport { useIndex, MODEL_INDEX_ACTION_TYPES } from '../SQLIndexing/IndexProvider';\nimport { SubRows } from './SubRow';\nimport { DeleteIndex } from '../SQLIndexing/DeleteIndex';\nimport { useDraggable } from '../Draggable/useDraggable';\nimport { useDroppable } from '../Draggable/useDroppable';\n\nconst defaultColumn = {\n  Cell: EditableCell,\n};\n\nconst Row = React.memo(({\n  row, index, moveRow, rowProps, visibleColumns, renderRowSubComponent, onExpand,\n}) => {\n  const dragRef = React.useRef(null);\n\n  const { drag, isDragging, preview } = useDraggable({ index });\n  const { drop, dropRef } = useDroppable({ index, moveRow });\n\n  const opacity = isDragging ? 0.5 : 1;\n\n  preview(drop(dropRef));\n  drag(dragRef);\n\n  return (\n    <>\n      <tr {...row.getRowProps()} className=\"relative\" ref={dropRef} style={{ opacity }}>\n        <td>\n          <div className=\"flex justify-start\" ref={dragRef}>\n            <DragHandle style={{\n              left: '0', position: 'relative', margin: '0', top: 'auto',\n            }}\n            />\n            {row?.original?.name !== 'PRIMARY' && !row?.original?.isDefault\n        && (<DeleteIndex deleteObj={row} />)}\n            <span {...row.getToggleRowExpandedProps?.()}>\n              <div className=\"w-3 h-3 ml-3 cursor-pointer\" onClick={() => onExpand(row)}>\n                {row?.original?.isExpanded ? <Icons.DownArrow /> : <Icons.RightArrow />}\n              </div>\n            </span>\n          </div>\n        </td>\n        {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n      </tr>\n      { row?.original?.isExpanded && renderRowSubComponent({ row, rowProps, visibleColumns })}\n    </>\n  );\n});\nRow.displayName = 'Row';\n\nconst Table = React.memo(({\n  // eslint-disable-next-line no-unused-vars\n  columns, data, renderRowSubComponent, onInputChange, moveRow, onAddRow, onExpand,\n}) => {\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    visibleColumns,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn,\n    onInputChange,\n    moveRow,\n    onAddRow,\n    onExpand,\n  });\n  // Render the UI for your table\n  return (\n    <DndProvider backend={HTML5Backend}>\n      <table {...getTableProps()}>\n        <thead>\n          {headerGroups.map((headerGroup, i) => (\n            <tr {...headerGroup.getHeaderGroupProps()} className=\"relative\" key={`header${i}`}>\n              <th key=\"col-icon\" className=\"z-100\">\n                <IconBox\n                  size=\"small\"\n                  tooltipPlace=\"right\"\n                  className=\"\"\n                  icon={<Icons.Plus color=\"#fff\" />}\n                  tooltip=\"Add indexing\"\n                  onClick={onAddRow}\n                />\n              </th>\n              {headerGroup.headers.map((column, ci) => (\n                <th {...column.getHeaderProps()} key={`col${i}${ci}`}>{column.render('Header')}</th>\n              ))}\n            </tr>\n          ))}\n        </thead>\n        <tbody {...getTableBodyProps()}>\n          {rows.map((row, index) => prepareRow(row) || (\n            <Row\n              key={`row${index}`}\n              index={index}\n              row={row}\n              moveRow={moveRow}\n              onExpand={onExpand}\n              renderRowSubComponent={renderRowSubComponent}\n              visibleColumns={visibleColumns}\n              rowProps={() => row.getRowProps()}\n              {...row.getRowProps()}\n            />\n          ))}\n        </tbody>\n      </table>\n    </DndProvider>\n  );\n});\nTable.displayName = 'Table';\nexport const MongoIndexing = React.memo(() => {\n  const {\n    modelIndexList, dispatch, handleAddRow, handleAutoFocus,\n  } = useIndex();\n\n  const columns = React.useMemo(() => [\n    {\n      key: 'name',\n      Header: 'Index name',\n      accessor: 'name',\n    },\n    {\n      key: 'ttlInput',\n      Header: 'Create TTL',\n      accessor: 'ttlInput',\n    },\n    {\n      key: 'unique',\n      Header: 'Unique index',\n      accessor: 'unique',\n    },\n  ], []);\n\n  // Create a function that will render our row sub components\n  const renderRowSubComponent = React.useCallback(\n    ({ row, rowProps, visibleColumns }) => (\n      <SubRows\n        row={row}\n        rowProps={rowProps}\n        visibleColumns={visibleColumns}\n      />\n    ),\n    [],\n  );\n  const onInputChange = (rowIndex, columnId, value) => {\n    let newData = cloneDeep(modelIndexList).map((row, index) => {\n      if (index === rowIndex) {\n        return {\n          ...modelIndexList[rowIndex],\n          [columnId]: value,\n        };\n      }\n      return row;\n    });\n    if (columnId === 'name') {\n      if (last(newData)?.[columnId]?.length > 0) { newData = handleAddRow({ indexList: newData, isPushSubRow: true }); }\n    }\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n  };\n\n  const moveRow = (dragIndex, hoverIndex) => dispatch({ type: MODEL_INDEX_ACTION_TYPES.MOVE_ROW, payload: { dragIndex, hoverIndex } });\n  const onAddRow = () => {\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.ADD_ROW });\n    requestAnimationFrame(() => {\n      // auto focus on add new row\n      handleAutoFocus({ idPrefix: 'rcell', focusField: 'name' });\n    });\n  };\n  const onExpand = (row) => dispatch({ type: MODEL_INDEX_ACTION_TYPES.EXPAND, payload: { row } });\n\n  return (\n    <>\n      <div className=\"dhiTable firstColTable text-left flex-grow h-full\">\n        {\n          !isEmpty(modelIndexList)\n            ? (\n              <Table\n                columns={columns}\n                data={modelIndexList}\n                renderRowSubComponent={renderRowSubComponent}\n                onInputChange={onInputChange}\n                moveRow={moveRow}\n                onAddRow={onAddRow}\n                onExpand={onExpand}\n              />\n            ) : null\n        }\n      </div>\n    </>\n  );\n});\nMongoIndexing.displayName = 'MongoIndexing';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/DeleteIndex.js",
    "content": "import React from 'react';\nimport { cloneDeep } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { ConfirmationAlert } from '../../../../../components';\nimport { useBoolean, useToastNotifications } from '../../../../hooks';\nimport { useEditor } from '../../Editor/EditorProvider';\nimport { useIndex, MODEL_INDEX_ACTION_TYPES } from './IndexProvider';\n\nconst DeleteIndex = React.memo(({ deleteObj, mainRow }) => {\n  const { modelIndexList, dispatch } = useIndex();\n  const { saveJSON } = useEditor();\n  const [isDelete, setIsDelete, hideIsDelete] = useBoolean(false);\n  const { addSuccessToast } = useToastNotifications();\n\n  const isDeleteDisable = modelIndexList?.length === 1 && !mainRow;\n\n  const handleDeleteRow = React.useCallback(() => {\n    // delete row by index\n    const newData = cloneDeep(modelIndexList);\n    newData.splice(deleteObj.index, 1);\n    if (deleteObj?.original?.isExist) saveJSON({ indexes: newData, msg: 'Index has been deleted successfully', showMsg: true });\n    else {\n      dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n      addSuccessToast('Index has been deleted successfully');\n    }\n  }, [modelIndexList, deleteObj, saveJSON]);\n\n  const handleDeleteSubRow = React.useCallback(() => {\n    // delete sub row by index\n    const newData = cloneDeep(modelIndexList);\n    const subFields = newData[mainRow.index]?.indexFields || [];\n    subFields.splice(deleteObj.index, 1);\n    newData[mainRow.index].indexFields = subFields;\n\n    if (deleteObj?.original?.isExist) saveJSON({ indexes: newData, msg: 'Index has been deleted successfully', showMsg: true });\n    else {\n      dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n      addSuccessToast('Index has been deleted successfully');\n    }\n  }, [modelIndexList, deleteObj, mainRow, saveJSON]);\n\n  const handleDeleteModal = React.useCallback(() => {\n    if (mainRow) handleDeleteSubRow();\n    else { handleDeleteRow(); }\n    hideIsDelete();\n  }, [mainRow, handleDeleteRow, handleDeleteSubRow]);\n\n  return (\n    <>\n      { isDelete\n        ? (\n          <ConfirmationAlert\n            description=\"Model index will be deleted permanently and cannot be restored in the future. Are you sure do you want to delete this index?\"\n            isOpen={isDelete}\n            handleSubmit={handleDeleteModal}\n            handleClose={hideIsDelete}\n          />\n        )\n        : null}\n\n      <div\n        className={`w-4 h-4 ml-2 cursor-pointer ${(isDeleteDisable) ? ' opacity-50 cursor-not-allowed' : ''}`}\n        onClick={() => {\n          // eslint-disable-next-line no-unused-expressions\n          isDeleteDisable ? undefined : setIsDelete();\n        }}\n      >\n        <Icons.Close />\n      </div>\n    </>\n  );\n});\nDeleteIndex.displayName = 'DeleteIndex';\nexport { DeleteIndex };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/EditableCells.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport { DB_CONST, DB_TYPE } from '../../../../../constant/model';\nimport { SQL_INDEX, getFieldPosition } from '../../../../../constant/modelIndexing';\nimport { useIndex } from './IndexProvider';\nimport {\n  MultiAttrCell, TypeCell, NameCell, SingleAttrCell, OrderTypeCell, LengthCell, CollateCell, AssignmentOperatorCell, OperatorCell, ValueCell, TTLCell, InputTTLCell, UniqueCell, MongoIndexTypeCell,\n} from './TableCells';\nimport { useEditor } from '../../Editor/EditorProvider';\n\nexport const EditableCell = React.memo(({\n  mainRow,\n  value: initialValue,\n  row: { index, original },\n  column: { id },\n  onInputChange, // This is a custom function that we supplied to our table instance\n}) => {\n  const { currentModel, currentApplicationCode } = useEditor();\n  // We need to keep and update the state of the cell normally\n  const [value, setValue] = React.useState(initialValue);\n  const { onKeyDownHandle } = useIndex();\n  const dbType = useSelector(((state) => DB_CONST[state.projects.applicationDatabase.databaseType]));\n\n  const onChange = (val, colName) => {\n    if (value === val) return;\n    setValue(val);\n    onInputChange(index, colName || id, val);\n  };\n\n  const handleNameChange = (val) => {\n    // name change\n    if (value === val) return;\n    setValue(val);\n  };\n\n  const onBlur = () => {\n    onInputChange(index, id, value);\n  };\n\n  // If the initialValue is changed external, sync it up with our state\n  React.useEffect(() => {\n    setValue(initialValue);\n  }, [initialValue]);\n\n  const fieldProps = {\n    value,\n    onChange,\n    disabled: dbType !== DB_TYPE.MONGODB && (mainRow ? mainRow.original?.name === 'PRIMARY' && mainRow.original?.isDefault\n      : original?.name === 'PRIMARY' && original?.isDefault),\n    isDisabled: dbType !== DB_TYPE.MONGODB && (mainRow ? mainRow.original?.name === 'PRIMARY' && mainRow.original?.isDefault\n      : original?.name === 'PRIMARY' && original?.isDefault),\n    onKeyDown: (e, fieldName) => onKeyDownHandle(e, fieldName, {\n      index,\n      idPrefix: mainRow ? `srcell${mainRow.index}` : 'rcell',\n      mainRow,\n    }),\n  };\n\n  const { FiledPosition } = React.useMemo(() => getFieldPosition(index, !!mainRow, dbType), [mainRow, index, dbType]);\n\n  switch (id) {\n    case 'name': return (\n      <NameCell\n        id={`rcell${FiledPosition.name}`}\n        disabled={fieldProps?.disabled}\n        value={value}\n        isMongoDb={dbType === DB_TYPE.MONGODB}\n        onChange={handleNameChange}\n        onBlur={onBlur}\n        onKeyDown={(e, fieldName) => onKeyDownHandle(e, fieldName, { index, idPrefix: 'rcell' })}\n      />\n    );\n    case 'indexType': return (\n      <TypeCell id={`rcell${FiledPosition.indexType}`} currentApplicationCode={currentApplicationCode} {...fieldProps} />\n    );\n    case 'fields': return (\n      <div className=\"min-w-40 w-full text-left\">\n        {[SQL_INDEX.TYPE.UNIQUE, SQL_INDEX.TYPE.PARTIAL, SQL_INDEX.TYPE.GIN].includes(original?.indexType)\n          ? <MultiAttrCell id={`rcell${FiledPosition.fields}`} {...fieldProps} />\n          : '-'}\n      </div>\n    );\n    case 'attribute': return (\n      <SingleAttrCell id={`srcell${mainRow.index}${FiledPosition.attribute}`} {...fieldProps} />\n    );\n    case 'order': return (\n      <OrderTypeCell id={`srcell${mainRow.index}${FiledPosition.order}`} {...fieldProps} />\n    );\n    case 'collate': return (\n      <CollateCell id={`srcell${mainRow.index}${FiledPosition.collate}`} {...fieldProps} />\n    );\n    case 'length': {\n      const attributeType = currentModel?.schemaJson?.[mainRow?.original?.indexFields?.[index]?.attribute]?.type;\n      return (\n        <LengthCell\n          id={`srcell${mainRow.index}${FiledPosition.length}`}\n          {...fieldProps}\n          disabled={(!attributeType || (attributeType !== 'STRING'))}\n        />\n      ); }\n    case 'value': {\n      return (\n        <ValueCell id={`srcell${mainRow.index}${FiledPosition.value}`} {...fieldProps} />\n      ); }\n    case 'operator': return (\n      mainRow?.original?.indexType === SQL_INDEX.TYPE.GIN ? <OperatorCell id={`srcell${mainRow.index}${FiledPosition.operator}`} {...fieldProps} />\n        : <AssignmentOperatorCell id={`srcell${mainRow.index}${FiledPosition.operator}`} {...fieldProps} />\n    );\n    case 'ttlInput': return (\n      <div className=\"w-full min-w-40  pr-6 flex items-center\">\n        <TTLCell\n          id={`rcell${FiledPosition.ttl}`}\n          {...fieldProps}\n          value={!!original?.ttl}\n        />\n        <InputTTLCell\n          id={`rcell${FiledPosition.expireAfterSeconds}`}\n          {...fieldProps}\n          value={original?.expireAfterSeconds}\n          disabled={!original?.ttl}\n        />\n      </div>\n    );\n    case 'unique': return (\n      <UniqueCell id={`rcell${FiledPosition.unique}`} {...fieldProps} />\n    );\n    case 'type': return (\n      <MongoIndexTypeCell id={`srcell${mainRow.index}${FiledPosition.type}`} {...fieldProps} />\n    );\n    default: return null;\n  }\n});\nEditableCell.displayName = 'EditableCell';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/IndexProvider.js",
    "content": "/* eslint-disable no-param-reassign */\nimport React from 'react';\nimport { cloneDeep } from 'lodash';\nimport update from 'immutability-helper';\nimport { useSelector } from 'react-redux';\nimport { useBoolean } from '../../../../../components/hooks';\nimport {\n  SQL_INDEX, getFieldPosition, getSubFieldPosition, MONGO_INDEX,\n} from '../../../../../constant/modelIndexing';\nimport { DB_CONST, DB_TYPE } from '../../../../../constant/model';\n\nexport const IndexContext = React.createContext();\n\nexport const MODEL_INDEX_ACTION_TYPES = {\n  FETCH_LIST: 'FETCH_LIST',\n  EDIT_DATA: 'EDIT_DATA',\n  SET_LIST: 'SET_LIST',\n  MOVE_ROW: 'MOVE_ROW',\n  MOVE_SUB_ROW: 'MOVE_SUB_ROW',\n  ADD_ROW: 'ADD_ROW',\n  ADD_SUB_ROW: 'ADD_SUB_ROW',\n  EXPAND: 'EXPAND',\n};\n\nfunction modelIndexReducer(state, { type, payload = {} }) {\n  switch (type) {\n    case MODEL_INDEX_ACTION_TYPES.FETCH_LIST: {\n      // to fetch model index list\n      return { ...state, modelIndexList: payload };\n    }\n    case MODEL_INDEX_ACTION_TYPES.SET_LIST: {\n      // to fetch model index list\n      // eslint-disable-next-line no-param-reassign\n      // state.modelIndexList = payload;\n      // return state;\n      return { ...state, modelIndexList: payload };\n    }\n    case MODEL_INDEX_ACTION_TYPES.EDIT_DATA: {\n      // to edit model index data\n      const modelIndexList = state?.modelIndexList?.map((modelIndex) => {\n        if (modelIndex?.name === payload?.prevName) {\n          // eslint-disable-next-line no-param-reassign\n          delete payload?.prevName;\n          return payload;\n        }\n        return modelIndex;\n      });\n      return { ...state, modelIndexList };\n    }\n    case MODEL_INDEX_ACTION_TYPES.MOVE_ROW: {\n      // to fetch model index list\n      const { dragIndex, hoverIndex } = payload;\n      const dragRecord = state.modelIndexList[dragIndex];\n      const recs = update(state.modelIndexList, {\n        $splice: [\n          [dragIndex, 1],\n          [hoverIndex, 0, dragRecord],\n        ],\n      });\n      return { ...state, modelIndexList: recs };\n    }\n    case MODEL_INDEX_ACTION_TYPES.MOVE_SUB_ROW: {\n      // to fetch model index list\n      const { dragIndex, hoverIndex, mainRow } = payload;\n      const newData = cloneDeep(state.modelIndexList);\n      const newFields = newData[mainRow.index]?.indexFields;\n      const dragRecord = newFields?.[dragIndex];\n      newData[mainRow.index].indexFields = update(newFields, {\n        $splice: [\n          [dragIndex, 1],\n          [hoverIndex, 0, dragRecord],\n        ],\n      });\n      return { ...state, modelIndexList: newData };\n    }\n    case MODEL_INDEX_ACTION_TYPES.ADD_ROW: {\n      // add new row\n      return { ...state, modelIndexList: state?.onAddRow({ indexList: state.modelIndexList }) };\n    }\n    case MODEL_INDEX_ACTION_TYPES.ADD_SUB_ROW: {\n      // add new row\n      return { ...state, modelIndexList: state?.onAddRow({ indexList: state.modelIndexList, mainRow: payload?.mainRow }) };\n    }\n    case MODEL_INDEX_ACTION_TYPES.EXPAND: {\n      // add new row\n      const newData = cloneDeep(state.modelIndexList);\n      newData[payload.row.index].isExpanded = !payload.row.original.isExpanded;\n      return { ...state, modelIndexList: newData };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\nconst DEFAULT = {\n  SUB_OBJ: {\n    attribute: '',\n    // collate: '', commented as discussed with Avina\n    order: '',\n    length: undefined,\n    operator: '',\n    value: '',\n  },\n  ROW_OBJ: {\n    isExpanded: false,\n    name: '',\n    indexType: '',\n    fields: [],\n    // operator: '', this will be managed in sub-row\n    indexFields: [],\n  },\n  MONGO_ROW_OBJ: {\n    isExpanded: false,\n    name: '',\n    ttl: '',\n    expireAfterSeconds: '',\n    indexFields: [],\n  },\n  MONGO_SUB_OBJ: {\n    attribute: '',\n    indexType: '',\n  },\n};\nconst IndexProvider = ({ children }) => {\n  const currentId = useSelector((state) => state.models.currentId);\n  const modelList = useSelector((state) => state.models.modelList) || [];\n  const currentModel = React.useMemo(() => modelList.find((model) => model._id === currentId), [currentId, modelList]);\n  const dbType = useSelector((state) => DB_CONST[state.projects.applicationDatabase.databaseType]);\n\n  const handleAddRow = ({ indexList, mainRow }) => {\n    // indexList: indexFields, indexFields:subrow, mainRow: main table row\n    const newData = cloneDeep(indexList) || [];\n    if (mainRow) {\n      // sub-row\n      if (dbType === DB_TYPE.MONGODB) {\n        // mongo\n        newData[mainRow.index]?.indexFields?.push(DEFAULT.MONGO_SUB_OBJ);\n      } else if (mainRow?.indexType === SQL_INDEX.TYPE.BTREE || mainRow?.indexType === SQL_INDEX.TYPE.PARTIAL\n        || mainRow?.original?.indexType === SQL_INDEX.TYPE.BTREE || mainRow?.original?.indexType === SQL_INDEX.TYPE.PARTIAL) {\n        // sql\n        newData[mainRow.index]?.indexFields?.push(DEFAULT.SUB_OBJ);\n      }\n    } else {\n      const obj = cloneDeep(DEFAULT.MONGO_ROW_OBJ);\n      if (obj.indexFields?.length <= 0) {\n        obj.indexFields.push(DEFAULT.MONGO_SUB_OBJ);\n      }\n      newData.push(dbType === DB_TYPE.MONGODB ? obj : DEFAULT.ROW_OBJ);\n    }\n    return newData;\n  };\n\n  const [stateData, dispatch] = React.useReducer(modelIndexReducer, {\n    modelIndexList: [],\n    onAddRow: handleAddRow,\n  });\n  const [modelIndexLoader, showModelIndexLoader, hideModelIndexLoader] = useBoolean(false);\n\n  const prepareData = () => {\n    if (currentModel?.modelIndexes?.length > 0) {\n      let temp = cloneDeep(currentModel.modelIndexes);\n\n      if (dbType === DB_TYPE.MONGODB) {\n        // mongodb\n        temp = temp.map((x) => {\n          const tempFields = [];\n          const obj = {\n            ...x,\n            ...x.options,\n            ttl: !!x.options?.expireAfterSeconds,\n            isExist: true,\n            isExpanded: false,\n          };\n          delete obj.options;\n          if (x?.indexFields && Object.entries(x.indexFields)?.length > 0) {\n            Object.keys(x.indexFields).forEach((f) => {\n              tempFields.push({\n                attribute: f,\n                type: x.indexFields[f],\n                isExist: true,\n              });\n            });\n          }\n          obj.indexFields = (tempFields?.length >= MONGO_INDEX.MAX_SUB_ROWS_ALLOWED) ? tempFields : tempFields.concat([DEFAULT.MONGO_SUB_OBJ]);\n          return obj;\n        });\n      } else {\n        // sql\n        temp = temp.map((x) => {\n          if (x.isParserRequired && x?.name === 'PRIMARY') {\n          // old data script\n            const newIndexFields = [];\n            if (x.indexFields && Object.entries?.(x.indexFields)?.length > 0) {\n              Object.keys(x.indexFields).forEach((y) => {\n                newIndexFields.push({\n                  attribute: y,\n                  collate: 'en_US',\n                  length: 1,\n                  order: 'ASC',\n                });\n              });\n            }\n            return {\n              ...x,\n              isDefault: true,\n              indexType: SQL_INDEX.TYPE.BTREE,\n              indexFields: newIndexFields,\n              isExist: true,\n              isExpanded: false,\n            };\n          }\n          if (x?.indexFields?.length > 0) {\n            if (x.indexType === SQL_INDEX.TYPE.BTREE || x.indexType === SQL_INDEX.TYPE.PARTIAL) {\n              x.indexFields = x.indexFields.map((y) => ({ ...y, isExist: true }));\n              x.indexFields = x.indexFields.concat([DEFAULT.SUB_OBJ]);\n            }\n          } else if (x.indexType === SQL_INDEX.TYPE.GIN) {\n            x.indexFields = [{ operator: x.operator, isExist: true }];\n          } else if (x.indexType && x.indexType !== SQL_INDEX.TYPE.UNIQUE) x.indexFields = [DEFAULT.SUB_OBJ];\n          return { ...x, isExist: true, isExpanded: false };\n        });\n      }\n\n      temp = temp.concat(handleAddRow({}));\n      dispatch({ type: MODEL_INDEX_ACTION_TYPES.FETCH_LIST, payload: cloneDeep(temp) });\n    } else { dispatch({ type: MODEL_INDEX_ACTION_TYPES.FETCH_LIST, payload: handleAddRow({}) }); }\n  };\n\n  React.useMemo(() => {\n    if (dbType && currentModel?.modelIndexes) { prepareData(); }\n  }, [currentModel?.modelIndexes, dbType]);\n\n  // common function for both indexing\n  const handleRowToSubFocus = ({\n    focusField, prevRow, prevIndex, downIndex, downRow, mainRow, index, ...opt\n  }) => {\n    // handle row to subrow focus\n    if (opt?.isDown) {\n      const subField = getSubFieldPosition(0, dbType); // 1st sub row\n      const focusIndex = subField.FiledPosition[focusField];\n      for (let nextIndex = 0; nextIndex <= downRow.indexFields?.length; nextIndex += 1) {\n        const field = document.querySelector(`#srcell${downIndex}${focusIndex - nextIndex} ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n    } else if (opt?.isUp) {\n      const subField = getSubFieldPosition(prevRow?.indexFields?.length - 1, dbType);// last sub row\n      const focusIndex = subField.FiledPosition[focusField];\n      const field = document.querySelector(`#srcell${prevIndex}${focusIndex} ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`);\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n    } else if (opt?.isPrev) {\n      const { FiledPosition } = getSubFieldPosition(downRow?.indexFields?.length - 1, dbType);// last sub row\n      const field = document.querySelector(`#srcell${downIndex}${FiledPosition[focusField]}`);\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n    } else if (opt?.isNext) {\n      // next row=>sub\n      const field = document.querySelector(`#srcell${index}${SQL_INDEX.SUB_FIELD_SEQ.attribute} [tabindex=\"0\"]`);\n      field?.focus();\n    }\n  };\n\n  // common function for both indexing\n  const handleSubToRowFocus = ({\n    focusField, prevRow, prevIndex, downIndex, downRow, index, mainRow, ...opt\n  }) => {\n    // handle subrow to row focus\n    if (opt?.isPrev) {\n      const { FiledPosition } = getFieldPosition(mainRow?.index, null, dbType);// last sub row\n      const field = document.querySelector(`#rcell${FiledPosition[focusField]} ${focusField === 'fields' ? '[tabindex=\"0\"]' : ''}`);\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n    } else if (opt?.isNext) {\n      // next sub=>row\n      const { FiledPosition } = getFieldPosition(mainRow.index + 1, null, dbType);// next row\n      const field = document.querySelector(`#rcell${FiledPosition.name}`);\n      field?.focus();\n    } else if (opt?.isDown) {\n      // next sub=>row\n      const { FiledPosition } = getFieldPosition(mainRow.index + 1, null, dbType);// next row\n      const field = document.querySelector(`#rcell${FiledPosition[focusField]} ${focusField === 'fields' ? '[tabindex=\"0\"]' : ''}`);\n      field?.focus();\n    } else if (opt?.isUp) {\n      // next sub=>row\n      const { FiledPosition } = getFieldPosition(mainRow.index, null, dbType);// same row\n      const field = document.querySelector(`#rcell${FiledPosition[focusField]} ${focusField === 'fields' ? '[tabindex=\"0\"]' : ''}`);\n      field?.focus();\n    }\n  };\n\n  const handleMongoKeyDown = (e, focusField, {\n    index, idPrefix, mainRow, lengthOfData, dataArray, FiledPosition, focusIndex,\n  }) => {\n    // handle keyboard shortcuts for mongo indexing\n    switch (e.keyCode) {\n      case 38:\n      { // up\n        let isFocused = false;\n        if (dataArray[index - 1]?.isExpanded) {\n        // row => subrow\n          for (let nextIndex = index - 1; nextIndex >= 0; nextIndex -= 1) {\n            if (dataArray[nextIndex]?.isExpanded) {\n            // row => subrow\n              isFocused = true;\n              handleRowToSubFocus({\n                isUp: true, focusField: 'attribute', prevRow: dataArray[nextIndex], prevIndex: nextIndex, mainRow,\n              });\n              break;\n            }\n          }\n        }\n        if (!isFocused) {\n          for (let nextIndex = MONGO_INDEX.TOTAL_FIELDS; nextIndex < lengthOfData * MONGO_INDEX.TOTAL_FIELDS; nextIndex += MONGO_INDEX.TOTAL_FIELDS) {\n            let isTabIndex = false;\n            if ([FiledPosition.attribute].includes(focusIndex - nextIndex)) isTabIndex = true;\n            let query = `#${idPrefix}${focusIndex - nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n            if (mainRow) { query = `#${idPrefix}${focusIndex - MONGO_INDEX.SUB_TOTAL_FIELDS}  ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`; }\n            const field = document.querySelector(query);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              break;\n            } else if (mainRow?.original?.indexFields?.length - 1 === mainRow?.index && mainRow?.original?.isExpanded) {\n            // sub=>row\n              handleSubToRowFocus({ isUp: true, mainRow, focusField: 'name' });\n            }\n          }\n        }\n        break; }\n      case 40:\n      { // down\n        let isFocused = false;\n        if (dataArray[index]?.isExpanded) {\n        // row => subrow\n          const nextIndex = index;\n          if (dataArray[nextIndex]?.isExpanded) {\n            isFocused = true;\n            handleRowToSubFocus({\n              isDown: true, focusField: 'attribute', downIndex: nextIndex, downRow: dataArray[nextIndex], mainRow,\n            });\n            break;\n          }\n        // }\n        }\n        if (!isFocused) {\n          for (let nextIndex = MONGO_INDEX.TOTAL_FIELDS; nextIndex < lengthOfData * MONGO_INDEX.TOTAL_FIELDS; nextIndex += MONGO_INDEX.TOTAL_FIELDS) {\n            let query = `#${idPrefix}${focusIndex + nextIndex} ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`;\n            if (mainRow) { query = `#${idPrefix}${FiledPosition[focusField] + MONGO_INDEX.SUB_TOTAL_FIELDS} ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`; }\n            const field = document.querySelector(query);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              isFocused = true;\n              field?.focus();\n              break;\n            } else if (mainRow?.original?.indexFields?.length - 1 === index) {\n            // sub=>row\n              handleSubToRowFocus({ isDown: true, mainRow, focusField: 'name' });\n            }\n            if (isFocused) break;\n          }\n        }\n        break; }\n      case 37:\n      { // left\n        if (e.ctrlKey) {\n          let isFocused = false;\n          if (!mainRow && dataArray[index - 1]?.isExpanded && focusField === 'name') {\n          // row => subrow\n            isFocused = true;\n            handleRowToSubFocus({\n              isPrev: true, focusField: 'type', downIndex: index - 1, downRow: dataArray[index - 1], mainRow,\n            });\n            break;\n          } else {\n            for (let nextIndex = 1; nextIndex !== lengthOfData * MONGO_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n              const field = document.querySelector(`#${idPrefix}${focusIndex - nextIndex}  ${focusField === 'type' ? '[tabindex=\"0\"]' : ''}`);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                isFocused = true;\n                break;\n              } else if (!isFocused && mainRow && index === 0 && focusField === 'attribute') {\n              // sub=>row\n                handleSubToRowFocus({ isPrev: true, mainRow, focusField: 'unique' });\n              }\n            }\n          }\n        }\n        break; }\n      case 39:\n      {\n        // right\n        if (e.ctrlKey) {\n          if (dataArray[index].isExpanded && focusField === 'unique') {\n          // row => subrow\n            handleRowToSubFocus({ isNext: true, index });\n          } else {\n            for (let nextIndex = 1; nextIndex !== lengthOfData * MONGO_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n              let isTabIndex = false;\n              // (sub) => sub;\n              if (MONGO_INDEX.SUB_TOTAL_FIELDS * FiledPosition.attribute === focusIndex) isTabIndex = true;\n              const query = `#${idPrefix}${focusIndex + nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n              const field = document.querySelector(query);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                break;\n              } else if ((focusField === 'type') && mainRow?.original?.indexFields?.length - 1 === index) {\n              // sub=>row\n                handleSubToRowFocus({ isNext: true, mainRow });\n              }\n            }\n          }\n        }\n        break; }\n      case 13:\n      {\n        // enter => same as next\n        if (dataArray[index].isExpanded && focusField === 'unique') {\n          // row => subrow\n          handleRowToSubFocus({ isNext: true, index });\n        } else {\n          for (let nextIndex = 1; nextIndex !== lengthOfData * MONGO_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n            let isTabIndex = false;\n            // (sub) => sub;\n            if (MONGO_INDEX.SUB_TOTAL_FIELDS * FiledPosition.attribute === focusIndex) isTabIndex = true;\n            const query = `#${idPrefix}${focusIndex + nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n            const field = document.querySelector(query);\n            if (field && !field?.hasAttribute?.('disabled')) {\n              field?.focus();\n              break;\n            } else if ((focusField === 'type') && mainRow?.original?.indexFields?.length - 1 === index) {\n              // sub=>row\n              handleSubToRowFocus({ isNext: true, mainRow });\n            }\n          }\n        }\n        break; }\n\n      default:\n        break;\n    }\n  };\n\n  const onKeyDownHandle = (e, focusField, { index, idPrefix, mainRow }) => {\n    const { FiledPosition } = getFieldPosition(index, !!mainRow, dbType);\n    const dataArray = mainRow?.original?.indexFields?.length > 0 ? mainRow.original.indexFields : stateData.modelIndexList;\n    const lengthOfData = dataArray.length;\n    const focusIndex = FiledPosition[focusField];\n    if (dbType === DB_TYPE.MONGODB) {\n      // manage keydown handle for mongo db\n      handleMongoKeyDown(e, focusField, {\n        index, idPrefix, mainRow, lengthOfData, dataArray, FiledPosition, focusIndex,\n      });\n    } else {\n      switch (e.keyCode) {\n        case 38:\n        { // up\n          let isFocused = false;\n          if (dataArray[index - 1]?.isExpanded) {\n          // row => subrow\n            for (let nextIndex = index - 1; nextIndex >= 0; nextIndex -= 1) {\n              if (dataArray[nextIndex]?.isExpanded) {\n              // row => subrow\n                isFocused = true;\n                let tempFocusField = '';\n                if (focusField === 'name') tempFocusField = 'attribute';\n                else if (focusField === 'indexType') tempFocusField = SQL_INDEX.TYPE.BTREE === dataArray[nextIndex].indexType ? 'order' : 'operator';\n                else if (focusField === 'name') tempFocusField = SQL_INDEX.TYPE.BTREE === dataArray[nextIndex].indexType ? 'length' : 'value';\n                handleRowToSubFocus({\n                  isUp: true, focusField: tempFocusField, prevRow: dataArray[nextIndex], prevIndex: nextIndex, mainRow,\n                });\n                break;\n              }\n            }\n          }\n          if (!isFocused) {\n            for (let nextIndex = SQL_INDEX.TOTAL_FIELDS; nextIndex < lengthOfData * SQL_INDEX.TOTAL_FIELDS; nextIndex += SQL_INDEX.TOTAL_FIELDS) {\n              let isTabIndex = focusField === 'fields' || false;\n              if ([FiledPosition.fields, FiledPosition.attribute].includes(focusIndex - nextIndex)) isTabIndex = true;\n              let query = `#${idPrefix}${focusIndex - nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n              if (mainRow) { query = `#${idPrefix}${focusIndex - SQL_INDEX.SUB_TOTAL_FIELDS}  ${focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`; }\n              const field = document.querySelector(query);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                break;\n              } else if (mainRow?.original?.indexFields?.length - 1 === mainRow?.index && mainRow?.original?.isExpanded) {\n              // sub=>row\n                let tempFocusField = '';\n                if (focusField === 'attribute') tempFocusField = 'name';\n                else if (focusField === 'order' || focusField === 'operator') tempFocusField = 'indexType';\n                else if (focusField === 'length' || focusField === 'value') tempFocusField = 'fields';\n                handleSubToRowFocus({ isUp: true, mainRow, focusField: tempFocusField });\n              }\n            }\n          }\n          break; }\n        case 40:\n        { // down\n          let isFocused = false;\n          if (dataArray[index]?.isExpanded) {\n          // row => subrow\n            const nextIndex = index;\n            // for (let nextIndex = index; nextIndex <= lengthOfData; nextIndex += 1) {\n            if (dataArray[nextIndex]?.isExpanded) {\n              isFocused = true;\n              let tempFocusField = '';\n              if (focusField === 'name') tempFocusField = 'attribute';\n              else if (focusField === 'indexType') tempFocusField = SQL_INDEX.TYPE.BTREE === dataArray[nextIndex].indexType ? 'order' : 'operator';\n              else if (focusField === 'fields') tempFocusField = SQL_INDEX.TYPE.BTREE === dataArray[nextIndex].indexType ? 'length' : 'value';\n              handleRowToSubFocus({\n                isDown: true, focusField: tempFocusField, downIndex: nextIndex, downRow: dataArray[nextIndex], mainRow,\n              });\n              break;\n            }\n          // }\n          }\n          if (!isFocused) {\n            for (let nextIndex = SQL_INDEX.TOTAL_FIELDS; nextIndex < lengthOfData * SQL_INDEX.TOTAL_FIELDS; nextIndex += SQL_INDEX.TOTAL_FIELDS) {\n              let isTabIndex = false;\n              if ([FiledPosition.fields, FiledPosition.attribute].includes(focusIndex + nextIndex)) isTabIndex = true;\n              let query = `#${idPrefix}${focusIndex + nextIndex} ${isTabIndex || focusField === 'fields' ? '[tabindex=\"0\"]' : ''}`;\n              if (mainRow) { query = `#${idPrefix}${FiledPosition[focusField] + SQL_INDEX.SUB_TOTAL_FIELDS} ${isTabIndex || focusField === 'attribute' ? '[tabindex=\"0\"]' : ''}`; }\n              const field = document.querySelector(query);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                isFocused = true;\n                field?.focus();\n                break;\n              } else if (mainRow?.original?.indexFields?.length - 1 === index) {\n              // sub=>row\n                let tempFocusField = '';\n                if (focusField === 'attribute') tempFocusField = 'name';\n                else if (focusField === 'order' || focusField === 'operator') tempFocusField = 'indexType';\n                else if (focusField === 'length' || focusField === 'value') tempFocusField = 'fields';\n                handleSubToRowFocus({ isDown: true, mainRow, focusField: tempFocusField });\n              }\n              if (isFocused) break;\n            }\n          }\n          break; }\n        case 37:\n        { // left\n          if (e.ctrlKey) {\n            let isFocused = false;\n            if (!mainRow && dataArray[index - 1]?.isExpanded && focusField === 'name') {\n            // row => subrow\n              isFocused = true;\n              const tempFocusField = dataArray[index - 1].indexType === SQL_INDEX.TYPE.BTREE ? 'length' : 'value';\n              handleRowToSubFocus({\n                isPrev: true, focusField: tempFocusField, downIndex: index - 1, downRow: dataArray[index - 1], mainRow,\n              });\n              break;\n            } else {\n              for (let nextIndex = 1; nextIndex !== lengthOfData * SQL_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n                let isTabIndex = false;\n                if (([SQL_INDEX.TYPE.BTREE, SQL_INDEX.TYPE.PARTIAL].includes(dataArray[index].indexType)\n              || [SQL_INDEX.TYPE.BTREE, SQL_INDEX.TYPE.PARTIAL].includes(mainRow?.original?.indexType))\n              && (focusField === 'operator' || focusField === 'order' || focusField === 'name')) isTabIndex = true;\n                const field = document.querySelector(`#${idPrefix}${focusIndex - nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`);\n                if (field && !field?.hasAttribute?.('disabled')) {\n                  field?.focus();\n                  isFocused = true;\n                  break;\n                } else if (!isFocused && mainRow && index === 0 && focusField === 'attribute') {\n                // sub=>row\n                  const tempFocusField = mainRow?.original?.indexType === SQL_INDEX.TYPE.BTREE ? 'indexType' : 'fields';\n                  handleSubToRowFocus({ isPrev: true, mainRow, focusField: tempFocusField });\n                }\n              }\n            }\n          }\n          break; }\n        case 39:\n        {\n        // right\n          if (e.ctrlKey) {\n            if (dataArray[index].isExpanded && (\n              (focusField === 'indexType' && dataArray[index].indexType === SQL_INDEX.TYPE.BTREE)\n          || (focusField === 'fields'\n           && [SQL_INDEX.TYPE.UNIQUE, SQL_INDEX.TYPE.PARTIAL, SQL_INDEX.TYPE.GIN].includes(dataArray[index].indexType)))\n            ) {\n            // row => subrow\n              handleRowToSubFocus({ isNext: true, index });\n            } else {\n              for (let nextIndex = 1; nextIndex !== lengthOfData * SQL_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n                let isTabIndex = false;\n                if ([FiledPosition.fields, FiledPosition.attribute].includes(focusIndex + nextIndex)) isTabIndex = true;\n                // (sub) => sub;\n                if (SQL_INDEX.SUB_TOTAL_FIELDS * FiledPosition.attribute === focusIndex) isTabIndex = true;\n                const query = `#${idPrefix}${focusIndex + nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n                const field = document.querySelector(query);\n                if (field && !field?.hasAttribute?.('disabled')) {\n                  field?.focus();\n                  break;\n                } else if ((focusField === 'value' || focusField === 'length') && mainRow?.original?.indexFields?.length - 1 === index) {\n                // sub=>row\n                  handleSubToRowFocus({ isNext: true, mainRow });\n                }\n              }\n            }\n          }\n          break; }\n        case 13:\n        {\n        // enter same as Next\n          if (dataArray[index].isExpanded && (\n            (focusField === 'indexType' && dataArray[index].indexType === SQL_INDEX.TYPE.BTREE)\n        || (focusField === 'fields'\n         && [SQL_INDEX.TYPE.UNIQUE, SQL_INDEX.TYPE.PARTIAL, SQL_INDEX.TYPE.GIN].includes(dataArray[index].indexType)))\n          ) {\n          // row => subrow\n            handleRowToSubFocus({ isNext: true, index });\n          } else {\n            for (let nextIndex = 1; nextIndex !== lengthOfData * SQL_INDEX.TOTAL_FIELDS; nextIndex += 1) {\n              let isTabIndex = false;\n              if ([FiledPosition.fields, FiledPosition.attribute].includes(focusIndex + nextIndex)) isTabIndex = true;\n              // (sub) => sub;\n              if (SQL_INDEX.SUB_TOTAL_FIELDS * FiledPosition.attribute === focusIndex) isTabIndex = true;\n              const query = `#${idPrefix}${focusIndex + nextIndex}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`;\n              const field = document.querySelector(query);\n              if (field && !field?.hasAttribute?.('disabled')) {\n                field?.focus();\n                break;\n              } else if ((focusField === 'value' || focusField === 'length') && mainRow?.original?.indexFields?.length - 1 === index) {\n              // sub=>row\n                handleSubToRowFocus({ isNext: true, mainRow });\n              }\n            }\n          }\n          break; }\n\n        default:\n          break;\n      }\n    }\n  };\n\n  const handleAutoFocus = ({ mainRow, focusField, idPrefix }) => {\n    const index = mainRow ? stateData.modelIndexList[mainRow.index]?.indexFields?.length : stateData.modelIndexList.length;\n    const { FiledPosition } = getFieldPosition(index, mainRow, dbType);\n    let isTabIndex = false;\n    if (mainRow && focusField === 'attribute') { isTabIndex = true; }\n    const nextfield = document.querySelector(`#${idPrefix}${FiledPosition[focusField]}  ${isTabIndex ? '[tabindex=\"0\"]' : ''}`);\n    nextfield?.focus();\n  };\n\n  const value = {\n    dispatch,\n    modelIndexLoader,\n    showModelIndexLoader,\n    hideModelIndexLoader,\n    modelIndexList: stateData.modelIndexList,\n    editModelIndexData: stateData.editModelIndexData,\n    handleAddRow,\n    onKeyDownHandle,\n    handleAutoFocus,\n  };\n\n  return <IndexContext.Provider value={value}>{children}</IndexContext.Provider>;\n};\n\nfunction useIndex() {\n  const context = React.useContext(IndexContext);\n  if (context === undefined) {\n    throw new Error('useIndex must be used within a IndexProvider');\n  }\n  return context;\n}\n\nexport { IndexProvider, useIndex };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/Subrow/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { DndProvider } from 'react-dnd';\nimport HTML5Backend from 'react-dnd-html5-backend';\nimport { useTable } from 'react-table';\nimport '../../../../../../assets/css/Table.css';\nimport { cloneDeep, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { DragHandle } from '../../../Editor/TableView/TableData/Sortable';\nimport { EditableCell } from '../EditableCells';\nimport { SQL_INDEX } from '../../../../../../constant/modelIndexing';\nimport { DeleteIndex } from '../DeleteIndex';\nimport { useDraggable } from '../../Draggable/useDraggable';\nimport { useDroppable } from '../../Draggable/useDroppable';\nimport { MODEL_INDEX_ACTION_TYPES, useIndex } from '../IndexProvider';\n\nconst Row = React.memo(({\n  row, index, moveRow, mainRow,\n}) => {\n  const dragRef = React.useRef(null);\n\n  const { drag, isDragging, preview } = useDraggable({ index, type: 'sub-row' });\n  const { drop, dropRef } = useDroppable({ index, moveRow, type: 'sub-row' });\n\n  const opacity = isDragging ? 0.5 : 1;\n\n  preview(drop(dropRef));\n  drag(dragRef);\n\n  return (\n    <>\n      <tr {...row.getRowProps()} className=\"relative\" ref={dropRef} style={{ opacity }}>\n        <td>\n          <div className=\"flex items-center\" ref={dragRef}>\n            <DragHandle style={{\n              left: '0', position: 'relative', margin: '0', top: '0',\n            }}\n            />\n            {mainRow?.original?.name !== 'PRIMARY' && !mainRow?.original?.isDefault && (\n            <DeleteIndex deleteObj={row} mainRow={mainRow} />)}\n          </div>\n        </td>\n        {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n      </tr>\n    </>\n  );\n});\nRow.displayName = 'Row';\nconst Table = React.memo(({\n  columns, data, onInputChange, moveRow, onAddRow, mainRow,\n}) => {\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    visibleColumns,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn: {\n      Cell: EditableCell,\n    },\n    onInputChange,\n    moveRow,\n    onAddRow,\n    mainRow,\n  });\n  // Render the UI for your table\n  return (\n    <DndProvider backend={HTML5Backend}>\n      <table {...getTableProps()}>\n        <thead>\n          {headerGroups.map((headerGroup, i) => (\n            <tr {...headerGroup.getHeaderGroupProps()} className=\"relative\" key={`sub-header${i}`}>\n              <th> </th>\n              {headerGroup.headers.map((column, ci) => (\n                <th {...column.getHeaderProps()} key={`sub-col${i}${ci}`}>{column.render('Header')}</th>\n              ))}\n            </tr>\n          ))}\n        </thead>\n        <tbody {...getTableBodyProps()}>\n          {rows.map((row, index) => prepareRow(row) || (\n            <Row\n              key={`sub-row${index}`}\n              index={index}\n              row={row}\n              moveRow={moveRow}\n              visibleColumns={visibleColumns}\n              mainRow={mainRow}\n              rowProps={() => row.getRowProps()}\n              {...row.getRowProps()}\n            />\n          ))}\n        </tbody>\n        {mainRow?.original?.name !== 'PRIMARY' && !mainRow?.original?.isDefault\n        && mainRow?.original?.indexType !== SQL_INDEX.TYPE.GIN\n          ? (\n            <td colSpan=\"5\">\n              <div\n                className=\"ml-20 text-sm text-gray-white flex underline items-center cursor-pointer labelGroup focus:outline-none focus:text-primary-dark\"\n              >\n                <div\n                  className=\"w-4 h-4 mr-2\"\n                  onClick={onAddRow}\n                >\n                  <Icons.Add />\n                </div>\n                <span onClick={onAddRow}>Add row</span>\n              </div>\n            </td>\n          )\n          : null}\n      </table>\n    </DndProvider>\n  );\n});\nTable.displayName = 'Table';\nexport function SubRows({\n  //   row,data\n  row, rowProps,\n}) {\n  const {\n    modelIndexList, dispatch, handleAddRow, handleAutoFocus,\n  } = useIndex();\n  const rowIndexType = React.useMemo(() => ({\n    isBTree: row?.original?.indexType === SQL_INDEX.TYPE.BTREE,\n    isGin: row?.original?.indexType === SQL_INDEX.TYPE.GIN,\n    isPartial: row?.original?.indexType === SQL_INDEX.TYPE.PARTIAL,\n    isUnique: row?.original?.indexType === SQL_INDEX.TYPE.UNIQUE,\n  }), [row?.original?.indexType]);\n\n  const columns = React.useMemo(() => (rowIndexType.isBTree ? [\n    { key: 'attribute', Header: 'Attribute', accessor: 'attribute' },\n    // { key: 'collate', Header: 'Collate', accessor: 'collate' },\n    { key: 'order', Header: 'Order', accessor: 'order' },\n    { key: 'length', Header: 'Length', accessor: 'length' },\n  ] : rowIndexType.isPartial ? [\n    { key: 'attribute', Header: 'Attribute', accessor: 'attribute' },\n    { key: 'operator', Header: 'Operator', accessor: 'operator' },\n    { key: 'value', Header: 'Value', accessor: 'value' },\n  ] : rowIndexType.isGin ? [\n    { key: 'operator', Header: 'Operator', accessor: 'operator' },\n  ] : []), [rowIndexType]);\n\n  // if (loading) { //add this for async\n  //   return (\n  //     <tr>\n  //       <td />\n  //       <td colSpan={visibleColumns.length - 1}>\n  //         Loading...\n  //       </td>\n  //     </tr>\n  //   );\n  // }\n  // error handling here :)\n\n  const handleAddSubRow = () => {\n    dispatch({\n      type: MODEL_INDEX_ACTION_TYPES.ADD_SUB_ROW,\n      payload: { indexFields: row?.original?.indexFields, mainRow: row },\n    });\n    requestAnimationFrame(() => {\n    // auto focus on add new sub-row\n      handleAutoFocus({ mainRow: row, idPrefix: `srcell${row.index}`, focusField: 'attribute' });\n    });\n  };\n  const moveRow = (dragIndex, hoverIndex) => dispatch({\n    type: MODEL_INDEX_ACTION_TYPES.MOVE_SUB_ROW,\n    payload: { dragIndex, hoverIndex, mainRow: row },\n  });\n\n  const onInputChange = (rowIndex, columnId, value) => {\n    let newData = cloneDeep(modelIndexList);\n    let tempFields = [...newData[row.index]?.indexFields];\n    tempFields = tempFields.map((srow, index) => {\n      if (index === rowIndex) {\n        if (columnId === 'attribute') { // clear length field value while switching attributes\n          return {\n            ...tempFields[rowIndex],\n            length: '',\n            [columnId]: value,\n          };\n        }\n        return {\n          ...tempFields[rowIndex],\n          [columnId]: value,\n        };\n      }\n      return srow;\n    });\n    newData[row.index].indexFields = tempFields;\n    if (columnId === 'attribute') {\n      if (last(newData[row.index].indexFields)?.[columnId]) {\n        newData = handleAddRow({ mainRow: row, indexList: newData });\n      }\n    }\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n  };\n  const subRows = row?.original?.indexFields || handleAddSubRow;\n\n  return (\n    <>\n      <tr {...rowProps}>\n        <td colSpan=\"4\" className=\"subRow\">\n          {\n          !rowIndexType?.isUnique\n            ? (\n              <Table\n                columns={columns}\n                data={subRows}\n                onInputChange={onInputChange}\n                moveRow={moveRow}\n                onAddRow={handleAddSubRow}\n                mainRow={row}\n              />\n            ) : null\n        }\n        </td>\n      </tr>\n    </>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/TableCells/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport omitDeep from 'omit-deep-lodash';\nimport {\n  Select, Input, SelectTree, Checkbox,\n} from '../../../../../../components';\nimport {\n  getAssignOperatorOpts, getOperatorOpts, SQL_INDEX, getCollateOpts, SQL_TYPE_OPTIONS, MONGO_TYPE_OPTIONS,\n} from '../../../../../../constant/modelIndexing';\nimport { modelAttrRegex } from '../../../../../../utils/regex';\nimport { regex } from '../../../../../../components/utils';\nimport { useEditor } from '../../../Editor/EditorProvider';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../../../constant/common';\nimport { DB_TYPE, MONGODB_INDEX_NAME_LENGTH } from '../../../../../../constant/model';\n\n// Index Name\nexport const NameCell = React.memo(({\n  onKeyDown, ...otherProps\n}) => (\n  <div className=\"min-w-40 w-full\">\n    <Input\n      size=\"small\"\n      placeholder=\"Enter index name\"\n      customRegex={modelAttrRegex}\n      {...otherProps}\n      maxLength={otherProps?.isMongoDb ? MONGODB_INDEX_NAME_LENGTH : MAX_INPUT_FIELD_LIMIT.title}\n      onKeyDown={(e) => onKeyDown(e, 'name')}\n    />\n  </div>\n));\nNameCell.displayName = 'NameCell';\n// Index Type\n// const TYPE_OPT = getTypeOptions(SQL_INDEX.TYPE) || [];\nexport const TypeCell = React.memo(({\n  onKeyDown, id, ...otherProps\n}) => {\n  const cellRef = React.useRef(null);\n  return (\n    <div className=\"text-left min-w-40 w-full\">\n      <Select\n        ref={cellRef}\n        sizeSmall\n        placeholder=\"Enter data type\"\n        isClearable={false}\n        options={SQL_TYPE_OPTIONS.filter((option) => (option))}\n        inputId={id}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && cellRef?.current?.state?.menuIsOpen) { return; }\n            onKeyDown(e, 'indexType');\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </div>\n  );\n});\nTypeCell.displayName = 'TypeCell';\n// Model Attribute\nexport const MultiAttrCell = React.memo(({\n  value, onChange, onKeyDown, ...otherProps\n}) => {\n  const { code, dbType } = useEditor();\n  const options = omitDeep(JSON.parse(code), dbType === DB_TYPE.MONGODB ? '_id' : 'id');\n\n  const handleChange = (val) => {\n    onChange(val?.allSelectedNode?.map((node) => node?.fullName));\n  };\n\n  return (\n    <>\n      <SelectTree\n        placeholder=\"Select attribute\"\n        noDataMessage=\"No options found. Please enter model schema\"\n        size=\"small\"\n        data={options}\n        defaultValue={value || []} // set value in array as per package\n        handleChange={handleChange}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) { // 40 is arrow down\n            onKeyDown(e, 'fields');\n            if (e.keyCode === 13 || e.keyCode === 40) {\n              return;\n            }\n            if (e.ctrlKey || e.keyCode === 13) { e.preventDefault(); }\n          }\n        }}\n      />\n    </>\n  );\n});\nMultiAttrCell.displayName = 'MultiAttrCell';\n// Model Attribute\nexport const SingleAttrCell = React.memo(({\n  value, onChange, onKeyDown, ...otherProps\n}) => {\n  const { code, dbType } = useEditor();\n  const options = omitDeep(JSON.parse(code), dbType === DB_TYPE.MONGODB ? '_id' : 'id');\n\n  const handleChange = (val) => {\n    onChange(val?.allSelectedNode?.[0]?.fullName);\n  };\n\n  return (\n    <div className=\"min-w-40\">\n      <SelectTree\n        dark\n        mode=\"radioSelect\"\n        placeholder=\"Select attribute\"\n        noDataMessage=\"No options found. Please enter model schema\"\n        size=\"small\"\n        data={options}\n        defaultValue={value ? [value] : []} // set value in array as per package\n        handleChange={handleChange}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) { // 40 is arrow down\n            onKeyDown(e, 'attribute');\n            if (e.keyCode === 13 || e.keyCode === 40) {\n              return;\n            }\n            if (e.ctrlKey || e.keyCode === 13) { e.preventDefault(); }\n          }\n        }}\n      />\n    </div>\n  );\n});\nSingleAttrCell.displayName = 'SingleAttrCell';\n// Order Type\nexport const OrderTypeCell = React.memo(({\n  onKeyDown, id, ...otherProps\n}) => {\n  const cellRef = React.useRef(null);\n  return (\n    <div className=\"min-w-40 text-left\">\n      <Select\n        isClearable\n        dark\n        sizeSmall\n        placeholder=\"Select order type \"\n        options={SQL_INDEX.ORDER_TYPE_OPTIONS}\n        inputId={id}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && cellRef?.current?.state?.menuIsOpen) { return; }\n            onKeyDown(e, 'order');\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </div>\n  );\n});\nOrderTypeCell.displayName = 'OrderTypeCell';\n// Length\nexport const LengthCell = React.memo(({\n  onKeyDown, ...otherProps\n}) => (\n  <div className=\"min-w-40\">\n    <Input\n      dark\n      size=\"small\"\n      placeholder=\"Enter length(> 0)\"\n      {...otherProps}\n      customRegex={regex.notZeroPositive}\n      value={otherProps.value ? otherProps.value.toString() : ''}\n      onChange={(val) => otherProps?.onChange(Number(val))}\n      onKeyDown={(e) => onKeyDown(e, 'length')}\n    />\n\n  </div>\n));\nLengthCell.displayName = 'LengthCell';\n// Value\nexport const ValueCell = React.memo(({\n  onKeyDown, ...otherProps\n}) => (\n  <div className=\"min-w-40\">\n    <Input\n      dark\n      size=\"small\"\n      placeholder=\"Enter value\"\n      {...otherProps}\n      onKeyDown={(e) => onKeyDown(e, 'value')}\n    />\n\n  </div>\n));\nValueCell.displayName = 'ValueCell';\n// Collate\nexport const CollateCell = React.memo(({\n  onKeyDown, id, ...otherProps\n}) => {\n  const TYPE_OPT = getCollateOpts() || [];\n  return (\n    <div className=\"min-w-40\">\n      <Select\n        dark\n        sizeSmall\n        placeholder=\"Select Collate\"\n        isClearable\n        options={TYPE_OPT}\n        inputId={id}\n        {...otherProps}\n        onKeyDown={(e) => onKeyDown(e, 'fields')}\n      />\n    </div>\n  );\n});\nCollateCell.displayName = 'CollateCell';\n// Assignment Operator (>,<)\nexport const AssignmentOperatorCell = React.memo(({\n  defaultValue, onInputChange, onKeyDown, id, ...otherProps\n}) => {\n  const TYPE_OPT = getAssignOperatorOpts() || [];\n  const cellRef = React.useRef(null);\n  return (\n    <div className=\"min-w-40\">\n      <Select\n        WrapClassName=\"mt-1\"\n        dark\n        sizeSmall\n        isClearable\n        placeholder=\"Select operators\"\n        options={TYPE_OPT}\n        value={defaultValue}\n        inputId={id}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && cellRef?.current?.state?.menuIsOpen) { return; }\n            onKeyDown(e, 'operator');\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </div>\n  );\n});\nAssignmentOperatorCell.displayName = 'AssignmentOperatorCell';\n// Operator (>,<)\nexport const OperatorCell = React.memo(({\n  onKeyDown, ...otherProps\n}) => {\n  const TYPE_OPT = getOperatorOpts() || [];\n  const cellRef = React.useRef(null);\n  return (\n    <div className=\"\">\n      <Select\n        dark\n        size=\"small\"\n        placeholder=\"Select operator\"\n        options={TYPE_OPT}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && cellRef?.current?.state?.menuIsOpen) { return; }\n            onKeyDown(e, 'operator');\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </div>\n  );\n});\nOperatorCell.displayName = 'OperatorCell';\n// *******MONGO DB******\n\n// TTL\nexport const TTLCell = React.memo(({\n  onChange, onKeyDown, value, ...otherProps\n}) => (\n  <>\n    <Checkbox\n      wrapClass=\" flex-shrink-0\"\n      checked={!!value}\n      {...otherProps}\n      onChange={(val) => onChange(val, 'ttl')}\n      onKeyDown={(e) => {\n        if (e.keyCode === 13) {\n          onChange(!e?.target?.checked, 'ttl');\n        } else onKeyDown(e, 'ttl');\n      }}\n    />\n  </>\n));\nTTLCell.displayName = 'TTLCell';\n// TTL Input in seconds\nexport const InputTTLCell = React.memo(({\n  onChange, value, onKeyDown, ...otherProps\n}) => (\n  <>\n    <Input.Number\n      WrapClassName=\"flex-grow mr-12\"\n      size=\"small\"\n      extetion=\"Seconds\"\n      {...otherProps}\n      value={value ? value.toString() : ''}\n      onChange={(val) => onChange(Number(val), 'expireAfterSeconds')}\n      onKeyDown={(e) => onKeyDown(e, 'expireAfterSeconds')}\n    />\n  </>\n));\nInputTTLCell.displayName = 'InputTTLCell';\n\n// Unique index\nexport const UniqueCell = React.memo(({\n  value, onChange, onKeyDown, ...otherProps\n}) => (\n  <>\n    <div className=\"w-full min-w-40  pr-6 min-w-max text-left\">\n      <Checkbox\n        checked={!!value}\n        {...otherProps}\n        onChange={(val) => onChange(val, 'unique')}\n        onKeyDown={(e) => {\n          if (e.keyCode === 13) {\n            onChange(!e?.target?.checked, 'unique');\n          } else { onKeyDown(e, 'unique'); }\n        }}\n      />\n    </div>\n  </>\n));\nUniqueCell.displayName = 'UniqueCell';\n// Index Type\nexport const MongoIndexTypeCell = React.memo(({\n  onKeyDown, id, ...otherProps\n}) => {\n  const cellRef = React.useRef(null);\n  return (\n    <div className=\"w-full min-w-40\">\n      <Select\n        WrapClassName=\"w-full\"\n        sizeSmall\n        dark\n        ref={cellRef}\n        placeholder=\"Select index type\"\n        isClearable={false}\n        options={MONGO_TYPE_OPTIONS}\n        inputId={id}\n        {...otherProps}\n        onKeyDown={(e) => {\n          if (e.ctrlKey || e.keyCode === 13) {\n            if (e.keyCode === 13 && cellRef?.current?.state?.menuIsOpen) { return; }\n            onKeyDown(e, 'type');\n            if (e.ctrlKey) e.preventDefault();\n          }\n        }}\n      />\n    </div>\n  );\n});\nMongoIndexTypeCell.displayName = 'MongoIndexTypeCell';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/SQLIndexing/index.js",
    "content": "/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { DndProvider } from 'react-dnd';\nimport HTML5Backend from 'react-dnd-html5-backend';\nimport { useTable } from 'react-table';\nimport '../../../../../assets/css/Table.css';\nimport { cloneDeep, isEmpty, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { IconBox } from '../../../../../components';\nimport { DragHandle } from '../../Editor/TableView/TableData/Sortable';\nimport { EditableCell } from './EditableCells';\nimport { useIndex, MODEL_INDEX_ACTION_TYPES } from './IndexProvider';\nimport { SubRows } from './Subrow';\nimport { DeleteIndex } from './DeleteIndex';\nimport { useDraggable } from '../Draggable/useDraggable';\nimport { useDroppable } from '../Draggable/useDroppable';\nimport { SQL_INDEX } from '../../../../../constant/modelIndexing';\n\nconst defaultColumn = {\n  Cell: EditableCell,\n};\n\nconst Row = React.memo(({\n  row, index, moveRow, rowProps, visibleColumns, renderRowSubComponent, onExpand,\n}) => {\n  const dragRef = React.useRef(null);\n\n  const { drag, isDragging, preview } = useDraggable({ index });\n  const { drop, dropRef } = useDroppable({ index, moveRow });\n\n  const opacity = isDragging ? 0.5 : 1;\n\n  preview(drop(dropRef));\n  drag(dragRef);\n\n  return (\n    <>\n      <tr {...row.getRowProps()} className=\"relative\" ref={dropRef} style={{ opacity }}>\n        <td>\n          <div className=\"flex justify-start\" ref={dragRef}>\n            <DragHandle style={{\n              left: '0', position: 'relative', margin: '0', top: 'auto',\n            }}\n            />\n            {row?.original?.name !== 'PRIMARY' && !row?.original?.isDefault\n        && (<DeleteIndex deleteObj={row} />)}\n            {row?.original?.indexType && row?.original?.indexType !== SQL_INDEX.TYPE.UNIQUE && (\n            <span {...row.getToggleRowExpandedProps?.()}>\n              <div className=\"w-3 h-3 ml-3 cursor-pointer\" onClick={() => onExpand(row)}>\n                {row?.original?.isExpanded ? <Icons.DownArrow /> : <Icons.RightArrow />}\n              </div>\n            </span>\n            )}\n          </div>\n        </td>\n        {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n      </tr>\n      {row?.original?.indexType && row?.original?.indexType !== SQL_INDEX.TYPE.UNIQUE\n      && row?.original?.isExpanded && renderRowSubComponent({ row, rowProps, visibleColumns })}\n    </>\n  );\n});\nRow.displayName = 'Row';\nconst Table = React.memo(({\n  // eslint-disable-next-line no-unused-vars\n  columns, data, renderRowSubComponent, onInputChange, moveRow, onAddRow, onExpand,\n}) => {\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    visibleColumns,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn,\n    onInputChange,\n    moveRow,\n    onAddRow,\n    onExpand,\n  });\n  // Render the UI for your table\n  return (\n    <DndProvider backend={HTML5Backend}>\n      <table {...getTableProps()}>\n        <thead>\n          {headerGroups.map((headerGroup, i) => (\n            <tr {...headerGroup.getHeaderGroupProps()} className=\"relative\" key={`header${i}`}>\n              <th key=\"col-icon\" className=\"z-100\">\n                <IconBox\n                  size=\"small\"\n                  tooltipPlace=\"right\"\n                  className=\"\"\n                  icon={<Icons.Plus color=\"#fff\" />}\n                  tooltip=\"Add indexing\"\n                  onClick={onAddRow}\n                />\n              </th>\n              {headerGroup.headers.map((column, ci) => (\n                <th {...column.getHeaderProps()} key={`col${i}${ci}`}>{column.render('Header')}</th>\n              ))}\n            </tr>\n          ))}\n        </thead>\n        <tbody {...getTableBodyProps()}>\n          {rows.map((row, index) => prepareRow(row) || (\n            <Row\n              key={`row${index}`}\n              index={index}\n              row={row}\n              moveRow={moveRow}\n              onExpand={onExpand}\n              renderRowSubComponent={renderRowSubComponent}\n              visibleColumns={visibleColumns}\n              rowProps={() => row.getRowProps()}\n              {...row.getRowProps()}\n            />\n          ))}\n        </tbody>\n      </table>\n    </DndProvider>\n  );\n});\nTable.displayName = 'Table';\nexport const SQLIndexing = React.memo(() => {\n  const {\n    modelIndexList, dispatch, handleAddRow, handleAutoFocus,\n  } = useIndex();\n\n  const columns = React.useMemo(() => [\n    {\n      key: 'name',\n      Header: 'Index name',\n      accessor: 'name',\n    },\n    {\n      key: 'indexType',\n      Header: 'Data type',\n      accessor: 'indexType',\n    },\n    {\n      key: 'fields', // for table key\n      Header: 'Attribute',\n      accessor: 'fields', // to access value\n    },\n  ], []);\n\n  // Create a function that will render our row sub components\n  const renderRowSubComponent = React.useCallback(\n    ({ row, rowProps, visibleColumns }) => (\n      <SubRows\n        row={row}\n        rowProps={rowProps}\n        visibleColumns={visibleColumns}\n      />\n    ),\n    [],\n  );\n  const onInputChange = (rowIndex, columnId, value) => {\n    // const newData = [...modelIndexList];\n    let newData = cloneDeep(modelIndexList).map((row, index) => {\n      if (index === rowIndex) {\n        return {\n          ...modelIndexList[rowIndex],\n          [columnId]: value,\n          indexFields: columnId === 'indexType' ? [] : row.indexFields, // clear sub-row on change type\n        };\n      }\n      return row;\n    });\n    // newData[rowIndex] = {\n    //   ...newData[rowIndex],\n    //   [columnId]: value,\n    // };\n    if (columnId === 'indexType' && (value === SQL_INDEX.TYPE.GIN)) {\n      // GIN type\n      // on type change expand sub-row\n      newData[rowIndex].isExpanded = true;\n      newData[rowIndex].indexFields = [{ operator: '' }];\n    }\n    if (columnId === 'indexType' && (value === SQL_INDEX.TYPE.PARTIAL || value === SQL_INDEX.TYPE.BTREE)) {\n    // on type change expand sub-row\n      newData[rowIndex].isExpanded = true;\n      // add new sub-row on type change\n      if (!newData[rowIndex]?.indexFields?.length > 0) newData = handleAddRow({ indexList: newData, mainRow: { ...newData[rowIndex], index: rowIndex } });\n    }\n    if (columnId === 'name') {\n      if (last(newData)?.[columnId]?.length > 0) { newData = handleAddRow({ indexList: newData }); }\n    }\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.SET_LIST, payload: newData });\n  };\n\n  const moveRow = (dragIndex, hoverIndex) => dispatch({ type: MODEL_INDEX_ACTION_TYPES.MOVE_ROW, payload: { dragIndex, hoverIndex } });\n  const onAddRow = () => {\n    dispatch({ type: MODEL_INDEX_ACTION_TYPES.ADD_ROW });\n    requestAnimationFrame(() => {\n    // auto focus on add new row\n      handleAutoFocus({ idPrefix: 'rcell', focusField: 'name' });\n    });\n  };\n  const onExpand = (row) => dispatch({ type: MODEL_INDEX_ACTION_TYPES.EXPAND, payload: { row } });\n\n  return (\n    <>\n      <div className=\"dhiTable firstColTable text-left flex-grow h-full\">\n        {\n          !isEmpty(modelIndexList)\n            ? (\n              <Table\n                columns={columns}\n                data={modelIndexList}\n                renderRowSubComponent={renderRowSubComponent}\n                onInputChange={onInputChange}\n                moveRow={moveRow}\n                onAddRow={onAddRow}\n                onExpand={onExpand}\n              />\n            ) : null\n        }\n      </div>\n    </>\n  );\n});\nSQLIndexing.displayName = 'SQLIndexing';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/indexingCss.js",
    "content": "export const indexingCss = {\n  tableHeadTop: 'pl-8 items-center sticky top-0 z-10 bg-gray-black border-b border-gray-200',\n  tableHeadTr: 'py-2 px-5 text-base text-primary-text font-normal text-left sticky top-0 bg-gray-200 z-1',\n  tableBodyTop: 'border-b border-r border-gray-200',\n  tableBodyTd: 'relative py-2 px-5',\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/Indexing/makeData.js",
    "content": "/* eslint-disable no-plusplus */\n/* eslint-disable no-nested-ternary */\n// import namor from 'namor';\n\nconst range = (len) => {\n  const arr = [];\n  for (let i = 0; i < len; i++) {\n    arr.push(i);\n  }\n  return arr;\n};\n\nconst newPerson = (id) => {\n  const statusChance = Math.random();\n  return {\n    id,\n    firstName: 'hello',\n    lastName: 'world',\n    age: Math.floor(Math.random() * 30),\n    visits: Math.floor(Math.random() * 100),\n    progress: Math.floor(Math.random() * 100),\n    status:\n      statusChance > 0.66\n        ? 'relationship'\n        : statusChance > 0.33\n          ? 'complicated'\n          : 'single',\n  };\n};\n\nexport default function makeData(...lens) {\n  const makeDataLevel = (depth = 0) => {\n    const len = lens[depth];\n    return range(len).map((i) => ({\n      ...newPerson(i),\n      subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,\n    }));\n  };\n\n  return makeDataLevel();\n}\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/Attention/index.js",
    "content": "import React from 'react';\nimport Drawer from 'rc-drawer';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport omitDeep from 'omit-deep-lodash';\nimport { isArray, isEmpty } from 'lodash';\nimport {\n  Checkbox,\n  Description, DrawerClose, DrawerFooter, DrawerHead, ListBoxWrap, ListTitle,\n} from '../../../../../components';\nimport { useBoolean } from '../../../../../components/hooks';\nimport { useLibrary } from '../LibraryProvider';\nimport { createMultipleModels } from '../../../../../api/models';\nimport { useToastNotifications } from '../../../../hooks';\nimport { addMultipleModel } from '../../../../../redux/reducers/models';\n\nexport const Attention = ({\n  attentionRef, checkedDataJson, getRelationTableData, setPanel, checkedIndexData, checkedRefIndexes,\n}) => {\n  const [mapRelation, setMapRelation] = React.useState([]);\n\n  const [isOpen, handelOpen, handelClose] = useBoolean(false);\n  const [isSubmit, setSubmit, hideSubmit] = useBoolean(false);\n  // const { prepareTableView, tableToCodeViewParser } = useEditor();\n\n  const { libraryModelList, selectedModel } = useLibrary();\n  const { addSuccessToast, addErrorToast } = useToastNotifications();\n  const { applicationId, currentApplicationCode } = useSelector(({ projects }) => ({\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n  const dispatch = useDispatch();\n\n  React.useImperativeHandle(attentionRef, () => ({ handelOpen }));\n\n  React.useEffect(() => {\n    if (isOpen) {\n      const relationTableData = getRelationTableData();\n      // map relationdata ref to name\n      setMapRelation(libraryModelList.map((model) => (relationTableData.includes(model._id) ? { ...model, schemaJson: omitDeep(model.schemaJson, 'description'), checked: true } : false)).filter((el) => el && el));\n    }\n  }, [isOpen]);\n\n  const onSelectAll = (checked) => {\n    setMapRelation(mapRelation.map((r) => ({ ...r, checked })));\n  };\n  const onChecked = (checked, index) => {\n    mapRelation[index].checked = checked;\n    setMapRelation([...mapRelation]);\n  };\n  const handleSubmit = () => {\n    setSubmit();\n    const mainModel = checkedDataJson();\n    const mainIndexes = isArray(checkedRefIndexes?.current) ? checkedIndexData() : selectedModel.modelIndexes;\n    const models = [{\n      modelName: selectedModel.name,\n      description: selectedModel.description,\n      schemaJson: mainModel,\n      hooks: selectedModel.hooks ?? [],\n      modelIndexes: mainIndexes ?? [],\n    }, ...mapRelation.filter((rel) => rel.checked).map((model) => ({\n      modelName: model.name,\n      description: model.description,\n      schemaJson: model.schemaJson,\n      hooks: model.hooks,\n      modelIndexes: model.modelIndexes,\n    }))];\n    const request = { currentApplicationCode, applicationId, models };\n    createMultipleModels(request).then((res) => {\n      addSuccessToast(res.message);\n      hideSubmit();\n      res.data?.success && dispatch(addMultipleModel(res.data.success.filter((model) => !isEmpty(Object.values(model)))));\n      setPanel();\n    }).catch((error) => {\n      addErrorToast(error);\n      hideSubmit();\n    });\n  };\n  return (\n    <Drawer\n      open={isOpen}\n      ease\n      level={null}\n      handler={false}\n      placement=\"right\"\n      wrapperClassName=\"\"\n    >\n      <DrawerHead title=\"Your attention is required!\" />\n      <DrawerClose onClick={handelClose} />\n      <div className=\"flex-grow overflow-auto p-5 smallCheckbox\">\n        <Description>The model that you have selected is carrying relationships from the below model(s). You need to add the below model(s) to avoid errors. Selected model(s) will be directly added to the custom model list that you can further modify based on your requirements.</Description>\n        <div className=\"mt-4\">\n          <div className=\"pb-3\">\n            <Checkbox onChange={onSelectAll} checked={!(mapRelation.findIndex((r) => !r.checked) >= 0)}>Select all</Checkbox>\n          </div>\n          {mapRelation.map((relation, index) => (\n            <ListBoxWrap key={relation._id} className=\"flex\" variant=\"small\" onClick={() => { onChecked(!relation.checked, index); }}>\n              <Checkbox checked={relation.checked} />\n              <div className=\"flex-grow ml-1\">\n                <ListTitle title={relation.name} />\n                <Description>{relation.description}</Description>\n              </div>\n            </ListBoxWrap>\n          ))}\n        </div>\n      </div>\n      <DrawerFooter\n        handleCancel={handelClose}\n        cancelTitle=\"Cancel\"\n        handleSubmit={handleSubmit}\n        submitTitle=\"Create model(s)\"\n        isSubmitting={isSubmit}\n      />\n    </Drawer>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/HookSetup/HookEditor/index.js",
    "content": "import React from 'react';\nimport { CodeEditor } from '../../../../../../components';\n\nexport const HookEditor = ({ curHook }) => (\n  <div style={{ width: 'calc(100% - 14rem)' }} className=\"xl:h-full xxl:h-full\">\n    <CodeEditor\n      readOnly\n      className=\"w-full h-full\"\n      language=\"javascript\"\n      defaultValue=\"\"\n      value={curHook}\n    />\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/HookSetup/HookList/index.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { SidebarList } from '../../../../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../../../../../components';\nimport { HOOK_TAB_TITLE } from '../../../../../../constant/model';\n\nexport const HookList = React.memo(({\n  hooks, setCurHook, currentApplicationCode,\n}) => (\n  <>\n    <div className=\"w-56 h-full\">\n      <SidebarList\n        style={{ width: '100%' }}\n        title={(HOOK_TAB_TITLE[currentApplicationCode]?.split(' ')?.[0]) ?? 'Hook'}\n        sidebarClass=\"xl:h-full xxl:h-full\"\n      >\n        <Menu iconShape=\"square\" className=\"px-2\">\n          <SidebarMenuList\n            mainMenuList={hooks?.map((h, i) => ({ _id: i + 1, title: (`${h.type}-${h.operation}`) }))}\n            titleKey=\"title\"\n            initialSelectedId={1}\n            onClick={setCurHook}\n          />\n        </Menu>\n      </SidebarList>\n    </div>\n  </>\n));\nHookList.displayName = 'HookList';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/HookSetup/index.js",
    "content": "import React from 'react';\nimport { NoData } from '../../../../../components';\nimport { getHookHeader, getHookFooter } from '../../../../../constant/model';\nimport { useEditor } from '../../Editor/EditorProvider';\nimport { useLibrary } from '../LibraryProvider';\nimport { HookEditor } from './HookEditor';\nimport { HookList } from './HookList';\n\nexport const HookSetup = () => {\n  const { selectedModel } = useLibrary();\n  const { dbType, currentApplicationCode } = useEditor();\n  const [hookCode, setHookCode] = React.useState(1);\n\n  const handleCode = (curHookId) => {\n    if (!selectedModel?.hooks || !selectedModel?.name || !dbType || !currentApplicationCode) return;\n\n    const header = getHookHeader({\n      dbType, modelName: selectedModel?.name, currentApplicationCode, ...selectedModel.hooks[curHookId - 1],\n    });\n    const footer = getHookFooter({\n      dbType, modelName: selectedModel?.name, currentApplicationCode, ...selectedModel.hooks[curHookId - 1],\n    });\n\n    const tHook = `${header}\\n\\n${selectedModel.hooks[curHookId - 1]?.code}\\n\\n${footer}`;\n    setHookCode(tHook);\n  };\n\n  React.useEffect(() => {\n    handleCode(1);\n  }, []);\n\n  return (\n    <>\n      <div className=\"w-full flex h-full\">\n        {selectedModel?.hooks?.length > 0 ? (\n          <>\n            <HookList\n              hooks={selectedModel?.hooks || []}\n              setCurHook={handleCode}\n              currentApplicationCode={currentApplicationCode}\n            />\n            {hookCode && <HookEditor curHook={hookCode} />}\n          </>\n        ) : <NoData title=\"No hooks found\" />}\n      </div>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/Indexing/SubRow/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport { useTable, useExpanded, useFlexLayout } from 'react-table';\nimport '../../../../../../assets/css/Table.css';\nimport { DB_CONST, DB_TYPE } from '../../../../../../constant/model';\nimport { MONGO_TYPE_OPTIONS, SQL_INDEX } from '../../../../../../constant/modelIndexing';\n\nfunction Table({ columns, data }) {\n  // Use the state and functions returned from useTable to build your UI\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n  },\n  useExpanded,\n  useFlexLayout);\n  // Render the UI for your table\n  return (\n    <table {...getTableProps()}>\n      <thead style={{ zIndex: '0' }}>\n        {headerGroups.map((headerGroup, index) => (\n          <tr key={index} {...headerGroup.getHeaderGroupProps()} className=\"relative\">\n            {headerGroup.headers.map((column) => (\n              <th key={column.id} {...column.getHeaderProps()}>{column.render('Header')}</th>\n            ))}\n          </tr>\n        ))}\n      </thead>\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row) => {\n          prepareRow(row);\n          return (\n            <>\n              <tr {...row.getRowProps()} className=\"relative\">\n                {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n              </tr>\n            </>\n          );\n        })}\n      </tbody>\n    </table>\n  );\n}\n\nexport const SubRow = ({ data, mainRow }) => {\n  const dbType = useSelector((state) => DB_CONST[state.projects.applicationDatabase.databaseType]);\n\n  const rowIndexType = React.useMemo(() => ({\n    isBTree: mainRow?.original?.indexType === SQL_INDEX.TYPE.BTREE,\n    isGin: mainRow?.original?.indexType === SQL_INDEX.TYPE.GIN,\n    isPartial: mainRow?.original?.indexType === SQL_INDEX.TYPE.PARTIAL,\n    isUnique: mainRow?.original?.indexType === SQL_INDEX.TYPE.UNIQUE,\n  }), [mainRow?.original?.indexType]);\n\n  const columns = React.useMemo(() => (dbType === DB_TYPE.MONGODB\n    ? [\n      {\n        Header: () => null, // No header\n        id: 'expander', // It needs an ID\n        Cell: () => (\n          <div className=\"flex justify-start items-center smallCheckbox\" />\n        ),\n        SubCell: () => null, // No expander on an expanded row\n      },\n      {\n        key: 'attribute',\n        Header: 'Attribute',\n        accessor: 'attribute',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.attribute}\n          </div>\n        ),\n      },\n      {\n        key: 'type',\n        Header: 'Index type',\n        accessor: 'type',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {MONGO_TYPE_OPTIONS.find((x) => x.id === row?.original?.type)?.name}\n          </div>\n        ),\n      }] : rowIndexType.isBTree ? [\n      {\n        // Make an expander cell\n        Header: () => null, // No header\n        id: 'expander', // It needs an ID\n        Cell: () => (\n          <div className=\"flex justify-start items-center smallCheckbox\" />\n        ),\n        SubCell: () => null, // No expander on an expanded row\n      },\n      {\n        Header: 'Attribute',\n        accessor: 'name',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.attribute}\n          </div>\n        ),\n      },\n      {\n        Header: 'Order',\n        accessor: 'order',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.order}\n          </div>\n        ),\n      },\n      {\n        Header: 'Length',\n        accessor: 'Length',\n        Cell: ({ row }) => (\n          <div className=\"w-full text-left\">\n            {row?.original?.length}\n          </div>\n        ),\n      },\n    ] : rowIndexType.isPartial ? [\n      {\n        // Make an expander cell\n        Header: () => null, // No header\n        id: 'expander', // It needs an ID\n        Cell: () => (\n          <div className=\"flex justify-start items-center smallCheckbox\" />\n        ),\n        SubCell: () => null, // No expander on an expanded row\n      },\n      {\n        Header: 'Attribute',\n        accessor: 'name',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.attribute}\n          </div>\n        ),\n      },\n      {\n        Header: 'Operator',\n        accessor: 'Operator',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.operator}\n          </div>\n        ),\n      },\n      {\n        Header: 'Value',\n        accessor: 'Value',\n        Cell: ({ row }) => (\n          <div className=\"w-full text-left\">\n            {row?.original?.value}\n          </div>\n        ),\n      },\n    ] : []),\n  [dbType]);\n  return (\n    <>\n      <td colSpan=\"4\" className=\"subRow text-left\">\n        <Table\n          columns={columns}\n          data={data}\n        />\n      </td>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/Indexing/index.js",
    "content": "/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport { useTable, useExpanded, useRowSelect } from 'react-table';\nimport '../../../../../assets/css/Table.css';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Checkbox, NoData,\n} from '../../../../../components';\nimport { SubRow } from './SubRow';\nimport { useLibrary } from '../LibraryProvider';\nimport { DB_CONST, DB_TYPE } from '../../../../../constant/model';\nimport { SQL_INDEX } from '../../../../../constant/modelIndexing';\nimport { setAlreadyChecked } from '../PreviewTable';\n\nconst setDefaultChecked = (data) => {\n  // Default set all id to checked\n  const defaultChecked = {};\n  data.map((mainRow, i) => {\n    defaultChecked[i] = true;\n    return mainRow;\n  });\n  return defaultChecked;\n};\n\nfunction Table({\n  columns, data, setCheckedRefData,\n}) {\n  // Use the state and functions returned from useTable to build your UI\n  const { checkedData } = useLibrary();\n\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    prepareRow,\n    selectedFlatRows,\n    toggleRowSelected,\n    toggleAllRowsSelected,\n  } = useTable({\n    columns,\n    data,\n    initialState: {\n      selectedRowIds: checkedData.indexCheckedData !== null ? setAlreadyChecked(checkedData.indexCheckedData) : setDefaultChecked(data),\n    },\n  },\n  useExpanded,\n  useRowSelect,\n  (hooks) => {\n    hooks.visibleColumns.push(() => [\n      {\n        id: 'selection',\n        Header: ({ isAllRowsSelected }) => (\n          <Checkbox\n            checked={isAllRowsSelected}\n            onChange={(select) => { toggleAllRowsSelected(select); }}\n          />\n        ),\n        Cell: ({ row }) => (\n          <div className=\"flex justify-start items-center smallCheckbox\">\n            <Checkbox checked={row.isSelected} onChange={(checked) => { toggleRowSelected(row.id, checked); }} />\n            { row?.original?.indexType !== SQL_INDEX.TYPE.UNIQUE\n              ? (\n                <span {...row.getToggleRowExpandedProps()}>\n                  {row.isExpanded\n                    ? (\n                      <div className=\"w-3 h-3 ml-3 cursor-pointer\">\n                        <Icons.DownArrow />\n                      </div>\n                    )\n                    : (\n                      <div className=\"w-3 h-3 ml-3 cursor-pointer\">\n                        <Icons.RightArrow />\n                      </div>\n                    )}\n                </span>\n              ) : null}\n          </div>\n        ),\n      },\n      ...columns,\n    ]);\n  });\n\n  React.useEffect(() => {\n    setCheckedRefData(selectedFlatRows);\n  }, [selectedFlatRows]);\n\n  // React.useEffect(() => {\n  //   toggleAllRowsSelected(true);\n  // }, [toggleAllRowsSelected]);\n\n  // Render the UI for your table\n  return (\n    <table {...getTableProps()}>\n      <thead className=\"z-1\">\n        {headerGroups.map((headerGroup, index) => (\n          <tr key={index} {...headerGroup.getHeaderGroupProps()} className=\"relative\">\n            {headerGroup.headers.map((column) => (\n              <th key={column.id} {...column.getHeaderProps()}>{column.render('Header')}</th>\n            ))}\n          </tr>\n        ))}\n      </thead>\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row) => {\n          prepareRow(row);\n          return (\n            <>\n              <tr {...row.getRowProps()} className=\"relative\">\n                {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n              </tr>\n              {\n                  row.isExpanded\n                  && <tr><SubRow mainRow={row} data={row?.original?.indexFields || []} /></tr>\n              }\n            </>\n          );\n        })}\n      </tbody>\n    </table>\n  );\n}\n\nexport const Indexing = ({ setCheckedRefData }) => {\n  const { selectedModel, indexes, dispatch } = useLibrary();\n  const dbType = useSelector((state) => DB_CONST[state.projects.applicationDatabase.databaseType]);\n  const checkedRefData = React.useRef([]); // to manage global data\n  React.useEffect(() => () => {\n    dispatch({ type: 'SetCheckedData', payload: { indexCheckedData: checkedRefData.current } });\n  }, []);\n  const columns = React.useMemo(\n    () => [\n      {\n        id: 'name',\n        Header: 'Index name',\n        accessor: 'name',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {row?.original?.name}\n          </div>\n        ),\n      },\n      {\n        id: 'indexType',\n        Header: dbType === DB_TYPE.MONGODB ? 'Create TTL' : 'Data type',\n        accessor: 'indexType',\n        Cell: ({ row }) => (\n          <div className=\"w-full min-w-40 text-left\">\n            {dbType === DB_TYPE.MONGODB ? `${row?.original?.ttl ? `${row?.original?.expireAfterSeconds} seconds` : 'No'} ` : row?.original?.indexType}\n          </div>\n        ),\n      },\n      {\n        id: 'fields',\n        Header: dbType === DB_TYPE.MONGODB ? 'Unique index' : 'Attribute',\n        accessor: 'fields',\n        Cell: ({ row }) => {\n          const iFields = row?.original?.fields;\n          let fields = '-';\n          if (dbType !== DB_TYPE.MONGODB) {\n            if (iFields?.length > 0) {\n              fields = iFields.toString();\n            }\n          }\n\n          return (\n            <div className=\"w-full  text-left\">\n              {dbType === DB_TYPE.MONGODB ? `${row?.original?.unique ? 'Yes' : 'No'}` : fields}\n            </div>\n          );\n        },\n      },\n    ],\n    [],\n  );\n  return (\n    <>\n      <div className=\"dhiTable firstColTable onlyReadView text-left flex-grow h-full\">\n        {selectedModel?.modelIndexes?.length > 0 ? (\n          <Table\n            columns={columns}\n            data={indexes}\n            setCheckedRefData={(data) => {\n              checkedRefData.current = data;\n              setCheckedRefData(data);\n            }}\n\n          />\n        ) : <NoData title=\"No indexing found\" />}\n      </div>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/LibraryProvider.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { DB_CONST } from '../../../../constant/model';\nimport { prepareIndexing } from '../../../../constant/modelIndexing';\n\nexport const LibraryContext = React.createContext();\n\nfunction selectionReducer(state, { type, payload = {} }) {\n  switch (type) {\n    case 'SetSelectionModel': {\n      // For selected model id set\n      return { ...state, selectedModel: payload };\n    }\n    case 'ResetSelectionModel': {\n      return { ...state, selectedModel: {} };\n    }\n    case 'SetLibraryModelList': {\n      return { ...state, libraryModelList: payload };\n    }\n    case 'SetIndexes': {\n      return { ...state, indexes: payload };\n    }\n    case 'SetCheckedData': {\n      return { ...state, checkedData: { ...state.checkedData, ...payload } };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\n\nconst LibraryProvider = ({ children }) => {\n  const [stateData, dispatch] = React.useReducer(selectionReducer, {\n    checkedData: {\n      schemaCheckedData: null, // to set initial Data\n      indexCheckedData: null,\n    },\n    selectedModel: {},\n    libraryModelList: [],\n    indexes: [],\n  });\n  const dbType = useSelector((state) => DB_CONST[state.projects.applicationDatabase.databaseType]);\n\n  React.useMemo(() => {\n    if (dbType && stateData?.selectedModel?.modelIndexes) {\n      dispatch({\n        type: 'SetIndexes',\n        payload: prepareIndexing({ modelIndexes: stateData.selectedModel.modelIndexes, dbType }),\n      });\n    }\n  }, [dbType, stateData?.selectedModel]);\n  React.useEffect(() => () => {\n    dispatch({\n      type: 'SetCheckedData',\n      payload: {\n        schemaCheckedData: null,\n        indexCheckedData: null,\n      },\n    });\n  }, [stateData.selectedModel._id]);\n  const value = {\n    selectedModel: stateData.selectedModel,\n    libraryModelList: stateData.libraryModelList,\n    indexes: stateData.indexes,\n    checkedData: stateData.checkedData,\n    dispatch,\n  };\n  return <LibraryContext.Provider value={value}>{children}</LibraryContext.Provider>;\n};\nfunction useLibrary() {\n  const context = React.useContext(LibraryContext);\n  if (context === undefined) {\n    throw new Error('useLibrary must be used within a LibraryProvider');\n  }\n  return context;\n}\n\nexport { LibraryProvider, useLibrary };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/PreviewTable/EditableCell.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { Input } from '../../../../../components';\n\nfunction EditableCell({ row: { original }, column: { id } }) {\n  return (\n    <div className={`w-full text-left${id === 'description' && 'min-w-40'}`}>\n      <Input\n        {...(id === 'description' && { className: 'truncate' })}\n        size=\"small\"\n        {...(original?.original?.[id] && 'dark')}\n        WrapClassName=\"flex-grow\"\n        disabled\n        value={original[id] || original?.original?.[id]}\n      />\n    </div>\n  );\n}\n\nexport default EditableCell;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/PreviewTable/SubRow.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useTable, useExpanded, useFlexLayout } from 'react-table';\nimport { Checkbox } from '../../../../../components';\n\nfunction Table({\n  // eslint-disable-next-line no-unused-vars\n  columns, data, selectedFlatRows,\n}) {\n  // Use the state and functions returned from useTable to build your UI\n  const {\n    getTableProps,\n    getTableBodyProps,\n    rows,\n    prepareRow,\n\n  } = useTable({\n    columns,\n    data,\n    initialState: {\n      selectedRowIds: selectedFlatRows,\n    },\n  },\n  useExpanded,\n  useFlexLayout);\n  return (\n    <table {...getTableProps()}>\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row) => {\n          prepareRow(row);\n          return (\n            <>\n              <tr {...row.getRowProps()} className=\"relative\">\n                {row.cells.map((cell) => <td key={cell.row.key} {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n              </tr>\n            </>\n          );\n        })}\n      </tbody>\n    </table>\n  );\n}\nexport const SubRow = ({ subRowData, selectedFlatRows, onChangeCheckBox }) => {\n  const columns = [{\n    id: 'expander', // It needs an ID\n    Cell: ({ row }) => (\n      <div className=\"flex justify-end items-center smallCheckbox\">\n        <Checkbox\n          onChange={(checked) => { onChangeCheckBox(row.original.id, checked); }}\n          checked={selectedFlatRows.includes(row.original.id)}\n        />\n      </div>\n    ),\n\n  },\n  {\n    Header: 'Attribute',\n    accessor: 'attr',\n    Cell: ({ value }) => (\n      <div className=\"text-left min-w-40\">\n        {value}\n        {/* <Input dark size=\"small\" disabled value={value} /> */}\n      </div>\n    ),\n  }, {\n    Header: 'Data type',\n    accessor: 'type',\n    Cell: ({ value }) => (\n      <div className=\"text-left min-w-40\">\n        {value}\n        {/* <Input dark disabled size=\"small\" value={value} /> */}\n      </div>\n    ),\n  }, {\n    Header: 'Description',\n    accessor: 'description',\n    Cell: ({ value }) => (\n      <div className=\" text-left\">\n        {value}\n        {/* <Input placeHolder=\"Description\" dark WrapClassName=\"flex-grow\" disabled size=\"small\" value={value} /> */}\n      </div>\n    ),\n  }];\n\n  return (\n    <>\n      <td colSpan=\"4\" className=\"subRow text-left\">\n        <Table\n          columns={columns}\n          data={subRowData}\n          selectedFlatRows={selectedFlatRows}\n        />\n      </td>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/PreviewTable/index.js",
    "content": "/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport {\n  useTable, useExpanded, useRowSelect, useFlexLayout,\n} from 'react-table';\n// import { TableViewCss } from '@assets/css/tableViewCss';\nimport { isEmpty } from 'lodash';\nimport '../../../../../assets/css/Table.css';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Checkbox, Description,\n} from '../../../../../components';\nimport { SubRow } from './SubRow';\nimport { useLibrary } from '../LibraryProvider';\nimport { useEditor } from '../../Editor/EditorProvider';\nimport { PopOver } from '../../../../../components/PopOver';\n\nconst columns = [{\n  Header: 'Attribute',\n  accessor: 'attr',\n  minWidth: 180,\n  width: 180,\n  maxWidth: 180,\n  Cell: ({ value }) => (\n    <div className=\"text-left min-w-40\">\n      {value}\n      {/* <Input size=\"small\" disabled value={value} /> */}\n    </div>\n  ),\n}, {\n  Header: 'Data type',\n  accessor: 'type',\n  minWidth: 130,\n  width: 130,\n  maxWidth: 130,\n  Cell: ({ value }) => (\n    <div className=\"text-left min-w-40\">\n      {value}\n      {/* <Input WrapClassName=\"flex-grow\" disabled size=\"small\" value={value} /> */}\n    </div>\n  ),\n}, {\n  Header: 'Description',\n  accessor: 'description',\n  minWidth: 250,\n  width: 250,\n  maxWidth: 250,\n  Cell: ({ value }) => (\n    <>\n      <div className=\"flex justify-between\">\n        <div className=\"text-left whitespace-normal\">\n          {value ? value.slice(0, 80) : '-'}\n          {/* <Input placeHolder=\"Description\" className=\"truncate\" WrapClassName=\"flex-grow\" disabled size=\"small\" value={value} /> */}\n\n          {value?.trim()?.length >= 80\n            && (\n            <PopOver\n              className=\"inline-block text-primary-dark hover:underline cursor-pointer ml-1\"\n              data=\"Read more\"\n              place=\"left\"\n              popOverValue={\n                <Description className=\"max-w-xl sm:text-primary-text opacity-80\">{value}</Description>\n        }\n            />\n            )}\n        </div>\n      </div>\n    </>\n  ),\n}];\nconst setDefaultChecked = (data) => {\n  // Default set all id to checked\n  const defaultChecked = {};\n  data.forEach((mainRow) => {\n    if (!isEmpty(mainRow.subRows)) {\n      mainRow.subRows.forEach((sub) => { defaultChecked[`${mainRow.key.slice(1)}.${sub.key.slice(2)}`] = true; });\n    }\n    defaultChecked[mainRow.key.slice(1)] = true;\n  });\n  return defaultChecked;\n};\n// To manage global all tab checked Data\nexport const setAlreadyChecked = (data) => {\n  const defaultChecked = {};\n  data.forEach((mainRow) => {\n    if (!isEmpty(mainRow.subRows)) {\n      // when subRow in not Expanded\n      mainRow.subRows.forEach((sub) => { defaultChecked[sub.id] = sub.isSelected !== undefined ? sub.isSelected : true; });\n    }\n    defaultChecked[mainRow.id] = true;\n  });\n  return defaultChecked;\n};\nconst Table = ({\n  data, setCheckedRefData,\n}) => {\n  const { checkedData } = useLibrary();\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    prepareRow,\n    selectedFlatRows,\n    toggleRowSelected,\n    toggleAllRowsSelected,\n  } = useTable({\n    columns,\n    data,\n    initialState: {\n      // null checked because all data empty\n      selectedRowIds: checkedData.schemaCheckedData !== null ? setAlreadyChecked(checkedData.schemaCheckedData) : setDefaultChecked(data),\n    },\n  }, useExpanded,\n  useRowSelect,\n  useFlexLayout,\n  (hooks) => {\n    hooks.visibleColumns.push((allColumns) => [\n      {\n        id: 'selection',\n        Header: ({ isAllRowsSelected }) => (\n          <Checkbox\n            checked={isAllRowsSelected}\n            onChange={(select) => { toggleAllRowsSelected(select); }}\n          />\n        ),\n        Cell: ({ row }) => (\n          <div className=\"flex justify-start items-center smallCheckbox\">\n            <Checkbox checked={row.isSelected} onChange={(checked) => { toggleRowSelected(row.id, checked); }} />\n            {!isEmpty(row.subRows) && (\n            <span {...row?.getToggleRowExpandedProps?.()}>\n              {row.isExpanded\n                ? (\n                  <div className=\"w-3 h-3 ml-3 cursor-pointer\">\n                    <Icons.DownArrow />\n                  </div>\n                )\n                : (\n                  <div className=\"w-3 h-3 ml-3 cursor-pointer\">\n                    <Icons.RightArrow />\n                  </div>\n                )}\n            </span>\n            )}\n          </div>\n        ),\n      },\n      ...allColumns,\n    ]);\n  });\n  React.useEffect(() => {\n    setCheckedRefData(selectedFlatRows);\n  }, [selectedFlatRows]);\n\n  React.useEffect(() => {\n    toggleAllRowsSelected(true);\n  }, [toggleAllRowsSelected]);\n  return (\n    <table {...getTableProps()} className=\"\">\n      <thead>\n        {headerGroups.map((headerGroup, index) => (\n          <tr key={index} {...headerGroup.getHeaderGroupProps()} className=\"relative\">\n            {headerGroup.headers.map((column) => (\n              <th key={column.id} {...column.getHeaderProps()}>{column.render('Header')}</th>\n            ))}\n          </tr>\n        ))}\n      </thead>\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row) => prepareRow(row) || (\n          <>\n            {row.depth === 0 && (\n            // to remove dupliacte subrow\n            <tr {...row.getRowProps()} className=\"relative\">\n\n              {row.cells.map((cell) => (\n                <td key={cell.row.id} {...cell.getCellProps()}>{cell.render('Cell')}</td>\n              ))}\n            </tr>\n            )}\n            {\n                 !isEmpty(row.subRows) && row.isExpanded\n                  && (\n                  <tr>\n                    <SubRow\n                      onChangeCheckBox={\n                        toggleRowSelected\n}\n                      selectedFlatRows={selectedFlatRows.map((selected) => selected.id)}\n                      subRowData={row.subRows.map((sub) => ({ id: sub.id, ...sub.original }))}\n                    />\n                  </tr>\n                  )\n              }\n          </>\n        ))}\n      </tbody>\n    </table>\n  );\n};\n\nexport const PreviewTable = ({ setCheckedRefData }) => {\n  const {\n    selectedModel, libraryModelList, dispatch,\n  } = useLibrary();\n  const checkedRefData = React.useRef([]); // to manage global data\n  const { prepareTableView } = useEditor();\n  const [tableData, setTableData] = React.useState([]);\n  React.useEffect(() => {\n    setTableData(prepareTableView({\n      isExcludeArrayId: true,\n      tCode: { ...selectedModel.schemaJson },\n      isMount: true,\n      isReturnTempArray: true,\n      customModelList: libraryModelList,\n    }) ?? []);\n  }, [selectedModel._id]);\n  React.useEffect(() => () => {\n    // set already checkedData\n    dispatch({ type: 'SetCheckedData', payload: { schemaCheckedData: checkedRefData.current } });\n  }, []);\n  return (\n    <>\n      <div className=\"dhiTable firstColTable onlyReadView text-left flex-grow h-full\">\n        <Table\n          data={tableData}\n          setCheckedRefData={(data) => {\n            checkedRefData.current = data;\n            setCheckedRefData(data);\n          }}\n        />\n      </div>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/LibraryPreview/index.js",
    "content": "import React from 'react';\nimport { isArray, isEmpty, uniq } from 'lodash';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport { TabCSs } from '../../../../assets/css/tab';\nimport {\n  Description, Heading, StepFooter,\n} from '../../../../components';\nimport { PreviewTable } from './PreviewTable';\nimport { useLibrary } from './LibraryProvider';\nimport { useEditor } from '../Editor/EditorProvider';\nimport { createModel } from '../../../../api/models';\nimport { useBoolean } from '../../../../components/hooks';\nimport { addModel } from '../../../../redux/reducers/models';\nimport { useToastNotifications } from '../../../hooks';\nimport { Attention } from './Attention';\nimport { HOOK_TAB_TITLE, ModelPanel } from '../../../../constant/model';\nimport { HookSetup } from './HookSetup';\nimport { Indexing } from './Indexing';\n\nexport const LibraryPreview = ({ setPanel }) => {\n  const attentionRef = React.useRef(); // Attention Model open\n  const checkedRefData = React.useRef({}); // To Take Library checked data\n  const checkedRefIndexes = React.useRef(); // To Take Library checked data\n  const relationTableData = React.useRef([]); // To Take Relation Table Data\n  const dispatch = useDispatch();\n  const [isSubmit, setSubmit, hideSubmit] = useBoolean(false);\n  const { applicationId, currentApplicationCode, modelList } = useSelector(({ projects, models }) => ({\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n    modelList: models.modelList,\n  }), shallowEqual);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const { selectedModel, dispatch: libraryDispatch, libraryModelList } = useLibrary();\n  const { tableToCodeViewParser } = useEditor();\n\n  const checkedDataJson = (isRelationTable = false) => checkedRefData.current.map((checked) => {\n    if (checked.original.ref && isRelationTable && checked.isSelected && libraryModelList.find((model) => model._id === checked.original.ref)?.name !== selectedModel.name\n      && modelList.findIndex((model) => model.name?.toLowerCase() === libraryModelList.find((library) => library._id === checked.original.ref)?.name?.toLowerCase()) < 0) {\n      relationTableData.current.push(checked.original.ref);\n    }\n    if (checked.isSelected && !checked.original.rowKey) {\n      return {\n        ...checked.original,\n        description: undefined,\n        // sub is undefined when subattribute is  not open\n        subRows: checked?.subRows?.filter((sub) => sub.isSelected || sub.isSelected === undefined).map((sub) => ({ ...sub.original, description: undefined })),\n      };\n    }\n    return false;\n  }).filter((el) => el && el);\n\n  const checkedIndexData = () => {\n    const selected = [];\n    checkedRefIndexes?.current?.forEach((checked) => {\n      if (checked.isSelected && !checked.original.rowKey) {\n        const isExist = selectedModel?.modelIndexes?.find((x) => x.name === checked?.original?.name);\n        if (isExist) { selected.push(isExist); }\n      }\n    });\n    return selected;\n  };\n\n  const handelSubmit = () => {\n    // attentionRef.current.handelOpen();\n    relationTableData.current = [];\n    const mapTemplate = checkedDataJson(true);\n    const mapIndexes = isArray(checkedRefIndexes?.current) ? checkedIndexData() : selectedModel.modelIndexes;\n    if (!isEmpty(relationTableData.current)) { attentionRef.current.handelOpen(); return; }\n    if (isEmpty(mapTemplate)) {\n      addErrorToast('You cannot create template without selecting any attributes. Kindly select the attributes and then proceed further.');\n      return;\n    }\n    setSubmit();\n    createModel({\n      modelIndexes: mapIndexes ?? [],\n      hooks: selectedModel.hooks ?? [],\n      schemaJson: tableToCodeViewParser({\n        tableArr: mapTemplate, isReturnJson: true, customModelList: libraryModelList, isExcludeArrayId: true,\n      }) ?? {},\n      applicationId,\n      definitionType: currentApplicationCode,\n      description: selectedModel.description,\n      name: selectedModel.name,\n    }).then((createRes) => {\n      dispatch(addModel(createRes?.data));\n      addSuccessToast(createRes?.message);\n      hideSubmit();\n      setPanel(ModelPanel.CUSTOM.name);\n    }).catch((error) => { addErrorToast(error); hideSubmit(); });\n  };\n  React.useEffect(() => {\n    relationTableData.current = [];\n  }, [selectedModel]);\n  return (\n    <>\n      {isEmpty(selectedModel)\n        && (\n          <div className=\"flex justify-center items-center h-full\">\n            <div className=\"text-center\">\n              <div className=\"w-24 h-24 m-auto mb-6\">\n                <Icons.Preview />\n              </div>\n              <Description variant=\"subTitle\">DhiWise offers a number of pre-defined schemas. Explore it, customize it and use it.</Description>\n            </div>\n          </div>\n        )}\n      {!isEmpty(selectedModel) && (\n      <>\n        <div className=\"px-3 py-2 previewTop\">\n          <Heading variant=\"h4\">{selectedModel?.name}</Heading>\n          <Description className=\"mt-1 xxl:w-9/12\">{selectedModel?.description}</Description>\n        </div>\n        <Tabs\n          selectedTabClassName={TabCSs.selectTab}\n          selectedTabPanelClassName=\"flex-grow h-0\"\n          className=\"relative flex-grow flex flex-col h-full\"\n        >\n          <TabList\n            className={`${TabCSs.tabHead}`}\n          >\n            <Tab className={TabCSs.tabTitle}>\n              Schema\n              {Object.keys(selectedModel.schemaJson || {}).length > 0 ? `(${Object.keys(selectedModel.schemaJson).length})` : ''}\n            </Tab>\n            <Tab className={TabCSs.tabTitle}>\n              {HOOK_TAB_TITLE[currentApplicationCode]}\n              {selectedModel?.hooks?.length > 0 ? `(${selectedModel.hooks.length})` : ''}\n            </Tab>\n            <Tab className={TabCSs.tabTitle}>\n              Indexing\n              {selectedModel?.modelIndexes?.length > 0 ? `(${selectedModel.modelIndexes.length})` : ''}\n            </Tab>\n          </TabList>\n          <TabPanel>\n            <PreviewTable\n              key={selectedModel._id}\n              setCheckedRefData={(checked) => { checkedRefData.current = checked; }}\n            />\n          </TabPanel>\n          <TabPanel>\n            <HookSetup key={`hook-${selectedModel._id}`} />\n          </TabPanel>\n          <TabPanel>\n            <Indexing\n              key={`indexing-${selectedModel._id}`}\n              checkedRefIndexes={checkedRefIndexes?.current}\n              setCheckedRefData={(checked) => { checkedRefIndexes.current = checked; }}\n            />\n          </TabPanel>\n        </Tabs>\n        <div>\n          <StepFooter\n            className=\"modelFooter\"\n            backClick={() => { libraryDispatch({ type: 'SetSelectionModel', payload: {} }); }}\n            Back=\"Cancel\"\n            Next=\"Use template\"\n            nextClick={handelSubmit}\n            nextLoading={isSubmit}\n          />\n        </div>\n        <Attention\n          attentionRef={attentionRef}\n          checkedDataJson={() => tableToCodeViewParser({\n            tableArr: checkedDataJson(false), isReturnJson: true, customModelList: libraryModelList, isExcludeArrayId: true,\n          })}\n          getRelationTableData={() => (uniq(relationTableData.current))}\n          setPanel={() => { setPanel(ModelPanel.CUSTOM.name); }}\n          checkedRefIndexes={checkedRefIndexes}\n          checkedIndexData={checkedIndexData}\n        />\n      </>\n      )}\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/ModelList/ModelLibrary/Library.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 5)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          className=\"mt-5\"\n          width=\"100%\"\n          height=\"50px\"\n          // viewBox=\"0 0 100% 50px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"80px\" height=\"6\" />\n          <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"50%\" height=\"6\" />\n\n          <rect x=\"90%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"8%\" height=\"6\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/ModelList/ModelLibrary/LibraryModelData.js",
    "content": "/* eslint-disable no-template-curly-in-string */\nimport { DATABASE_TYPE } from '../../../../../constant/Project/applicationStep';\n\nexport const LibraryModelData = {\n  [DATABASE_TYPE.MONGODB]: [\n    {\n      _id: '611e1e50b9fee44a6a19400b',\n      name: 'Blog',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        title: {\n          type: 'String',\n          description: 'Title of blog post',\n        },\n        alternativeHeadline: {\n          type: 'String',\n          description: 'Alternative  headline of blog post',\n        },\n        image: {\n          type: 'String',\n          description: 'Image of blog',\n        },\n        publishDate: {\n          type: 'String',\n          description: 'Publish date of blog',\n        },\n        author: {\n          name: {\n            type: 'String',\n            description: 'Name of author',\n          },\n          image: {\n            type: 'String',\n            description: 'Picture of author',\n          },\n          email: {\n            type: 'String',\n            description: 'Email of author',\n          },\n        },\n        publisher: {\n          name: {\n            type: 'String',\n            description: 'Name of publisher',\n          },\n          url: {\n            type: 'String',\n          },\n          logo: {\n            type: 'String',\n          },\n        },\n        articleSection: {\n          type: 'String',\n        },\n        articleBody: {\n          type: 'String',\n          description: 'Blog artical that you want to display',\n        },\n        description: {\n          type: 'String',\n        },\n        slug: {\n          type: 'String',\n          description: 'Uniq slug',\n        },\n        url: {\n          type: 'String',\n        },\n        isDraft: {\n          type: 'Boolean',\n        },\n        isDeleted: {\n          type: 'Boolean',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      hooks: [\n        {\n          code: \"// 'this' refers to the current document about to be saved\\nconst record = this;\\n// create slug using title\\nlet slug = record.title.toLowerCase();\\nslug = slug.replace(/\\\\s+/g,\\\"-\\\")\\n// Replace and then store it\\nrecord.slug = slug;\",\n          operation: 'save',\n          type: 'pre',\n        },\n      ],\n      modelIndexes: [\n        {\n          name: 'index_title_publishdate',\n          indexFields: {\n            title: 1,\n            publishDate: -1,\n          },\n          options: {\n            unique: true,\n          },\n        },\n        {\n          name: 'index_title',\n          indexFields: {\n            title: 1,\n          },\n        },\n        {\n          name: 'index_publishdate',\n          indexFields: {\n            publishDate: -1,\n          },\n        },\n      ],\n    },\n    {\n      _id: '611e1e50b9fee44a6a19400c',\n      name: 'Master',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'string',\n        },\n        slug: {\n          type: 'string',\n        },\n        code: {\n          type: 'string',\n        },\n        group: {\n          type: 'string',\n          description: 'Group name in which group you want to consider master',\n        },\n        description: {\n          type: 'string',\n        },\n        sequence: {\n          type: 'Number',\n        },\n        image: {\n          type: 'string',\n        },\n        parentId: {\n          type: 'ObjectId',\n          ref: 'Master',\n        },\n        parentCode: {\n          type: 'Boolean',\n        },\n        isDefault: {\n          type: 'Boolean',\n          default: false,\n        },\n        isDeleted: {\n          type: 'Boolean',\n          default: false,\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      hooks: [\n        {\n          code: \" // 'this' refers to the current document about to be saved\\n  const record = this;\\n  // create slug using code\\n  const slug = record.code.toLowerCase();\\n  // Replace and then store it\\n  record.slug = slug;\",\n          operation: 'save',\n          type: 'pre',\n        },\n      ],\n    },\n    {\n      _id: '611e1e50b9fee44a6a19400d',\n      name: 'Event',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'string',\n          description: 'Name of event',\n        },\n        description: {\n          type: 'string',\n        },\n        address: {\n          line1: {\n            type: 'string',\n          },\n          line2: {\n            type: 'string',\n          },\n          city: {\n            type: 'string',\n          },\n          country: {\n            type: 'string',\n          },\n          state: {\n            type: 'string',\n          },\n          pincode: {\n            type: 'string',\n          },\n          lat: {\n            type: 'Number',\n            description: 'latitude of location',\n          },\n          lng: {\n            type: 'Number',\n            description: 'longitude  of location',\n          },\n        },\n        startDateTime: {\n          type: 'Date',\n          description: 'Start date event',\n        },\n        endDateTime: {\n          type: 'Date',\n          description: 'End date event',\n        },\n        speakers: [\n          {\n            name: {\n              type: 'string',\n            },\n            image: {\n              type: 'string',\n            },\n            email: {\n              type: 'string',\n            },\n          },\n        ],\n        organizer: {\n          name: {\n            type: 'string',\n          },\n          image: {\n            type: 'string',\n          },\n          email: {\n            type: 'string',\n          },\n          url: {\n            type: 'string',\n          },\n        },\n        image: {\n          type: 'string',\n        },\n        attachments: {\n          type: 'Array',\n          decription: 'Event attachemnt',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      modelIndexes: [\n        {\n          name: 'index_name',\n          indexFields: {\n            name: 1,\n          },\n          options: {\n            unique: true,\n          },\n        },\n      ],\n    },\n    {\n      _id: '611e1e50b9fee44a6a19400e',\n      name: 'Appointment_slot',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        startTime: {\n          type: 'Date',\n          required: true,\n          description: 'slot start time',\n        },\n        endTime: {\n          type: 'Date',\n          required: true,\n          description: 'slot end time',\n        },\n        offset: {\n          type: 'Number',\n          description: 'add offset to mange timezone',\n        },\n        appliedFrom: {\n          type: 'Date',\n          description: 'from when this slot it available',\n        },\n        appliedTo: {\n          type: 'Date',\n          description: 'to  which date this slot it available',\n        },\n        userId: {\n          type: 'ObjectId',\n          ref: 'user',\n          description: 'for  user wise slot ',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      modelIndexes: [\n        {\n          name: 'index_startTime',\n          indexFields: {\n            startTime: -1,\n          },\n        },\n      ],\n    },\n    {\n      _id: '611e1e50b9fee44a6a19400f',\n      name: 'Appointment_schedule',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        slot: {\n          type: 'ObjectId',\n          ref: 'Appointment_slot',\n          description: 'reference of slot module',\n        },\n        startTime: {\n          type: 'Date',\n          required: true,\n          description: 'start time of schedule',\n        },\n        endTime: {\n          type: 'Date',\n          required: true,\n          description: 'end time of schedule',\n        },\n        date: {\n          type: 'Date',\n          required: true,\n          description: 'Date of schedule',\n        },\n        offset: {\n          type: 'Number',\n          description: 'add offset to mange timezone',\n        },\n        participant: {\n          type: 'Array',\n          description: 'number of user who paricipant in booked appoinment',\n        },\n        host: {\n          type: 'ObjectId',\n          ref: 'user',\n          description: 'host of appoinment who manage the requested schedule',\n        },\n        isCancelled: {\n          type: 'Boolean',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194010',\n      name: 'ToDo',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'String',\n        },\n        description: {\n          type: 'String',\n        },\n        date: {\n          type: 'Date',\n        },\n        dueDate: {\n          type: 'Date',\n        },\n        isCompleted: {\n          type: 'Boolean',\n        },\n        settings: {\n          type: 'JSON',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      modelIndexes: [\n        {\n          name: 'index_date',\n          indexFields: {\n            date: -1,\n          },\n        },\n        {\n          name: 'index_dueDate',\n          indexFields: {\n            dueDate: -1,\n          },\n        },\n      ],\n    },\n    {\n      _id: '611e1e50b9fee44a6a194011',\n      name: 'Chat_group',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'String',\n          required: true,\n        },\n        code: {\n          type: 'String',\n          required: true,\n        },\n        admin: {\n          type: 'String',\n          required: true,\n        },\n        member: {\n          type: 'Array',\n          description: 'Array of memberid',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194012',\n      name: 'Chat_message',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        message: {\n          type: 'String',\n          required: true,\n        },\n        sender: {\n          type: 'String',\n          required: true,\n          description: 'Sender id of message',\n        },\n        recipient: {\n          type: 'String',\n          required: true,\n          description: 'Recipient id of message',\n        },\n        groupId: {\n          type: 'ObjectId',\n          ref: 'Chat_group',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194013',\n      name: 'Comment',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        comment: {\n          type: 'String',\n        },\n        upvoteCount: {\n          type: 'Number',\n        },\n        downVoteCount: {\n          type: 'Number',\n        },\n        commentTime: {\n          type: 'Date',\n        },\n        parentItem: {\n          type: 'ObjectId',\n          ref: 'Comment',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194014',\n      name: 'Plan',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'String',\n        },\n        decription: {\n          type: 'String',\n        },\n        code: {\n          type: 'String',\n        },\n        validityInDays: {\n          type: 'String',\n        },\n        minimumUser: {\n          type: 'Number',\n        },\n        maximumUser: {\n          type: 'Number',\n        },\n        perUserAmount: {\n          type: 'Number',\n        },\n        markup: {\n          type: 'Number',\n        },\n        discount: {\n          type: 'Number',\n        },\n        validFrom: {\n          type: 'Date',\n        },\n        validTo: {\n          type: 'Date',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194015',\n      name: 'Task',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        title: {\n          type: 'String',\n        },\n        description: {\n          type: 'String',\n        },\n        attachments: {\n          type: 'Array',\n        },\n        status: {\n          type: 'Number',\n        },\n        date: {\n          type: 'Date',\n        },\n        dueDate: {\n          type: 'Date',\n        },\n        completedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        completedAt: {\n          type: 'Date',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n    {\n      _id: '611e1e50b9fee44a6a194016',\n      name: 'Customer',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        firstName: {\n          type: 'String',\n        },\n        lastName: {\n          type: 'String',\n        },\n        name: {\n          type: 'String',\n        },\n        profile: {\n          type: 'String',\n        },\n        contactNumber: {\n          type: 'String',\n        },\n        email: {\n          type: 'String',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date ',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n      modelIndexes: [\n        {\n          name: 'index_firstName_lastName',\n          indexFields: {\n            firstName: 1,\n            lastName: 1,\n          },\n        },\n        {\n          name: 'index_firstName',\n          indexFields: {\n            firstName: 1,\n          },\n        },\n        {\n          name: 'index_lastName',\n          indexFields: {\n            firstName: 1,\n          },\n        },\n      ],\n      hooks: [\n        {\n          // eslint-disable-next-line no-template-curly-in-string\n          code: \" // 'this' refers to the current document about to be saved\\n  const user = this;\\n\\n  user.name = `${user.firstName}, ${user.lastName}`;\\n  \",\n          operation: 'save',\n          type: 'pre',\n        },\n        {\n          // eslint-disable-next-line no-template-curly-in-string\n          code: \" // 'this' refers to the current document about to be saved\\n  const user = this;\\n\\n  user.name = `${user.firstName}, ${user.lastName}`;\\n  \",\n          operation: 'save',\n          type: 'post',\n        },\n      ],\n    },\n    {\n      _id: '6124c4837e7d38eaf76492a1',\n      name: 'user',\n      ormType: 1,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        firstName: {\n          type: 'String',\n        },\n        lastName: {\n          type: 'String',\n        },\n        name: {\n          type: 'String',\n        },\n        username: {\n          type: 'String',\n        },\n        password: {\n          type: 'String',\n        },\n        email: {\n          type: 'String',\n        },\n        isActive: {\n          type: 'Boolean',\n        },\n        createdAt: {\n          type: 'Date',\n        },\n        updatedAt: {\n          type: 'Date',\n        },\n        updatedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n        addedBy: {\n          type: 'ObjectId',\n          ref: 'user',\n        },\n      },\n    },\n  ],\n  SQL_TYPES: [\n    {\n      _id: '611e4001b9fee44a6a194032',\n      name: 'Blog',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        title: {\n          type: 'STRING',\n          description: 'Title of blog post',\n        },\n        alternativeHeadline: {\n          type: 'STRING',\n          description: 'Alternative  headline of blog post',\n        },\n        image: {\n          type: 'STRING',\n          description: 'Image of blog',\n        },\n        publishDate: {\n          type: 'STRING',\n          description: 'Publish date of blog',\n        },\n        authorName: {\n          type: 'STRING',\n          description: 'Name of author',\n        },\n        authorImage: {\n          type: 'STRING',\n          description: 'Picture of author',\n        },\n        authorEmail: {\n          type: 'STRING',\n          description: 'Email of author',\n        },\n        publisherName: {\n          type: 'STRING',\n        },\n        publisherUrl: {\n          type: 'STRING',\n        },\n        publisherLogo: {\n          type: 'STRING',\n        },\n        keywords: {\n          type: 'STRING',\n          description: 'Keywords for blog',\n        },\n        articleSection: {\n          type: 'STRING',\n        },\n        articleBody: {\n          type: 'STRING',\n          description: 'Blog artical that you want to display',\n        },\n        description: {\n          type: 'STRING',\n        },\n        slug: {\n          type: 'STRING',\n          description: 'Uniq slug',\n        },\n        url: {\n          type: 'STRING',\n        },\n        isDraft: {\n          type: 'BOOLEAN',\n        },\n        isDeleted: {\n          type: 'BOOLEAN',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n      modelIndexes: [\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '613714331eae3ead86dbad12',\n          name: 'index_title_publishdate',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'title',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n            {\n              attribute: 'publishDate',\n              order: 'DESC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '61371479a83136aa782f201b',\n          name: 'index_title',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'title',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '613714b10f40ef68ba3c6b32',\n          name: 'index_publishdate',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'publishDate',\n              order: 'DESC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      _id: '611e4001b9fee44a6a194033',\n      name: 'Master',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'STRING',\n        },\n        slug: {\n          type: 'STRING',\n        },\n        code: {\n          type: 'STRING',\n        },\n        group: {\n          type: 'STRING',\n          description: 'Group name in which group you want to consider master',\n        },\n        description: {\n          type: 'STRING',\n        },\n        sequence: {\n          type: 'INTEGER',\n        },\n        image: {\n          type: 'STRING',\n        },\n        parentId: {\n          type: 'INTEGER',\n          ref: 'Master',\n          refAttribute: 'id',\n        },\n        parentCode: {\n          type: 'BOOLEAN',\n        },\n        isDefault: {\n          type: 'BOOLEAN',\n          default: false,\n        },\n        isDeleted: {\n          type: 'BOOLEAN',\n          default: false,\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a194034',\n      name: 'Event',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'STRING',\n          description: 'name of event',\n        },\n        description: {\n          type: 'STRING',\n        },\n        address_line1: {\n          type: 'STRING',\n        },\n        address_line2: {\n          type: 'STRING',\n        },\n        address_city: {\n          type: 'STRING',\n        },\n        address_country: {\n          type: 'STRING',\n        },\n        address_state: {\n          type: 'STRING',\n        },\n        address_pincode: {\n          type: 'STRING',\n        },\n        address_lat: {\n          type: 'INTEGER',\n          description: 'latitude of location',\n        },\n        address_lng: {\n          type: 'INTEGER',\n          description: 'longitude  of location',\n        },\n        startDateTime: {\n          type: 'DATE',\n          description: 'start Date event',\n        },\n        endDateTime: {\n          type: 'DATE',\n          description: 'end Date event',\n        },\n        speakers_name: {\n          type: 'STRING',\n        },\n        speakers_image: {\n          type: 'STRING',\n        },\n        speakers_email: {\n          type: 'STRING',\n        },\n        organizer_name: {\n          type: 'STRING',\n        },\n        organizer_image: {\n          type: 'STRING',\n        },\n        organizer_email: {\n          type: 'STRING',\n        },\n        organizer_url: {\n          type: 'STRING',\n        },\n        image: {\n          type: 'STRING',\n        },\n        attachments: {\n          type: 'STRING',\n          decription: 'Event attachemnt',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n      modelIndexes: [\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '61370f828b76c71cf8040dc8',\n          name: 'index_name',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'name',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      _id: '611e4001b9fee44a6a194035',\n      name: 'Appointment_slot',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        startTime: {\n          type: 'DATE',\n          description: 'slot start time',\n        },\n        endTime: {\n          type: 'DATE',\n          description: 'slot end time',\n        },\n        offset: {\n          type: 'INTEGER',\n          description: 'add offset to mange timezone',\n        },\n        appliedFrom: {\n          type: 'DATE',\n          description: 'from when this slot it available',\n        },\n        appliedTo: {\n          type: 'DATE',\n          description: 'to which date this slot it available',\n        },\n        userId: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n          description: 'for user wise slot',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n      modelIndexes: [\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '61370990623bff3277a0c7fc',\n          name: 'index_startTime',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'startTime',\n              order: 'DESC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      _id: '611e4001b9fee44a6a194036',\n      name: 'Appointment_schedule',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        slot: {\n          type: 'INTEGER',\n          ref: 'Appointment_slot',\n          refAttribute: 'id',\n          description: 'reference of slot module',\n        },\n        startTime: {\n          type: 'DATE',\n          description: 'start time of schedule',\n        },\n        endTime: {\n          type: 'DATE',\n          description: 'end time of schedule',\n        },\n        date: {\n          type: 'DATE',\n          description: 'date of schedule',\n        },\n        offset: {\n          type: 'INTEGER',\n          description: 'add offset to mange timezone',\n        },\n        participant: {\n          type: 'STRING',\n          description: 'paricipant in booked appoinment',\n        },\n        host: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n          description: 'host of appoinment who manage the requested schedule',\n        },\n        isCancelled: {\n          type: 'BOOLEAN',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a194037',\n      name: 'ToDo',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'STRING',\n        },\n        description: {\n          type: 'STRING',\n        },\n        date: {\n          type: 'DATE',\n        },\n        dueDate: {\n          type: 'DATE',\n        },\n        isCompleted: {\n          type: 'BOOLEAN',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n      modelIndexes: [\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '613708fa5bf5759565bb892d',\n          name: 'index_date',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'date',\n              order: 'DESC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '61370900debe284f456278e8',\n          name: 'index_dueDate',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'dueDate',\n              order: 'DESC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      _id: '611e4001b9fee44a6a194038',\n      name: 'Chat_group',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'STRING',\n          required: true,\n        },\n        code: {\n          type: 'STRING',\n          required: true,\n        },\n        member: {\n          type: 'STRING',\n        },\n        admin: {\n          type: 'STRING',\n          required: true,\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a194039',\n      name: 'Chat_message',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        message: {\n          type: 'STRING',\n          required: true,\n        },\n        sender: {\n          type: 'STRING',\n          required: true,\n        },\n        recipient: {\n          type: 'STRING',\n          required: true,\n        },\n        groupId: {\n          type: 'INTEGER',\n          ref: 'Chat_group',\n          refAttribute: 'id',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a19403a',\n      name: 'Comment',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        comment: {\n          type: 'STRING',\n        },\n        upvoteCount: {\n          type: 'INTEGER',\n        },\n        downVoteCount: {\n          type: 'INTEGER',\n        },\n        commentTime: {\n          type: 'DATE',\n        },\n        parentItem: {\n          type: 'INTEGER',\n          ref: 'Comment',\n          refAttribute: 'id',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a19403b',\n      name: 'Plan',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        name: {\n          type: 'STRING',\n        },\n        decription: {\n          type: 'STRING',\n        },\n        code: {\n          type: 'STRING',\n        },\n        validityInDays: {\n          type: 'STRING',\n        },\n        minimumUser: {\n          type: 'INTEGER',\n        },\n        maximumUser: {\n          type: 'INTEGER',\n        },\n        perUserAmount: {\n          type: 'INTEGER',\n        },\n        markup: {\n          type: 'INTEGER',\n        },\n        discount: {\n          type: 'INTEGER',\n        },\n        validFrom: {\n          type: 'DATE',\n        },\n        validTo: {\n          type: 'DATE',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a19403c',\n      name: 'Task',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        title: {\n          type: 'STRING',\n        },\n        description: {\n          type: 'STRING',\n        },\n        attachments: {\n          type: 'STRING',\n        },\n        status: {\n          type: 'INTEGER',\n        },\n        date: {\n          type: 'DATE',\n        },\n        dueDate: {\n          type: 'DATE',\n        },\n        completedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        completedAt: {\n          type: 'DATE',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n    {\n      _id: '611e4001b9fee44a6a19403d',\n      name: 'Customer',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        firstName: {\n          type: 'STRING',\n        },\n        lastName: {\n          type: 'STRING',\n        },\n        profile: {\n          type: 'STRING',\n        },\n        contactNumber: {\n          type: 'STRING',\n        },\n        email: {\n          type: 'STRING',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n      hooks: [\n        {\n          code: 'user.name = `${user.firstName}, ${user.lastName}`;',\n          operation: 'save',\n          type: 'pre',\n        },\n      ],\n      modelIndexes: [\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '6137045c0cceab001bced43f',\n          name: 'index_firstName_lastName',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'firstName',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n            {\n              attribute: 'lastName',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '6137076a1766ad45ac715c17',\n          name: 'index_firstName',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'firstName',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n        {\n          isParserRequired: false,\n          isDefault: false,\n          fields: [],\n          _id: '613707765d0031d4a45ae3f1',\n          name: 'index_lastName',\n          indexType: 'BTREE',\n          indexFields: [\n            {\n              attribute: 'lastName',\n              order: 'ASC',\n              length: 10,\n              operator: '',\n              value: '',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      _id: '6124c4837e7d38eaf76492a2',\n      name: 'user',\n      ormType: 2,\n      isActive: true,\n      isDeleted: false,\n      schemaJson: {\n        firstName: {\n          type: 'STRING',\n        },\n        lastName: {\n          type: 'STRING',\n        },\n        name: {\n          type: 'STRING',\n        },\n        username: {\n          type: 'STRING',\n        },\n        password: {\n          type: 'STRING',\n        },\n        email: {\n          type: 'STRING',\n        },\n        isActive: {\n          type: 'BOOLEAN',\n        },\n        createdAt: {\n          type: 'DATE',\n        },\n        updatedAt: {\n          type: 'DATE',\n        },\n        updatedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n        addedBy: {\n          type: 'INTEGER',\n          ref: 'user',\n          refAttribute: 'id',\n        },\n      },\n    },\n  ],\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/ModelList/ModelLibrary/index.js",
    "content": "import React from 'react';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport {\n  Button,\n  Description,\n  ListBoxWrap, ListTitle, NoData, SearchBox, Tag,\n} from '../../../../../components';\nimport { useComponentWillUnmount } from '../../../../hooks';\n\nimport { useLibrary } from '../../LibraryPreview/LibraryProvider';\nimport { DATABASE_TYPE } from '../../../../../constant/Project/applicationStep';\nimport { LibraryModelData } from './LibraryModelData';\n\nconst ModelLibraryList = ({ modelData }) => {\n  const { selectedModel, dispatch } = useLibrary();\n\n  return (\n    <ListBoxWrap\n      variant=\"small\"\n      className=\"flex px-3 items-center relative groupBox\"\n      onClick={() => { dispatch({ type: 'SetSelectionModel', payload: modelData }); }}\n    >\n      <div className={`absolute w-full h-full left-0 pr-3 groupItem ${selectedModel._id === modelData._id ? 'block' : 'hidden'}`}>\n        <div className=\"bg-gray-100 opacity-80 absolute left-0 w-full h-full\" />\n        <div className=\"flex justify-end items-center h-full\">\n          <Button variant=\"outline\" className=\"bg-gray-200\" shape=\"rounded\" size=\"small\">Preview model</Button>\n        </div>\n      </div>\n      <div className=\"flex-grow mr-4 overflow-hidden\">\n        <ListTitle title={modelData.name} />\n        <Description className=\"truncate sm:text-xs\">{modelData.description}</Description>\n      </div>\n      <div className=\"flex-shrink-0 text-center\">\n        <Tag title={`${modelData.schemaJson ? Object.keys(modelData.schemaJson).length : 0} attribute`} size=\"small\" />\n      </div>\n    </ListBoxWrap>\n  );\n};\n\nexport const ModelLibrary = () => {\n  const { dispatch, libraryModelList } = useLibrary();\n  const [modelList, setModelList] = React.useState([]);\n  const { ormType } = useSelector(({ projects }) => ({\n    ormType: projects.currentProjectDetail.applicationList.find((app) => app._id === projects.currentApplicationId)?.stepInput?.ormType ?? DATABASE_TYPE.MONGODB,\n    applicationId: projects.currentApplicationId,\n  }), shallowEqual);\n  const searchRef = React.useRef('');\n  React.useEffect(() => {\n    const listData = [DATABASE_TYPE.SQL, DATABASE_TYPE.POSTGRE_SQL, DATABASE_TYPE.MYSQL].includes(ormType) ? LibraryModelData.SQL_TYPES : LibraryModelData[ormType];\n    dispatch({ type: 'SetLibraryModelList', payload: listData });\n    setModelList(listData);\n  }, []);\n  const onSearch = (search) => {\n    const searchString = search.trim();\n    if (searchRef.current !== searchString) {\n      // to stop multiple api call\n      if (isEmpty(searchString)) {\n        setModelList(libraryModelList);\n        return;\n      }\n      setModelList(libraryModelList.filter(((model) => model.name.toLowerCase().includes(searchString.toLowerCase()))));\n    }\n    searchRef.current = searchString;\n    dispatch({ type: 'ResetSelectionModel' });\n  };\n  useComponentWillUnmount(() => {\n    dispatch({ type: 'ResetSelectionModel' });\n  });\n  return (\n    <>\n\n      <div className=\"flex flex-col h-full\">\n        <div className=\"p-3 flex headTop flex-shrink-0\">\n          <div className=\"flex-grow h-9\">\n            <SearchBox onSearch={onSearch} placeholder=\"Search model\" />\n          </div>\n        </div>\n\n        <div className=\"overflow-auto flex-grow\">\n\n          {!isEmpty(modelList) ? (\n            <>\n              {modelList.map((m) => (<ModelLibraryList key={m.id} modelData={m} />))}\n            </>\n          ) : <NoData imageHeight={150} imgSize={150} className=\"w-full\" smallBox title=\"No model found\" />}\n        </div>\n      </div>\n\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/ModelList/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport ScrollArea from 'react-scrollbar';\nimport { Menu, MenuItem } from 'react-pro-sidebar';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { useLocation } from 'react-router';\nimport { TabCSs } from '../../../../assets/css/tab';\nimport { SidebarList } from '../../../Shared/Layout/Sidebar/SubSidebar';\nimport { LinkTag, Description } from '../../../../components';\nimport { CreateModel } from '../AddModalPopup';\nimport { setCurrentModel } from '../../../../redux/reducers/models';\nimport { useBoolean } from '../../../hooks';\nimport { SidebarMenuListCss } from '../../../../components/SidebarMenuList/sidebarMenuListCss';\nimport {\n  ModelPanel,\n} from '../../../../constant/model';\nimport { useModel } from '../Editor/ModelProvider';\nimport { ModelLibrary } from './ModelLibrary';\nimport DeleteModel from '../DeleteModel';\nimport { getModelDetail } from '../../../../redux/thunks/models';\n\nexport const ModelList = ({ setPanel, modelPanel }) => {\n  const {\n    isError, isJsonError, isChangeInTable, setChangeNextEvent, setNoChangeInTable, setSaveWarning,\n  } = useModel();\n  const [modalStatus, showModal, hideModal] = useBoolean(false);\n  const modelList = useSelector((state) => state.models.modelList);\n  const currentId = useSelector((state) => state.models.currentId);\n  const currentModel = React.useMemo(() => modelList.find((model) => model._id === currentId), [currentId, modelList]);\n  const dispatch = useDispatch();\n  const location = useLocation();\n\n  const openCreateModel = () => {\n    if (isChangeInTable) {\n      setChangeNextEvent(() => {\n        setNoChangeInTable();\n        showModal();\n      });\n      setSaveWarning();\n      return;\n    }\n\n    showModal();\n  };\n  React.useEffect(() => {\n    if (location.state?.isOpenPopup) {\n      // when dashboard redirect open popup\n      openCreateModel();\n    }\n  }, [location.state?.isOpenPopup]);\n  return (\n    <>\n      <SidebarList\n        {...(ModelPanel.CUSTOM.name === modelPanel && { isAddButton: true })}\n        sidebarClass=\"modelList z-10 xxl:w-2/12\"\n        style={{ top: '0', width: '16rem' }}\n        title=\"Models\"\n        addClick={openCreateModel}\n        tooltip=\"Add model\"\n        Scroll\n      >\n\n        <Tabs selectedIndex={modelPanel === ModelPanel.CUSTOM.name ? ModelPanel.CUSTOM.tabIndex : ModelPanel.LIBRARY.tabIndex} className=\"flex-grow flex flex-col h-0\" selectedTabPanelClassName=\"h-0 flex-grow\" selectedTabClassName={TabCSs.selectTab}>\n          <TabList className={`${TabCSs.tabHead} modelListTab`}>\n            <Tab onClick={() => { setPanel(ModelPanel.CUSTOM.name); }} className={TabCSs.tabSmallTitle}>Custom</Tab>\n            <Tab\n              onClick={() => {\n                if (isChangeInTable) {\n                  setChangeNextEvent(() => {\n                    setPanel(ModelPanel.LIBRARY.name);\n                    setNoChangeInTable();\n                  });\n                  setSaveWarning();\n                  return;\n                }\n                setPanel(ModelPanel.LIBRARY.name);\n              }}\n              className={TabCSs.tabSmallTitle}\n            >\n              Library\n\n            </Tab>\n          </TabList>\n          <TabPanel>\n            <div className=\"overflow-auto h-full\">\n              <ScrollArea\n                speed={0.8}\n                className=\"area h-full justify-between\"\n                contentClassName=\"w-full\"\n                smoothScrolling\n              >\n                {modelList.length ? (\n                  <Menu iconShape=\"square\" className=\"p-2 cursor-text\">\n                    {modelList.map((d) => (\n                      <MenuItem\n                        key={`model${d._id}`}\n                        className={`${SidebarMenuListCss.menuList} sm:py-0 relative ${currentId === d._id && (!!isError(d.name) || (isJsonError && currentModel?.name === d.name)) ? 'bg-secondary-red border-secondary-red' : ''}  ${currentId === d._id && SidebarMenuListCss.menuActive}`}\n                      >\n                        <div\n                          className=\"flex items-center justify-between w-full py-1 pr-8\"\n                          onClick={() => {\n                            if (isChangeInTable) {\n                              setChangeNextEvent(() => {\n                                dispatch(setCurrentModel({ currentId: d._id }));\n                                dispatch(getModelDetail(d._id));\n                                setNoChangeInTable();\n                              });\n                              setSaveWarning();\n                              return;\n                            }\n\n                            if (d._id === currentId) return;\n                            dispatch(setCurrentModel({ currentId: d._id }));\n                            dispatch(getModelDetail(d._id));\n                          }}\n                        >\n                          <span className={`text-primary-text text-sm leading-5 truncate ${(!!isError(d.name) || (isJsonError && currentModel?.name === d.name)) ? 'text-secondary-red' : ''} ${currentId === d._id && 'text-defaultWhite'}`}>\n                            {d.name}\n                          </span>\n                        </div>\n                        {!d?.isDefault && <DeleteModel isDeleteWhiteIcon={currentId === d._id} className=\"absolute right-2 py-2 top-0 bottom-0 m-auto\" currentId={d._id} />}\n                      </MenuItem>\n                    ))}\n                  </Menu>\n                )\n                  : (\n                    <div className=\"flex justify-center\">\n                      <div className=\"text-center py-5 px-2\">\n                        <h4 className=\"text-lg text-primary-text mb-1\">Create New Model</h4>\n                        <Description>\n                          {/* No model is available in this application. */}\n                          <LinkTag onClick={openCreateModel}> Click here</LinkTag>\n                          to add a model in your application.\n                        </Description>\n                      </div>\n                    </div>\n                  )}\n              </ScrollArea>\n            </div>\n          </TabPanel>\n          <TabPanel>\n            <ModelLibrary />\n          </TabPanel>\n        </Tabs>\n        <CreateModel\n          handleCancel={hideModal}\n          closeModal={hideModal}\n          isOpen={modalStatus}\n        />\n      </SidebarList>\n\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Modal/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\n// import Layout from '../../Shared/Layout/index';\nimport { useHistory } from 'react-router';\nimport { isEmpty } from 'lodash';\nimport { ModelList } from './ModelList';\nimport Editor, { NoModelData } from './Editor';\nimport {\n  BoxLayout, Loader, NoData, StepFooter,\n} from '../../../components';\nimport { listModels } from '../../../redux/thunks/models';\nimport { ModelPanel } from '../../../constant/model';\nimport { ModelProvider } from './Editor/ModelProvider';\nimport LayoutStepUrl from '../../Shared/LayoutStepUrl';\nimport { StepHeader } from '../../Shared/Layout/StepHeader';\nimport { encryptStorage } from '../../../utils/localStorage';\nimport { LAYOUT_STEP_MODULE_NAME, RedirectUrl } from '../../../constant/Nodecrud';\nimport { useBoolean } from '../../../components/hooks';\nimport { useToastNotifications } from '../../hooks';\nimport { LibraryPreview } from './LibraryPreview';\nimport { LibraryProvider } from './LibraryPreview/LibraryProvider';\nimport { EditorProvider } from './Editor/EditorProvider';\n\n// import { LibraryDashboard } from './LibraryPreview/LibraryDashboard';\n// const Editor = React.lazy(() => new Promise((resolve) => setTimeout(() => resolve(import('./Editor')), 3000)));\nconst ModalFooter = ({ saveRef, loaderRef, listFetching }) => {\n  // loaderRef=to setloader async and await not work in delete loader\n  const history = useHistory();\n  const [isLoading, , , setLoader] = useBoolean(false);\n  const buttonRef = React.useRef('');\n  const { addErrorToast } = useToastNotifications();\n  const { modelList } = useSelector(({ models }) => ({ modelList: models.modelList, currentModel: models.currentId }));\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  React.useEffect(() => {\n    if (!isLoading)buttonRef.current = 'save';\n  }, [isLoading]);\n  const handleSave = (buttonText) => {\n    buttonRef.current = buttonText;\n    if (isEmpty(modelList)) {\n      addErrorToast(NoModelData);\n      return;\n    }\n    saveRef.current?.handleSave({ isRedirect: buttonRef.current === 'next' });\n  };\n  React.useImperativeHandle(loaderRef, () => ({ setLoader }));\n  return (\n    <StepFooter\n      backClick={() => {\n        history.push(RedirectUrl[currentApplicationCode].model.previousUrl);\n      }}\n      isSaveDisable={listFetching}\n      isNextDisable={listFetching}\n      nextClick={() => {\n        handleSave('next');\n      }}\n      nextLoading={buttonRef.current === 'next' && isLoading}\n      saveLoading={buttonRef.current === 'save' && isLoading}\n      saveClick={() => {\n        handleSave('save');\n      }}\n      Back=\"Previous\"\n      Next=\"Save & Next\"\n      saveText=\"Save\"\n    />\n  );\n};\nexport default function Modal(props) {\n  const saveRef = React.useRef();\n  const loaderRef = React.useRef();\n\n  const applicationId = useSelector(\n    (state) => state.projects.currentApplicationId,\n  );\n  const dispatch = useDispatch();\n  const currentId = useSelector((state) => state.models.currentId);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const listFetching = useSelector((state) => state.models.listFetching);\n  const [modelPanel, setPanel] = React.useState(ModelPanel.CUSTOM.name);\n\n  React.useEffect(() => {\n    dispatch(listModels({ applicationId }));\n  }, []);\n  React.useEffect(() => () => {\n    // Remove\n    // to maintain remove toggle from sidebar when crud in url\n    !window.location.pathname.includes('crud') && encryptStorage.remove('sidebarToggle');\n  }, []);\n  const EditorWrap = () => (\n    <Editor\n      saveRef={saveRef}\n      loaderRef={loaderRef}\n      currentId={currentId}\n    />\n  );\n\n  return (\n    <div className=\"flex flex-col h-screen\">\n      {/* // Remove */}\n      <StepHeader backTitle=\"Back to screen\" headTitle=\"CRUD\" link={RedirectUrl[currentApplicationCode].model.backScreenUrl} />\n      <LayoutStepUrl isOpenBigLayout={false} isBuildShow moduleName={LAYOUT_STEP_MODULE_NAME[currentApplicationCode]}>\n        {/* w-sidebarRight */}\n        {listFetching && <Loader style={{ minHeight: '100%' }} />}\n        {!listFetching && (\n          <ModelProvider currentId={currentId}>\n            <LibraryProvider>\n              <div className=\"flex h-0 flex-row flex-grow\">\n                <ModelList\n                  setPanel={setPanel}\n                  modelPanel={modelPanel}\n                  {...props}\n                />\n                <BoxLayout variant=\"subRight\" className=\"sm:h-auto\" style={{ width: 'calc(100% - 16rem)' }}>\n                  <div className=\"w-full flex flex-col\">\n                    {!currentId && modelPanel === ModelPanel.CUSTOM.name ? (\n                      <div style={{ minHeight: 'calc(100vh - 215px)' }} className=\"flex items-center h-full\">\n                        <NoData\n                          title=\"No model found\"\n                        />\n                      </div>\n                    ) : (\n                      <React.Suspense fallback={<Loader />}>\n                        {modelPanel === ModelPanel.CUSTOM.name ? <EditorWrap /> : (\n                          <EditorProvider>\n                            <LibraryPreview setPanel={setPanel} />\n                          </EditorProvider>\n                        ) }\n                      </React.Suspense>\n                    )}\n                  </div>\n                </BoxLayout>\n              </div>\n            </LibraryProvider>\n            {/* // Remove */}\n            {modelPanel === ModelPanel.CUSTOM.name && <ModalFooter saveRef={saveRef} loaderRef={loaderRef} />}\n          </ModelProvider>\n        )}\n      </LayoutStepUrl>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/Header.js",
    "content": "import { isEmpty } from 'lodash';\nimport React from 'react';\nimport {\n  Button,\n  Heading,\n} from '../../../components';\n\nconst Header = (props) => {\n  const { onCancel, permissions } = props;\n  return (\n    <div className=\"flex justify-between py-3 px-3 items-center  headTop pb-5\">\n      <div className=\"w-6/12\">\n        <Heading variant=\"h5\">Model permission</Heading>\n      </div>\n      { !isEmpty(permissions) && (\n      <div className=\"flex justify-end w-6/12\">\n        <Button\n          size=\"medium\"\n          variant=\"secondary\"\n          shape=\"rounded\"\n          onClick={onCancel}\n        >\n          Reset\n        </Button>\n\n      </div>\n      )}\n    </div>\n  );\n};\nexport default React.memo(Header);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/Permission.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 5)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          width=\"100%\"\n          height=\"80\"\n          // viewBox=\"0 0 100% 80\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n          <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n\n          <rect x=\"27%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"27%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n\n          <rect x=\"55%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"55%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n\n          <rect x=\"80%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"80%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/PermissionHelperFunctions.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { cloneDeep, uniq } from 'lodash';\nimport { CRUD, CRUD_OPERATIONS } from '../../../constant/permission';\n\nexport function prepareSettingData(settings, platform, operation, permission) {\n  settings[platform][operation] = {};\n  settings[platform][operation].isAuth = permission?.schemaJson?.[platform]?.[CRUD.isAuth];\n  settings[platform][operation].selected = permission?.schemaJson?.[platform]?.[operation];\n  settings[platform][operation].policy = permission?.schemaJson?.[platform]?.[CRUD.POLICY];\n  settings[platform][operation].attributes = [];\n}\n\nexport const isCrud = (action) => [CRUD.C, CRUD.R, CRUD.U, CRUD.D, CRUD.BC, CRUD.BU, CRUD.HD, CRUD.ALL].includes(action);\n\nexport const getDeviceOperation = (deviceOperations) => ({\n  [CRUD.C]: deviceOperations.includes(CRUD.C),\n  [CRUD.R]: deviceOperations.includes(CRUD.R),\n  [CRUD.U]: deviceOperations.includes(CRUD.U),\n  [CRUD.D]: deviceOperations.includes(CRUD.D),\n  [CRUD.BC]: deviceOperations.includes(CRUD.BC),\n  [CRUD.BU]: deviceOperations.includes(CRUD.BU),\n  [CRUD.HD]: deviceOperations.includes(CRUD.HD),\n});\n\nexport const isAnyAction = (deviceObj) => {\n  // marked checked all for actions\n  const deviceType = cloneDeep(deviceObj);\n  delete deviceType.ALL;\n  const allCrud = {\n    [CRUD.C]: deviceType[CRUD.C],\n    [CRUD.R]: deviceType[CRUD.R],\n    [CRUD.U]: deviceType[CRUD.U],\n    [CRUD.D]: deviceType[CRUD.D],\n    [CRUD.BC]: deviceType[CRUD.BC],\n    [CRUD.BU]: deviceType[CRUD.BU],\n    [CRUD.HD]: deviceType[CRUD.HD],\n  };\n  const isAll = Object.keys(allCrud)?.some((val) => deviceType[val]);\n  return isAll;\n};\n\nexport const isCheckedAll = (deviceObj) => {\n  // marked checked all for actions\n  const deviceType = cloneDeep(deviceObj);\n  delete deviceType.ALL;\n  const allCrud = {\n    [CRUD.C]: deviceType[CRUD.C],\n    [CRUD.R]: deviceType[CRUD.R],\n    [CRUD.U]: deviceType[CRUD.U],\n    [CRUD.D]: deviceType[CRUD.D],\n    [CRUD.BC]: deviceType[CRUD.BC],\n    [CRUD.BU]: deviceType[CRUD.BU],\n    [CRUD.HD]: deviceType[CRUD.HD],\n  };\n  const isAll = Object.keys(allCrud)?.every((val) => deviceType[val]);\n  return isAll;\n};\n\nexport const isCheckedAllModel = (schema) => Object.keys(schema)?.every((val) => schema[val].ALL);\n\nexport const isCheckedAllDevice = (newPerm, loginAccess) => {\n  // to check all device (Admin ALL)\n  const deviceObject = {};\n  loginAccess?.forEach((platform) => {\n    deviceObject[platform] = newPerm?.every((p) => p.schemaJson[platform]?.ALL);\n  });\n  return deviceObject;\n};\n\nexport const prepareData = (currentPermissions, applicationLoginAccess, setDeviceData) => {\n  const newPermissions = currentPermissions?.map((permission) => {\n    Object.keys(permission.schemaJson)?.map((platform) => {\n      if (applicationLoginAccess?.includes(platform)) {\n        const deviceOperations = permission.schemaJson[platform];\n        let deviceObj = {};\n        if (Array.isArray(deviceOperations)) {\n          deviceObj = getDeviceOperation(deviceOperations);\n          deviceObj[CRUD.ALL] = !!isCheckedAll(deviceObj); // ALL actions\n          deviceOperations.forEach((action) => {\n            if (typeof action === 'object') {\n              deviceObj[CRUD.isAuth] = action[CRUD.isAuth];\n              deviceObj[CRUD.POLICY] = action[CRUD.isAuth] ? uniq(action[CRUD.POLICY]?.concat('auth') || ['auth']) : uniq(action[CRUD.POLICY]?.filter((policy) => policy !== 'auth') || []);\n            }\n          });\n          permission.schemaJson[platform] = deviceObj; // converted array to obj type\n        }\n        return platform;\n      }\n      delete permission.schemaJson[platform];\n      return platform;\n    });\n    permission.isAllModal = isCheckedAllModel(permission.schemaJson); // ALL model\n    return permission;\n  });\n  const checkedAllDevice = isCheckedAllDevice(newPermissions, applicationLoginAccess);// ALL device\n  setDeviceData(checkedAllDevice);\n  return newPermissions;\n};\n\nexport const getSettingOperationsType = (operationType) => ((operationType === 'D') ? 'Soft Delete' : CRUD_OPERATIONS[operationType]);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/PermissionItem.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\n// import ReactTooltip from 'react-tooltip';\nimport { cloneDeep, isEmpty } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  ListTitle,\n  Checkbox,\n  Select,\n  IconBox,\n} from '../../../components';\nimport { CRUD } from '../../../constant/permission';\nimport { SETTING_ACTION_TYPES, useSettings } from './PermissionSettingProvider';\n\nfunction PermissionItem(props) {\n  const {\n    title, permissionSet, onChange, permission, policyLists, handleShow, permissionSettingRef, platformTypeRef, isAnyAction,\n  } = props;\n\n  const { dispatch } = useSettings();\n\n  const handleChange = (val, action, type) => {\n    // to update permission Array @val: checkbox value,@action: any from CRUD, @type: device type\n    onChange(val, {\n      action,\n      permission,\n      type,\n    });\n  };\n\n  const ActionCheckbox = (propsVal) => {\n    const {\n      children, operationType, platformType, disabled = false,\n    } = propsVal;\n    return (\n      <Checkbox\n        className=\"text-center\"\n        checked={!!permissionSet[platformType][operationType]}\n        disabled={disabled}\n        onChange={(val) => {\n          if (operationType === CRUD.isAuth) {\n            const policiesList = permissionSet[platformType][CRUD.POLICY];\n            if (val) {\n              policiesList?.unshift('auth');\n              handleChange(policiesList, CRUD.POLICY, platformType);\n            } else {\n              handleChange(policiesList?.filter((policy) => policy !== 'auth'), CRUD.POLICY, platformType);\n            }\n          }\n          handleChange(val, operationType, platformType);\n        }}\n      >\n        {children}\n      </Checkbox>\n    );\n  };\n\n  const ModalCheckbox = (propsVal) => {\n    const { children } = propsVal;\n    return (\n      <Checkbox\n        className=\"text-center\"\n        checked={!!permission.isAllModal}\n        onChange={(val) => handleChange(val, CRUD.ALL_MODEL)}\n      >\n        {children}\n      </Checkbox>\n    );\n  };\n\n  const getSettings = (settingData, platform) => {\n    const editSettingData = {};\n    !isEmpty(settingData) && settingData?.forEach((setting) => {\n      const settingObj = {};\n      settingObj.platformType = platform;\n      settingObj.operation = setting;\n      settingObj.selected = permission?.schemaJson?.[platform]?.[setting];\n      settingObj.policy = !isEmpty(permission?.additionalJson?.additionalSetting?.[platform]?.[setting]?.policy) ? (permission?.schemaJson?.[platform]?.[CRUD.isAuth] ? permission?.additionalJson?.additionalSetting?.[platform]?.[setting]?.policy?.concat('auth') : permission?.additionalJson?.additionalSetting?.[platform]?.[setting]?.policy?.filter((policy) => policy !== 'auth')) : permission?.schemaJson?.[platform]?.[CRUD.POLICY]; // Add newly selected policy in settings if no policy is selected for that setting // Add/Remove 'auth' policy in additionalSetting object based on 'isAuth' value\n      settingObj.isAuth = permission?.schemaJson?.[platform]?.[CRUD.isAuth];\n      settingObj.attributes = cloneDeep(permission?.additionalJson?.additionalSetting?.[platform]?.[setting]?.attributes);\n      settingObj.model = permission?.schemaId?._id;\n      editSettingData[setting] = settingObj;\n    });\n    dispatch({ type: SETTING_ACTION_TYPES.EDIT_DATA, payload: editSettingData });\n  };\n\n  return (\n    <tr variant=\"normal\" className=\"border-t-1 border-gray-200 \">\n      <td className=\"sticky -left-3 z-1 bg-gray-black pl-5 cursor-pointer py-5 px-1 modelPermissionLeft\">\n        <ListTitle titleClass=\"truncate\" title={title} />\n        <div className=\"mr-2 flex items-center\">\n          <ModalCheckbox value={CRUD.ALL} />\n          <div className=\"text-sm text-primary-text\">All platform permission</div>\n        </div>\n      </td>\n      <td className=\"permissionPage\">\n        <table>\n          <tr>\n            {permissionSet\n            && Object.keys(permissionSet).sort().map((platform) => (\n              <td className=\"cursor-pointer py-5 px-1 pr-8 permissionTableList\" key={platform}>\n                <div className=\"flex justify-between items-center\">\n                  <div className=\"flex justify-start\">\n                    <div className=\"mr-2\">\n                      <ActionCheckbox platformType={platform} operationType={CRUD.ALL}>\n                        All\n                      </ActionCheckbox>\n                    </div>\n                    <div className=\"mr-2\">\n                      <ActionCheckbox platformType={platform} operationType={CRUD.C}>\n                        Create\n                      </ActionCheckbox>\n                    </div>\n                    <div className=\"mr-2 text-center\">\n                      <ActionCheckbox platformType={platform} operationType={CRUD.R}>\n                        View\n                      </ActionCheckbox>\n                    </div>\n                    <div className=\"mr-2\">\n                      <ActionCheckbox platformType={platform} operationType={CRUD.U}>\n                        Update\n                      </ActionCheckbox>\n                    </div>\n                    <div className=\"mr-2\">\n                      <ActionCheckbox platformType={platform} operationType={CRUD.D}>\n                        Delete\n                      </ActionCheckbox>\n                    </div>\n                  </div>\n                  <IconBox\n                    onClick={() => {\n                      permissionSettingRef.current = permission;\n                      platformTypeRef.current = platform;\n                      const settingData = !isEmpty(permission?.additionalJson?.additionalSetting?.[platform]) ? Object.keys(permission?.additionalJson?.additionalSetting?.[platform]) : {};\n                      getSettings(settingData, platform);\n                      handleShow();\n                    }}\n                    disabled={!isAnyAction(permission?.schemaJson?.[platform])}\n                    size=\"medium\"\n                    tooltip=\"Setting\"\n                    shape=\"rounded\"\n                    variant=\"primary\"\n                    icon={<Icons.Setting color=\"#ffffff\" />}\n                  />\n                </div>\n                <div className=\"w-96 mt-2.5 p-2 border-1 border-gray-200 rounded-3 flex justify-start items-center\">\n                  <div className=\"text-center flex-grow-0 flex items-center mr-3\">\n                    <ActionCheckbox platformType={platform} operationType={CRUD.isAuth} disabled={!isAnyAction(permission?.schemaJson?.[platform])} />\n                    <div className=\"text-sm text-primary-text\">Auth</div>\n                  </div>\n                  <div className=\"flex-grow w-80\">\n                    <Select\n                      name=\"policy\"\n                      defaultValue={permissionSet[platform][CRUD.POLICY]}\n                      disabled={!isAnyAction(permission?.schemaJson?.[platform])}\n                      value={permissionSet[platform][CRUD.POLICY]}\n                      placeholder=\"Select middleware\"\n                      options={policyLists}\n                      isMulti\n                      valueKey=\"fileName\"\n                      labelKey=\"fileName\"\n                      onChange={(value) => {\n                        if (value?.includes('auth')) {\n                          handleChange(true, CRUD.isAuth, platform);\n                        } else {\n                          handleChange(false, CRUD.isAuth, platform);\n                        }\n                        handleChange(value, CRUD.POLICY, platform);\n                      }}\n                    />\n                  </div>\n                </div>\n\n              </td>\n            ))}\n          </tr>\n        </table>\n      </td>\n    </tr>\n  );\n}\nexport default PermissionItem;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/PermissionSettingProvider.js",
    "content": "import React from 'react';\nimport { isEmpty } from 'lodash';\n\nexport const PermissionSettingContext = React.createContext();\n\nexport const SETTING_ACTION_TYPES = {\n  MUTATE_EDIT: 'mutateEditSetting',\n  EDIT: 'editSetting',\n  EDIT_DATA: 'editSettingData',\n  RESET_EDIT_DATA: 'resetEditSettingData',\n};\n\nfunction permissionSettingReducer(state, { type, payload }) {\n  switch (type) {\n    case SETTING_ACTION_TYPES.MUTATE_EDIT: {\n      return { ...state, editSettingData: payload || {} };\n    }\n    case SETTING_ACTION_TYPES.EDIT: {\n      const { editSettingData } = state;\n      if (isEmpty(Object.keys(editSettingData))) {\n        editSettingData[payload.operation] = payload;\n      }\n      Object.keys(editSettingData)?.forEach((operation) => {\n        if (operation === payload?.operation) {\n          editSettingData[operation] = payload;\n        } else {\n          editSettingData[payload.operation] = payload;\n        }\n      });\n      return { ...state, editSettingData };\n    }\n    case SETTING_ACTION_TYPES.EDIT_DATA: {\n      return { ...state, editSettingData: payload };\n    }\n    case SETTING_ACTION_TYPES.RESET_EDIT_DATA: {\n      return { ...state, editSettingData: {} };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\n\nconst PermissionSettingProvider = ({ children }) => {\n  const [stateData, dispatch] = React.useReducer(permissionSettingReducer, { editSettingData: {} });\n  const value = {\n    editSettingData: stateData.editSettingData,\n    dispatch,\n  };\n  return <PermissionSettingContext.Provider value={value}>{children}</PermissionSettingContext.Provider>;\n};\n\nfunction useSettings() {\n  const context = React.useContext(PermissionSettingContext);\n  if (context === undefined) {\n    throw new Error('useSettings must be used within a PermissionSettingProvider');\n  }\n  return context;\n}\n\nexport { PermissionSettingProvider, useSettings };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/Permissions.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable no-param-reassign */\nimport React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  capitalize, isEmpty, sortBy,\n} from 'lodash';\nimport { CRUD, DEVICE_TYPE_NAME, LINKED_CRUD_OPERATION } from '../../../constant/permission';\nimport { Checkbox } from '../../../components';\nimport PermissionItem from './PermissionItem';\nimport useToastNotifications from '../../hooks/useToastNotifications';\nimport { Setting } from './Setting';\nimport { SETTING_ACTION_TYPES, useSettings } from './PermissionSettingProvider';\nimport {\n  isAnyAction, isCheckedAll, isCheckedAllModel, isCrud, isCheckedAllDevice,\n} from './PermissionHelperFunctions';\n\nconst Permission = React.forwardRef(({ ...props }, ref) => {\n  const [isOpen, setIsOpen] = useState(false);\n  const [permissions, setPermissions] = React.useState([]);\n  const [deviceData, setDeviceData] = React.useState({});\n  const permissionSettingRef = React.useRef(null);\n  const platformTypeRef = React.useRef(null);\n\n  const { editSettingData, dispatch } = useSettings();\n\n  React.useImperativeHandle(ref, () => ({ permissions, editSettingData, dispatch }));\n  const handleShow = () => {\n    setIsOpen(true);\n  };\n  const handleClose = () => {\n    dispatch({ type: SETTING_ACTION_TYPES.RESET_EDIT_DATA });\n    setIsOpen(false);\n  };\n\n  const { addErrorToast } = useToastNotifications();\n\n  React.useEffect(() => {\n    if (props?.permissions) {\n      setPermissions(props?.permissions);\n      setDeviceData(props?.deviceData);\n    }\n  }, [props?.permissions]);\n\n  const handleChange = (value, options) => {\n    const { action, type, permission } = options;\n    const newPermissions = [...permissions];\n    newPermissions?.map((perm) => {\n      const newPermission = perm;\n\n      function mapSchemaJson() {\n        Object.keys(newPermission.schemaJson)?.map((plat) => {\n          const platform = plat;\n\n          function uncheckAuth() {\n            if (!isAnyAction(newPermission.schemaJson[platform])) {\n              // uncheck AUTH selection if any action is not selected\n              newPermission.schemaJson[platform].isAuth = false;\n              newPermission.schemaJson[platform][CRUD.POLICY] = newPermission.schemaJson[platform][CRUD.POLICY]?.filter((policy) => policy !== 'auth');\n              if ((action === CRUD.isAuth) && value) {\n                addErrorToast('Please select model actions first.');\n              }\n            }\n          }\n\n          function mapDeviceType() {\n            Object.keys(newPermission.schemaJson[platform])?.map((act) => {\n              if (isCrud(act)) {\n                newPermission.schemaJson[platform][act] = value;\n              }\n              return act;\n            });\n            uncheckAuth();\n          }\n\n          if (type) {\n            if (platform === type) {\n              if (action === CRUD.ALL || action === CRUD.ALL_DEVICE) {\n                // on mark 'ALL' actions: all actions will be checked/unchecked\n                // on mark 'ALL' Devices: all model permission of device will be checked/unchecked\n                mapDeviceType();\n              } else {\n                // other than ALL actions\n                if (action === CRUD.POLICY) {\n                  newPermission.schemaJson[platform][action] = isEmpty(value?.filter((policy) => props?.policyLists?.find((policyData) => policyData?.fileName === policy))) ? [] : value?.filter((policy) => props?.policyLists?.find((policyData) => policyData?.fileName === policy)); // to remove inactive policies\n                } else if (!value && LINKED_CRUD_OPERATION[action]) { // to remove Linked Operations from schemaJson\n                  LINKED_CRUD_OPERATION[action]?.forEach((operation) => {\n                    newPermission.schemaJson[platform][operation] = value;\n                  });\n                } else {\n                  newPermission.schemaJson[platform][action] = value;\n                }\n                newPermission.schemaJson[platform].ALL = !!isCheckedAll(newPermission.schemaJson[platform]);\n                uncheckAuth();\n              }\n            }\n          } else if (action === CRUD.ALL_MODEL) {\n            // on Mark 'ALL' Model: update all model actions\n            mapDeviceType();\n          }\n          return platform;\n        });\n      }\n\n      if (newPermission._id === permission?._id || action === CRUD.ALL_DEVICE) {\n        mapSchemaJson();\n        newPermission.isAllModal = isCheckedAllModel(newPermission.schemaJson); // ALL model permission\n      }\n      return newPermission;\n    });\n    const checkedAllDevice = isCheckedAllDevice(newPermissions, props?.applicationLoginAccess);\n    setDeviceData(checkedAllDevice);\n    setPermissions(newPermissions);\n  };\n\n  const AllDeviceCheckbox = (options) => {\n    const { children, value } = options;\n    return (\n      <Checkbox\n        className=\"text-center\"\n        checked={deviceData[value]}\n        onChange={(val) => {\n          handleChange(val, {\n            action: 'ALL_DEVICE',\n            type: value,\n          });\n        }}\n      >\n        {children}\n      </Checkbox>\n    );\n  };\n\n  return (\n    <>\n      {\n        !isEmpty(permissions)\n        && (\n          <table className=\"smallCheckbox modelPermissionTable\">\n            <tr className=\"sticky -left-3 z-10 bg-gray-black top-0\">\n              <td className=\"sticky -left-3 z-1 bg-gray-black pl-5 pr-10 w-96 modelPermissionLeft\">\n                <div className=\"flex justify-between items-center\">\n                  <div className=\"\">Model list</div>\n                  <div />\n                </div>\n              </td>\n              <td className=\"pb-3\">\n                <table>\n                  <tr>\n                    {props?.applicationLoginAccess?.sort()?.map((type) => (\n                      <td className=\"text-left pr-10 permissionTableList\" key={type}>\n                        <div className=\"flex justify-between\">\n                          {capitalize((DEVICE_TYPE_NAME[type?.toUpperCase()] ?? type) ?? '')}\n                          <AllDeviceCheckbox value={type}>\n                            All\n                          </AllDeviceCheckbox>\n                        </div>\n                      </td>\n                    ))}\n                  </tr>\n                </table>\n              </td>\n            </tr>\n            {sortBy(permissions, ['schemaId.name'])?.map((permission) => (\n              <PermissionItem\n                handleShow={handleShow}\n                title={permission?.schemaId?.name}\n                permissionSet={permission?.schemaJson}\n                permission={permission}\n                policyLists={props?.policyLists}\n                onChange={handleChange}\n                permissionSettingRef={permissionSettingRef}\n                platformTypeRef={platformTypeRef}\n                isAnyAction={isAnyAction}\n                key={permission?.schemaId?._id}\n              />\n            ))}\n          </table>\n        )\n      }\n\n      {isOpen && (\n        <Setting\n          isOpen={isOpen}\n          onClose={handleClose}\n          onDrawerClose={handleClose}\n          permissionData={permissionSettingRef?.current}\n          platformType={platformTypeRef?.current}\n          policyList={props?.policyLists}\n          handleSave={props?.handleSave}\n          onChange={handleChange}\n        />\n      )}\n    </>\n  );\n});\nPermission.displayName = 'Permission';\nexport default Permission;\nPermission.propTypes = {\n  /**\n   * Permission array\n   */\n  permissions: PropTypes.arrayOf.isRequired,\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/Setting/SettingDetail.js",
    "content": "import React from 'react';\nimport {\n  cloneDeep, isEmpty, lowerCase,\n} from 'lodash';\nimport { useSelector } from 'react-redux';\nimport {\n  Checkbox, Select, SelectTree, TagGroup,\n} from '../../../../components';\nimport { CRUD } from '../../../../constant/permission';\nimport { SETTING_ACTION_TYPES, useSettings } from '../PermissionSettingProvider';\nimport { defaultAttributes } from '../../../../components/SelectTree';\nimport { ORM_TYPE } from '../../../../constant/Project/applicationStep';\nimport { getSettingOperationsType } from '../PermissionHelperFunctions';\n\nexport const SettingDetail = ({\n  policyList, permissionData, platformType, onChange, linkedOperation,\n}) => {\n  const modelList = useSelector((state) => state.models.modelList);\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const [selectedPolicies, setSelectedPolicies] = React.useState({});\n  const [selectedAttributes, setSelectedAttributes] = React.useState({});\n\n  const { editSettingData, dispatch } = useSettings();\n\n  React.useEffect(() => {\n    const policies = {};\n    const attributes = {};\n    linkedOperation?.forEach((operationType) => {\n      policies[operationType] = editSettingData?.[operationType]?.policy || permissionData?.schemaJson?.[platformType]?.[CRUD.POLICY];\n      attributes[operationType] = editSettingData?.[operationType]?.attributes || [];\n    });\n    setSelectedPolicies(policies);\n    setSelectedAttributes(attributes);\n  }, [linkedOperation]);\n\n  const handlePolicySelection = (policies, operationType) => {\n    const updatedPolicies = cloneDeep(selectedPolicies);\n    updatedPolicies[operationType] = policies;\n    setSelectedPolicies(updatedPolicies);\n    dispatch({\n      type: SETTING_ACTION_TYPES.EDIT,\n      payload: {\n        platformType,\n        operation: operationType,\n        selected: true,\n        policy: policies || [],\n        isAuth: permissionData?.schemaJson?.[platformType]?.[CRUD.isAuth],\n        attributes: selectedAttributes[operationType],\n        model: permissionData?.schemaId?._id,\n      },\n    });\n  };\n\n  const handleAttributeSelection = (allSelectedNode, operationType) => {\n    const updatedAttributes = cloneDeep(selectedAttributes);\n    updatedAttributes[operationType] = allSelectedNode?.map((node) => node?.fullName);\n    setSelectedAttributes(updatedAttributes);\n    dispatch({\n      type: SETTING_ACTION_TYPES.EDIT,\n      payload: {\n        platformType,\n        operation: operationType,\n        selected: true,\n        policy: !isEmpty(selectedPolicies[operationType]) ? selectedPolicies[operationType] : permissionData?.schemaJson?.[platformType]?.[CRUD.POLICY],\n        isAuth: permissionData?.schemaJson?.[platformType]?.[CRUD.isAuth],\n        attributes: allSelectedNode?.map((node) => node?.fullName),\n        model: permissionData?.schemaId?._id,\n      },\n    });\n  };\n\n  const handleSelectOperation = (val, operationType, platform) => {\n    if (val === false) {\n      delete editSettingData[operationType];\n      dispatch({ type: SETTING_ACTION_TYPES.MUTATE_EDIT, payload: editSettingData });\n    } else {\n      dispatch({\n        type: SETTING_ACTION_TYPES.EDIT,\n        payload: {\n          platformType: platform,\n          operation: operationType,\n          selected: val,\n          policy: selectedPolicies[operationType] || permissionData?.schemaJson?.[platformType]?.[CRUD.POLICY],\n          isAuth: permissionData?.schemaJson?.[platformType]?.[CRUD.isAuth],\n          attributes: selectedAttributes[operationType] || [],\n          model: permissionData?.schemaId?._id,\n        },\n      });\n    }\n  };\n\n  const handleChange = (val, action, type) => {\n    // to update permission Array @val: checkbox value,@action: any from CRUD, @type: device type\n    onChange(val, {\n      action,\n      permission: permissionData,\n      type,\n    });\n  };\n\n  return (\n    <>\n      {\n      linkedOperation?.map((operationType, i) => (\n        <>\n          <div className={i % 2 === 0 ? '' : 'mt-4 border-t border-gray-200 pt-4'} key={operationType}>\n            <Checkbox\n              wrapClass=\"mt-3\"\n              checked={!!permissionData?.schemaJson?.[platformType]?.[operationType]}\n              onChange={(val) => {\n                handleSelectOperation(val, operationType, platformType);\n                handleChange(val, operationType, platformType);\n              }}\n            >\n              {getSettingOperationsType(operationType)}\n            </Checkbox>\n            <div className=\"grid grid-cols-1 gap-5 mt-3\">\n              <Select\n                desc={`Select the middleware you wanted to apply for the ${lowerCase(getSettingOperationsType(operationType))} operation.`}\n                label=\"Middleware\"\n                defaultValue={selectedPolicies[operationType]}\n                value={selectedPolicies[operationType]}\n                placeholder=\"Select middleware\"\n                options={permissionData?.schemaJson?.[platformType]?.[CRUD.isAuth] ? policyList : policyList?.filter((policy) => policy?.fileName !== 'auth')}\n                isMulti\n                valueKey=\"fileName\"\n                labelKey=\"fileName\"\n                onChange={(value) => handlePolicySelection(value, operationType)}\n                disabled={!permissionData?.schemaJson?.[platformType]?.[operationType]}\n              />\n              <div>\n                <SelectTree\n                  mode=\"multiSelect\"\n                  desc={`Select the attribute of your model that you desire to get in ${lowerCase(getSettingOperationsType(operationType))} API response.`}\n                  defaultValue={selectedAttributes[operationType]}\n                  noDataMessage=\"No attribute\"\n                  data={{ ...defaultAttributes[ormType], ...modelList?.find((model) => model?._id === permissionData?.schemaId?._id)?.schemaJson || {} }}\n                  disabledKey={['_id']}\n                  label=\"Attribute\"\n                  placeholder=\"Select attribute\"\n                  WrapClassName=\"selectValue\"\n                  handleChange={(allSelectedNode) => handleAttributeSelection(allSelectedNode?.allSelectedNode, operationType)}\n                  disabled={(!permissionData?.schemaJson?.[platformType]?.[operationType])}\n                />\n                <TagGroup\n                  titleKey=\"title\"\n                  TagList={selectedAttributes[operationType]?.map((tag) => ({\n                    title: tag,\n                    tagVariant: 'secondary',\n                    close: true,\n                  }))}\n                  disabledTag={ormType === ORM_TYPE.MONGOOSE ? [{\n                    title: '_id',\n                    tagVariant: 'secondary',\n                    close: true,\n                  }] : []}\n                  disabled={!permissionData?.schemaJson?.[platformType]?.[operationType]}\n                  onClick={(index) => {\n                    selectedAttributes[operationType].splice(ormType === ORM_TYPE.MONGOOSE ? (index - 1) : index, 1);\n                    dispatch({\n                      type: SETTING_ACTION_TYPES.EDIT,\n                      payload: {\n                        platformType,\n                        operation: operationType,\n                        selected: true,\n                        policy: !isEmpty(selectedPolicies[operationType]) ? selectedPolicies[operationType] : permissionData?.schemaJson?.[platformType]?.[CRUD.POLICY],\n                        isAuth: permissionData?.schemaJson?.[platformType]?.[CRUD.isAuth],\n                        attributes: cloneDeep(selectedAttributes[operationType]),\n                        model: permissionData?.schemaId?._id,\n                      },\n                    });\n                    setSelectedAttributes(cloneDeep(selectedAttributes));\n                  }}\n                />\n              </div>\n            </div>\n          </div>\n        </>\n      ))\n    }\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/Setting/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport Drawer from 'rc-drawer';\nimport { capitalize } from 'lodash';\nimport { TabCSs } from '../../../../assets/css/tab';\nimport {\n  Description, DrawerFooter, DrawerHead, DrawerClose,\n} from '../../../../components';\nimport { SettingDetail } from './SettingDetail';\nimport {\n  CRUD_OPERATIONS, LINKED_CRUD_OPERATION, DEVICE_TYPE_NAME,\n} from '../../../../constant/permission';\n\nexport const Setting = ({\n  onDrawerClose, isOpen, onClose, permissionData, platformType, policyList, handleSave, onChange,\n}) => {\n  const [activeTab, setActiveTab] = React.useState(CRUD_OPERATIONS.C);\n\n  const handleTabChange = (type) => {\n    setActiveTab(type);\n  };\n  return (\n    <Drawer\n      open={isOpen}\n      handleSubmit={onClose}\n      onClose={onDrawerClose}\n      handleCancel={onClose}\n      ease\n      level={null}\n      handler={false}\n      placement=\"right\"\n      wrapperClassName=\"\"\n    >\n\n      <DrawerClose onClick={onClose} />\n      <DrawerHead title={`${permissionData?.schemaId?.name} - ${capitalize((DEVICE_TYPE_NAME[platformType?.toUpperCase()] ?? platformType) ?? '')}`} className=\"xl:block xxl:block\">\n        <Description className=\"mt-2\">{`Set up middleware and its attributes for ${permissionData?.schemaId?.name} for the ${capitalize((DEVICE_TYPE_NAME[platformType?.toUpperCase()] ?? platformType) ?? '')}.`}</Description>\n      </DrawerHead>\n      <Tabs selectedTabPanelClassName=\"h-0 flex-grow\" className=\"flex-grow h-0 flex flex-col\" selectedTabClassName={TabCSs.selectTab}>\n        <TabList className={`${TabCSs.tabHead} settingTab pt-2 mx-5 flex-shrink-0`}>\n          {\n             Object.keys(LINKED_CRUD_OPERATION)?.map((operation) => (\n               <Tab className={`${TabCSs.tabTitle}`} key={CRUD_OPERATIONS[operation]} onClick={() => handleTabChange(CRUD_OPERATIONS[operation])}>\n                 {CRUD_OPERATIONS[operation]}\n               </Tab>\n             ))\n            }\n        </TabList>\n        {\n             Object.keys(LINKED_CRUD_OPERATION)?.map((operation) => (\n               <TabPanel key={CRUD_OPERATIONS[operation]}>\n                 <div className=\"px-5 overflow-auto h-full\">\n                   <SettingDetail policyList={policyList} permissionData={permissionData} platformType={platformType} onChange={onChange} linkedOperation={LINKED_CRUD_OPERATION[operation]} />\n                 </div>\n               </TabPanel>\n             ))\n          }\n      </Tabs>\n      <DrawerFooter\n        cancelTitle=\"Cancel\"\n        submitTitle=\"Submit\"\n        handleCancel={onClose}\n        handleSubmit={() => {\n          handleSave(activeTab);\n          onClose();\n        }}\n      />\n\n    </Drawer>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Permission/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable no-param-reassign */\nimport React, { useState, useRef } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport cloneDeep from 'lodash/cloneDeep';\nimport concat from 'lodash/concat';\nimport { isEmpty, uniq } from 'lodash';\nimport { useHistory } from 'react-router';\nimport { NoData, StepFooter } from '../../../components';\nimport {\n  getModelPermissions,\n  upsertModelPermissions,\n} from '../../../api/models';\nimport Header from './Header';\nimport Permissions from './Permissions';\nimport useToastNotifications from '../../hooks/useToastNotifications';\nimport useBoolean from '../../hooks/useBoolean';\nimport { validationMsg } from '../../../utils/validationMsgs';\nimport Spinner from './Permission.loader';\nimport { CRUD } from '../../../constant/permission';\nimport { getPolicies } from '../../../api/policy';\nimport { listModels } from '../../../redux/thunks/models';\nimport { PermissionSettingProvider, SETTING_ACTION_TYPES } from './PermissionSettingProvider';\nimport { prepareData, prepareSettingData } from './PermissionHelperFunctions';\nimport LayoutStepUrl from '../../Shared/LayoutStepUrl';\nimport { StepHeader } from '../../Shared/Layout/StepHeader';\nimport { encryptStorage } from '../../../utils/localStorage';\nimport { LAYOUT_STEP_MODULE_NAME, RedirectUrl } from '../../../constant/Nodecrud';\n\nexport default function Permission() {\n  const history = useHistory();\n  const [permissionList, setPermissionList] = useState([]);\n  const [policyLists, setPolicyLists] = React.useState([]);\n  const [loader, setLoader, hideLoader] = useBoolean(false);\n  const [upsertLoader, setUpsertLoader, hideUpsertLoader] = useBoolean(false);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const projectDetail = useSelector((state) => state.projects.currentProjectDetail);\n  const applicationLoginAccess = projectDetail?.applicationList?.find((d) => d._id === applicationId)?.configInput?.platform;\n  const [deviceData, setDeviceData] = React.useState({});\n  const dataRef = useRef(null);\n  const buttonRef = React.useRef('');\n  const modelList = useSelector(({ models }) => models.modelList);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n\n  React.useEffect(() => () => {\n    // Remove\n    // to maintain remove toggle from sidebar when crud in url\n    !window.location.pathname.includes('crud') && encryptStorage.remove('sidebarToggle');\n  }, []);\n\n  const {\n    addErrorToast,\n    addSuccessToast,\n  } = useToastNotifications();\n  const dispatch = useDispatch();\n\n  const fetchData = async () => {\n    try {\n      setLoader();\n      const policyRes = await getPolicies({ applicationId });\n      const permissionRes = await getModelPermissions({ applicationId });\n\n      setPolicyLists(policyRes?.data?.list || []);\n      if (!isEmpty(permissionRes?.data?.list)) {\n        const newPermissionData = prepareData(permissionRes?.data?.list, cloneDeep(applicationLoginAccess), setDeviceData);\n        setPermissionList(newPermissionData);\n        setTimeout(() => {\n          hideLoader();\n        }, 100);\n      } else {\n        setPermissionList(permissionRes?.data?.list || []);\n        hideLoader();\n      }\n    } catch (error) {\n      addErrorToast(error);\n    }\n  };\n\n  const fetch = () => {\n    setLoader();\n    getModelPermissions({ applicationId }).then((data) => {\n      if (!isEmpty(data?.data?.list)) {\n        const newPermissionData = prepareData(data?.data?.list, cloneDeep(applicationLoginAccess), setDeviceData);\n        setPermissionList(newPermissionData);\n        hideLoader();\n      } else {\n        setPermissionList(data?.data?.list || []);\n        hideLoader();\n      }\n    }).catch(addErrorToast).finally(hideLoader);\n  };\n\n  React.useEffect(() => {\n    fetchData();\n  }, []);\n\n  React.useEffect(() => {\n    if (applicationId) {\n      dispatch(listModels({ applicationId }));\n    }\n  }, [applicationId]);\n\n  const handleSave = () => {\n    const currentPermissions = cloneDeep(dataRef?.current?.permissions) || []; // to get all latest/updated permissions list\n    const permissionSetting = cloneDeep(dataRef?.current?.editSettingData) || {}; // to get latest/updated additionalSetting data of selected model's selected platform\n\n    const exist = currentPermissions?.find((permission) => Object.keys(permission?.schemaJson)?.some((platform) => Object.values(permission.schemaJson[platform])?.some((key) => (key)))); // to check schemaJson Data\n\n    if (!exist) {\n      addErrorToast(validationMsg.select('Model Permissions'));\n      return;\n    }\n\n    const model = permissionSetting?.[Object.keys(permissionSetting)?.[0]]?.model; // to get selected model _id of selected platform\n\n    const requestArray = [];\n    currentPermissions?.map((permission) => {\n      const reqJson = {};\n      const settingJson = {};\n      const settings = (permission?.schemaId?._id === model) ? permissionSetting : (permission?.additionalJson?.additionalSetting || {});\n\n      Object.keys(permission.schemaJson)?.forEach((platform) => {\n        // to add/remove 'auth' policy in additionalSetting object based on 'isAuth' value\n        !isEmpty(settings?.[platform]) && Object.keys(settings?.[platform])?.forEach((operation) => {\n          settings[platform][operation][CRUD.POLICY] = permission?.schemaJson?.[platform]?.[CRUD.isAuth] ? uniq(settings?.[platform]?.[operation]?.[CRUD.POLICY]?.concat('auth')) : settings?.[platform]?.[operation]?.[CRUD.POLICY]?.filter((policy) => policy !== 'auth');\n        });\n      });\n\n      if (!model) { // if settings drawer isn't opened\n        !isEmpty(settings) ? Object.keys(permission?.schemaJson)?.forEach((platform) => {\n          if (settings[platform]) { // if additionalJson for selected platform exists\n            Object.keys((permission?.schemaJson?.[platform]))?.forEach((operation) => {\n              if (![CRUD.isAuth, CRUD.POLICY, CRUD.ALL].includes(operation)) {\n                if (permission?.schemaJson?.[platform]?.[operation]) {\n                  if (settings?.[platform]?.[operation]) {\n                    settings[platform][operation].isAuth = permission?.schemaJson?.[platform]?.[CRUD.isAuth];\n                    settings[platform][operation].selected = permission?.schemaJson?.[platform]?.[operation];\n                    settings[platform][operation].policy = !isEmpty(settings?.[platform]?.[operation].policy) ? settings?.[platform]?.[operation].policy : permission?.schemaJson?.[platform]?.[CRUD.POLICY];\n                  } else {\n                    prepareSettingData(settings, platform, operation, permission);\n                  }\n                } else {\n                  delete settings?.[platform]?.[operation]; // to remove unchecked operation from additionalSetting\n                }\n              }\n            });\n          } else { // if additionalJson for selected platform doesn't exist, create the same in additionalJson\n            settings[platform] = {};\n            Object.keys((permission?.schemaJson?.[platform]))?.forEach((operation) => {\n              if (![CRUD.isAuth, CRUD.POLICY, CRUD.ALL].includes(operation)) {\n                if (permission?.schemaJson?.[platform][operation]) {\n                  prepareSettingData(settings, platform, operation, permission);\n                }\n              }\n            });\n          }\n        })\n          : Object.keys((permission?.schemaJson))?.forEach((platform) => { // if additionalJson object doesn't exist, create the same in additionalSetting object\n            settings[platform] = {};\n            Object.keys((permission?.schemaJson?.[platform]))?.forEach((operation) => {\n              if (![CRUD.isAuth, CRUD.POLICY, CRUD.ALL].includes(operation)) {\n                if (permission?.schemaJson?.[platform][operation]) {\n                  prepareSettingData(settings, platform, operation, permission);\n                }\n              }\n            });\n          });\n      }\n\n      if (permission?.schemaId?._id === model) {\n        // to add/remove (un)checked operations' data of selected permission in/from additionalJson object\n        Object.keys(settings)?.forEach((action) => {\n          const platform = settings?.[action]?.platformType;\n          settingJson[platform] = {};\n          !isEmpty(settings) && Object.keys(settings)?.map((operation) => {\n            if (permission?.schemaId?._id === model && permission?.schemaJson?.[platform]?.[operation]) {\n              settingJson[platform][operation] = {};\n              settingJson[platform][operation].selected = permission?.schemaJson?.[platform]?.[operation] ? settings?.[operation]?.selected : permission?.schemaJson?.[platform]?.[operation];\n              settingJson[platform][operation].policy = uniq(settings?.[operation]?.policy);\n              settingJson[platform][operation].isAuth = permission?.schemaJson?.[platform]?.[CRUD.isAuth] ? settings?.[operation]?.isAuth : permission?.schemaJson?.[platform]?.[CRUD.isAuth];\n              settingJson[platform][operation].attributes = settings?.[operation]?.attributes || [];\n            } else {\n              delete settings?.[platform]?.[operation];\n            }\n            return settingJson;\n          });\n        });\n      }\n\n      Object.keys(permission.schemaJson)?.map((platform) => {\n        // remove extra keys\n        delete permission.schemaJson[platform].ALL;\n        reqJson[platform] = [];\n        reqJson[platform].push({ [CRUD.isAuth]: !!permission?.schemaJson[platform][CRUD.isAuth], policy: permission?.schemaJson?.[platform]?.[CRUD.POLICY] || [] });\n        delete permission.schemaJson[platform][CRUD.isAuth];\n        delete permission.schemaJson[platform][CRUD.POLICY];\n        delete permission.schemaJson[platform].isAuthentication;\n        reqJson[platform] = concat(reqJson[platform], Object.keys(permission.schemaJson[platform])?.filter((act) => permission?.schemaJson[platform][act]));\n        return platform;\n      });\n\n      const obj = {\n        _id: permission._id,\n        schemaId: permission.schemaId._id,\n        schemaJson: reqJson,\n        additionalJson: {\n          additionalSetting: (permission?.schemaId?._id === model) ? { ...(!isEmpty(permission?.additionalJson?.additionalSetting) && permission?.additionalJson?.additionalSetting), ...settingJson } : settings,\n        },\n      };\n      requestArray.push(obj);\n      return permission;\n    });\n\n    setUpsertLoader();\n    upsertModelPermissions({ data: requestArray }).then((data) => {\n      fetch();\n      addSuccessToast(data?.message);\n      dataRef?.current?.dispatch({ type: SETTING_ACTION_TYPES.RESET_EDIT_DATA });\n      hideUpsertLoader();\n\n      if (buttonRef.current === 'next') history.push(RedirectUrl[currentApplicationCode].permission.nextUrl);\n    }).catch((error) => {\n      addErrorToast(error);\n      hideUpsertLoader();\n    });\n  };\n\n  return (\n    <div className=\"flex flex-col h-screen\">\n      <StepHeader backTitle=\"Back to screen\" headTitle=\"CRUD\" link={RedirectUrl[currentApplicationCode].permission.backScreenUrl} />\n      <LayoutStepUrl isOpenBigLayout={false} isBuildShow moduleName={LAYOUT_STEP_MODULE_NAME[currentApplicationCode]}>\n\n        <div className=\"w-full h-0 flex flex-grow flex-col\">\n          <Header\n            upsertLoader={upsertLoader}\n            onSave={handleSave}\n            onCancel={fetch}\n            permissions={permissionList}\n          />\n          <div\n            className=\"overflow-auto h-full\"\n          >\n            {loader && <Spinner />}\n            {!loader\n             && (\n               !isEmpty(permissionList)\n                 ? (\n                   <PermissionSettingProvider>\n                     <Permissions ref={dataRef} permissions={permissionList} applicationLoginAccess={cloneDeep(applicationLoginAccess)} policyLists={policyLists} handleSave={handleSave} deviceData={deviceData} />\n                   </PermissionSettingProvider>\n                 )\n                 : (\n                   <NoData\n                     onClick={() => {\n                       // Remove\n                       if (isEmpty(applicationLoginAccess)) { history.push(RedirectUrl[currentApplicationCode].platformConfig.pageUrl); return; }\n                       if (isEmpty(modelList)) {\n                         history.push(RedirectUrl[currentApplicationCode].model.pageUrl);\n                       }\n                     }}\n                     title={isEmpty(applicationLoginAccess) ? 'No platforms are available.' : isEmpty(modelList) ? 'No models are available.' : 'No model permission found'}\n                     btnText={isEmpty(applicationLoginAccess) ? 'Add platform' : isEmpty(modelList) ? 'Add model' : ''}\n                   />\n                 )\n             )}\n          </div>\n        </div>\n        <StepFooter\n          backClick={() => {\n            history.push(RedirectUrl[currentApplicationCode].permission.previousUrl);\n          }}\n          nextClick={() => {\n            buttonRef.current = 'next';\n            handleSave();\n          }}\n          isNextDisable={loader}\n          isSaveDisable={loader}\n          nextLoading={buttonRef.current === 'next' && upsertLoader}\n          saveLoading={buttonRef.current === 'save' && upsertLoader}\n          saveClick={() => {\n            buttonRef.current = 'save';\n            handleSave();\n          }}\n          Back=\"Previous\"\n          Next=\"Save & Next\"\n          saveText=\"Save\"\n        />\n      </LayoutStepUrl>\n    </div>\n\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/AddRouteProvider.js",
    "content": "import React from 'react';\nimport { isEmpty, uniqBy, last } from 'lodash';\nimport { FormProvider, useForm } from 'react-hook-form';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport { createNodeRoute, updateNodeRoute } from '../../../../api/routes';\nimport { ROUTE_GENERATE_TYPE, ROUTE_VALIDATION_MESSAGE } from '../../../../constant/routes';\nimport useToastNotifications from '../../../hooks/useToastNotifications';\nimport { useRoute } from '../RouteProvider';\nimport { useAddToggle } from '../AddToggleProvider';\n\nexport const AddRouteTabContext = React.createContext();\n\nexport const RouteTabIndexName = {\n  [ROUTE_GENERATE_TYPE.MANUAL]: {\n    0: 'Basic',\n    1: 'Advance',\n    // 2: 'Configuration',\n    2: 'Query builder',\n  },\n  [ROUTE_GENERATE_TYPE.AUTO]: {\n    get: {\n      '{{id}}': {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      default: {\n        0: 'Model permission',\n      },\n    },\n    post: {\n      list: {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      default: {\n        0: 'Model permission',\n      },\n    },\n    put: {\n      '{{}}': {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      '{{id}}': {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      updateBulk: {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      default: {\n        0: 'Model permission',\n      },\n    },\n    delete: {\n      '{{id}}': {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n      default: {\n        0: 'Query builder',\n        1: 'Model permission',\n      },\n    },\n  },\n};\n\nconst TabWiseFields = {\n  0: { requiredFiled: ['platform', 'method', 'route', 'controller', 'action'], notRequiredFiled: ['groupName', 'description'] },\n  1: { requiredFiled: [], notRequiredFiled: ['headers', 'policies'] },\n  2: { requiredFiled: [], notRequiredFiled: ['queryBuilder'] },\n};\n\nconst AddRouteTabProvider = ({ children }) => {\n  const methods = useForm({ shouldUnregister: false, mode: 'all' });\n  const { handleSubmit, getValues, errors } = methods;\n\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const {\n    editRouteData, dispatch, selectedModelId, generalizedModel,\n  } = useRoute();\n  const { hideAddModal } = useAddToggle();\n\n  const [updateId, setUpdateId] = React.useState('');\n  const [tabIndex, setTabIndex] = React.useState(0);\n  const loadingCallBackRef = React.useRef(() => { });\n\n  const { currentApplicationId, currentApplicationCode, modelList } = useSelector(({ models, projects }) => ({\n    currentApplicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n    modelList: models.modelList,\n  }), shallowEqual);\n\n  // If any fields gets added then add it to TabWiseFields\n  const findErrorTabIndex = (data = getValues()) => {\n    const tabError = [];\n    if ([1, 2, 3].includes(tabIndex)) {\n      Object.keys(TabWiseFields).forEach((tb) => TabWiseFields[tb].requiredFiled.forEach((filed) => {\n        if (isEmpty(data[filed]) && !tabError.includes(tb)) {\n          tabError.push(tb);\n        }\n      }));\n    }\n    if (!isEmpty(tabError)) {\n      // const tabName = tabError.map((tab) => RouteTabIndexName[tab]).toString();\n      setTabIndex(Math.min(tabError));\n      addErrorToast(ROUTE_VALIDATION_MESSAGE.tabValidation);\n      return false;\n    }\n    return true;\n  };\n\n  const handleSave = (data) => {\n    const requestData = {\n      ...data,\n    };\n\n    loadingCallBackRef.current({ isLoading: true });\n\n    const uploadData = requestData.uploads ?? { isSingle: true, storage: 'local' };\n\n    const apiRequest = {\n      applicationId: currentApplicationId,\n      type: ROUTE_GENERATE_TYPE.MANUAL,\n      ...editRouteData,\n      ...requestData,\n      definitionType: currentApplicationCode,\n      fileUpload: { uploads: [{ ...uploadData }] },\n      uploads: undefined,\n      queryBuilder: requestData?.queryBuilder?.map((query) => (\n        // eslint-disable-next-line no-nested-ternary\n        { ...query, filterJson: query?.filter ? query.filterJson : undefined, filter: query?.filter ? (typeof query?.filter === typeof 'string' ? JSON.parse(query?.filter) : query?.filter) : undefined })),\n      ...(requestData.modelId && { groupName: modelList?.find((model) => model?._id === data?.modelId)?.name }),\n      headers: !isEmpty(requestData?.headers) ? uniqBy(requestData?.headers, 'key')?.filter((header) => header?.key && header?.value) : [{ key: '', value: '' }],\n    };\n\n    if (isEmpty(data)) return;\n\n    if ((apiRequest?.type === ROUTE_GENERATE_TYPE.AUTO) || (apiRequest?.type === ROUTE_GENERATE_TYPE.MANUAL && findErrorTabIndex())) {\n      const apiCall = editRouteData?._id || updateId ? updateNodeRoute(editRouteData._id || updateId, apiRequest) : createNodeRoute(apiRequest);\n      apiCall.then((response) => {\n        addSuccessToast(response.message);\n\n        if (selectedModelId !== generalizedModel?._id) {\n          (selectedModelId === response?.data?.modelId) && dispatch({ type: editRouteData?._id || updateId ? 'EditRoute' : 'AddRoute', payload: response.data });\n          (selectedModelId !== response?.data?.modelId) && dispatch({ type: 'DeleteRoute', payload: response.data });\n        } else {\n          (response?.data?.modelId === null) ? dispatch({ type: editRouteData?._id || updateId ? 'EditRoute' : 'AddRoute', payload: response.data }) : dispatch({ type: 'DeleteRoute', payload: response.data });\n        }\n\n        setUpdateId(response.data?._id); // For Calling second panel edit api\n\n        // dispatch({ type: 'SetEditRouteData', payload: response.data });\n        // setTabIndex((prevIndex) => (prevIndex !== 2 ? prevIndex + 1 : 0));\n\n        if (tabIndex !== Object.keys(RouteTabIndexName[editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL]).length - 1) setTabIndex((prevIndex) => (prevIndex + 1));\n\n        loadingCallBackRef.current({ isLoading: false });\n\n        if (tabIndex === (Object.values(((editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL) === ROUTE_GENERATE_TYPE.MANUAL) ? (RouteTabIndexName[editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL]) : (RouteTabIndexName[editRouteData?.type][editRouteData?.method][['{{id}}', 'list', '{{}}', 'updateBulk'].includes(last(editRouteData?.route?.split('/'))) ? last(editRouteData?.route?.split('/')) : 'default']))?.length - 1)) hideAddModal();\n      }).catch((error) => {\n        addErrorToast(error); loadingCallBackRef.current({ isLoading: false, isFailed: true });\n      });\n      return;\n    }\n    loadingCallBackRef.current({ isLoading: false, isFailed: true });\n  };\n\n  const value = {\n    handleSave: !isEmpty(errors) ? findErrorTabIndex : handleSubmit(handleSave),\n    setTabIndex: (index) => { setTabIndex(index); },\n    loadingCallBack: (loadingFn) => { loadingCallBackRef.current = loadingFn; },\n    findErrorTabIndex,\n    tabIndex,\n    resetData: () => { setUpdateId(''); },\n  };\n\n  return (\n    <FormProvider\n      // eslint-disable-next-line react/jsx-props-no-spreading\n      {...methods}\n    >\n      <AddRouteTabContext.Provider value={value}>{children}</AddRouteTabContext.Provider>\n    </FormProvider>\n  );\n};\n\nfunction useAddRoute() {\n  const context = React.useContext(AddRouteTabContext);\n  if (context === undefined) {\n    throw new Error('useAddRoute must be used within a AddRouteTabProvider');\n  }\n  return context;\n}\n\nexport { AddRouteTabProvider, useAddRoute };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/Advance/index.js",
    "content": "import React from 'react';\nimport {\n  cloneDeep, concat, isEmpty, uniq, uniqBy,\n} from 'lodash';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport { useSelector } from 'react-redux';\nimport { getPolicies } from '../../../../../api/policy';\nimport { APIKeyValue, LabelBox, Select } from '../../../../../components';\nimport { ROUTE_HEADERS } from '../../../../../constant/routes';\nimport { useRoute } from '../../RouteProvider';\nimport { useToastNotifications } from '../../../../hooks';\n\n// const headerObject = {\n//   key: '',\n//   value: '',\n// };\n\nconst HeaderComponent = (props) => {\n  const methods = useFormContext();\n  const { addErrorToast } = useToastNotifications();\n\n  const { setValue } = methods;\n  const [customHeaders, setCustomHeaders] = React.useState(\n    concat(props?.value && cloneDeep(props?.value), { key: '', value: '' }),\n  );\n\n  const checkDuplicateKey = (headerList) => {\n    const keys = headerList\n      ?.map((header) => header?.key)\n      ?.filter((el) => el && el);\n    return keys?.length === uniq(keys)?.length;\n  };\n\n  const handleInputChange = (e, index, type) => {\n    const headersList = [...customHeaders];\n    headersList[index][type] = e;\n    setCustomHeaders(headersList);\n\n    // setValue('headers', headersList);\n  };\n\n  const handleInputBlur = (e, index, type) => {\n    const headersList = [...customHeaders];\n    if (\n      type === 'key'\n      && e.target.value.length\n      && index === headersList?.length - 1\n    ) {\n      headersList[index + 1] = { key: '', value: '' };\n    }\n    setCustomHeaders(uniqBy(headersList, 'key'));\n    !checkDuplicateKey(headersList) && addErrorToast('Key already exists.');\n    setValue(\n      'headers',\n      uniqBy(headersList, 'key')?.filter((header) => header?.key),\n    );\n    // setOtherFormData({ headers: headersList.findIndex((header) => !isEmpty(header?.key)) >= 0 ? customHeaders?.filter((header) => header?.key) : headerObject });\n  };\n\n  const handleDeleteHeader = (index) => {\n    const headersList = [...customHeaders];\n    if (headersList?.length !== 1) {\n      headersList.splice(index, 1);\n    } else {\n      headersList[index] = { key: '', value: '' };\n    }\n    setCustomHeaders(uniqBy(headersList, 'key'));\n    setValue(\n      'headers',\n      uniqBy(headersList, 'key')?.filter((header) => header?.key),\n    );\n    // setOtherFormData({ headers: headersList.findIndex((header) => !isEmpty(header?.key)) >= 0 ? customHeaders?.filter((header) => header?.key) : headerObject });\n  };\n  return (\n    <>\n      {customHeaders?.map((header, index) => {\n        if (header) {\n          return (\n            <tr className=\"align-top\">\n              <APIKeyValue\n                APIValue\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...props}\n                isValue\n                isAutoSuggest\n                // isDelete={(customHeaders?.length > 1)}\n                isDelete\n                inputProps={{\n                  value: header?.key,\n                  placeholder: 'Enter new key',\n                  onChange: (e) => handleInputChange(e, index, 'key'),\n                  onBlur: (e) => handleInputBlur(e, index, 'key'),\n                  list: `headers${index}`,\n                  autoComplete: 'off',\n                  error:\n                    !isEmpty(header?.value)\n                    && isEmpty(header?.key)\n                    && 'key is required',\n                  customRegex: false,\n                }}\n                valueProps={{\n                  value: header?.value,\n                  placeholder: 'Enter new value',\n                  onChange: (e) => handleInputChange(e, index, 'value'),\n                  error:\n                    !isEmpty(header?.key)\n                    && isEmpty(header?.value)\n                    && 'value is required',\n                }}\n                autoSuggestProps={{\n                  list: ROUTE_HEADERS,\n                  id: `headers${index}`,\n                }}\n                deleteProps={{\n                  onDelete: () => handleDeleteHeader(index),\n                  disabled:\n                    index === customHeaders?.length - 1 && isEmpty(header?.key),\n                }}\n              />\n            </tr>\n          );\n        }\n        return null;\n      })}\n    </>\n  );\n};\nfunction Advance() {\n  const [policyLists, setPolicyLists] = React.useState([]);\n  const currentApplicationId = useSelector(\n    (state) => state.projects.currentApplicationId,\n  );\n  const { editRouteData } = useRoute();\n\n  // React.useEffect(() => {\n  //   () => {\n\n  //   };\n  // }, []);\n  const methods = useFormContext();\n\n  const { control, setValue, getValues } = methods;\n  function fetchAllPolicies() {\n    getPolicies({\n      applicationId: currentApplicationId,\n    }).then((policyRes) => {\n      // TODO:Fixed one api call\n      const policyList = policyRes?.data?.list;\n      setPolicyLists(policyList);\n      const editData = editRouteData?.policies || getValues('policies');\n      const editDataFilter = editData?.filter((policy) => policyList?.find((policyData) => policyData?.fileName === policy));\n      setValue(\n        'policies',\n        isEmpty(editDataFilter) ? undefined : editDataFilter,\n      );\n    });\n  }\n\n  React.useEffect(() => {\n    fetchAllPolicies();\n  }, []);\n\n  return (\n    <div className=\"py-3\">\n      <Controller\n        control={control}\n        name=\"policies\"\n        render={(controlProps) => (\n          <Select\n            // eslint-disable-next-line react/jsx-props-no-spreading\n            {...controlProps}\n            isMulti\n            className=\"w-6/12\"\n            placeholder=\"Select middleware\"\n            options={policyLists}\n            onChange={(data) => {\n              setValue('policies', data);\n              // setOtherFormData({ policies: data?.policies?.filter((policy) => policyLists?.find((policyData) => policyData?.fileName === policy)) });\n            }}\n            label=\"Middleware\"\n            valueKey=\"fileName\"\n            labelKey=\"fileName\"\n          />\n        )}\n      />\n      <div className=\"mt-5\">\n        <LabelBox>Custom header</LabelBox>\n        <table className=\"w-6/12 mt-5\">\n          <Controller\n            control={control}\n            name=\"headers\"\n            defaultValue={editRouteData.headers}\n            render={(controlProps) => (\n              // eslint-disable-next-line react/jsx-props-no-spreading\n              <HeaderComponent {...controlProps} />\n            )}\n          />\n        </table>\n      </div>\n    </div>\n  );\n}\n\nexport default Advance;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/Basic/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useHistory } from 'react-router';\nimport { Icons } from '@dhiwise/icons';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport {\n  Input, Select, TagGroup, IconBox,\n} from '../../../../../components';\nimport { RedirectUrl } from '../../../../../constant/Nodecrud';\nimport { ROUTE_TYPES } from '../../../../../constant/routes';\nimport { getError } from '../../../../../utils/validationMsgs';\nimport { useRoute } from '../../RouteProvider';\nimport { getApplicationPlatforms } from '../../../../../utils/applicationPlatform';\nimport { nodeKeyRegex } from '../../../../../utils/regex';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../../constant/common';\n\nfunction Basic() {\n  const {\n    control, setValue, errors, watch, getValues,\n  } = useFormContext();\n\n  const { selectedModelId, editRouteData, generalizedModel } = useRoute();\n\n  const history = useHistory();\n\n  const {\n    modelList, currentApplicationId, projectDetail, currentApplicationCode,\n  } = useSelector(({ models, projects }) => ({\n    modelList: models.modelList,\n    currentApplicationId: projects.currentApplicationId,\n    projectDetail: projects.currentProjectDetail,\n    ormType: projects.applicationDatabase.ormType,\n    currentApplicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n  const applicationLoginAccess = projectDetail?.applicationList?.find((d) => d._id === currentApplicationId)?.configInput?.platform;\n\n  return (\n\n    <div className=\"grid grid-cols-3 gap-5 py-3\">\n      <div className=\"grid col-span-3 xxl:col-span-1 grid-cols-2 gap-5\">\n        <div className=\"flex\">\n          <Controller\n            control={control}\n            name=\"modelId\"\n            defaultValue={(selectedModelId === generalizedModel?._id) ? null : selectedModelId}\n            // rules={{ required: true }}\n            render={(controlProps) => (\n              <>\n                <Select\n                  WrapClassName=\"flex-grow\"\n                  {...controlProps}\n                  onChange={(modelId) => {\n                    setValue('modelId', modelId);\n                    setValue('attributes', []); // to reset selected attributes\n                    setValue('platform', ''); // to reset the platform if user change model\n                    setValue('controller', modelId ? (modelList?.find((model) => model?._id === modelId)?.name) : ''); // predict the name of controller based on selected model\n                  }}\n                  placeholder=\"Select model\"\n                  options={modelList}\n                  label=\"Model\"\n                  error={!controlProps.modelId && getError(errors, 'modelId', 'Model')}\n                  valueKey=\"_id\"\n                />\n                {isEmpty(modelList) && <IconBox icon={<Icons.Plus />} className=\"ml-1 flex-shrink-0 mt-9\" variant=\"secondary\" shape=\"rounded\" size=\"normal\" tooltip=\"Add model\" onClick={() => history.push(RedirectUrl[currentApplicationCode].model.pageUrl)} />}\n              </>\n            )}\n          />\n        </div>\n        <Controller\n          control={control}\n          name=\"platform\"\n          defaultValue={editRouteData?.platform}\n          rules={{ required: true }}\n          render={(controlProps) => (\n            <Select\n              {...controlProps}\n              placeholder=\"Select platform\"\n              options={getApplicationPlatforms(applicationLoginAccess)}\n              label=\"Platform*\"\n              error={!controlProps.value && getError(errors, 'platform', 'Platform')}\n            />\n          )}\n        />\n      </div>\n      <div className=\"flex items-start col-span-3 xxl:col-span-2\">\n        <Controller\n          control={control}\n          RadiusType\n          name=\"method\"\n          rules={{ required: true }}\n          defaultValue={editRouteData.method}\n          render={(controlProps) => (\n            <Select\n              WrapClassName=\"flex flex-wrap content-end w-40\"\n              className=\"w-full\"\n              {...controlProps}\n              placeholder=\"Method\"\n              options={ROUTE_TYPES}\n              label=\"Method*\"\n              error={!controlProps.value && getError(errors, 'method', 'Method')}\n            />\n          )}\n        />\n        <div style={{ width: 'calc(100% - 10rem)', marginLeft: '2px' }}>\n          <Controller\n            control={control}\n            name=\"route\"\n            defaultValue={editRouteData.route ? editRouteData.route : '/'}\n            rules={{ required: true, pattern: /^\\/[a-zA-Z0-9]+/ }}\n            render={(controlProps) => (\n              <Input\n                {...controlProps}\n                placeholder=\"Enter route\"\n                label=\"Route*\"\n                onChange={(val) => {\n                  if (val?.indexOf('/') !== 0 || isEmpty(val)) {\n                    controlProps.onChange('/');\n                  } else {\n                    controlProps.onChange(val);\n                  }\n                }}\n                onBlur={(e) => {\n                  isEmpty(e.target.value) && setValue('route', '/');\n                }}\n                desc=\"Enter API route (path) used to call appropriate API.\"\n                error={getError(errors, 'route', (errors?.route?.type === 'pattern') ? \"Route field cannot be left blank. It should have valid API's path.\" : 'Route')}\n              />\n            )}\n          />\n        </div>\n      </div>\n      <Controller\n        control={control}\n        name=\"controller\"\n        defaultValue={editRouteData.controller || (modelList?.find((model) => model?._id === selectedModelId)?.name)}\n        rules={{ required: true }}\n        render={(controlProps) => (\n          <Input\n            {...controlProps}\n            placeholder=\"Enter controller\"\n            label=\"Controller*\"\n            customRegex={nodeKeyRegex}\n            maxLength={MAX_INPUT_FIELD_LIMIT.title}\n            desc=\"Enter name of the controller from where function is called.\"\n            error={!controlProps.value && getError(errors, 'controller', 'Controller')}\n          />\n        )}\n      />\n      <Input\n        placeholder=\"controller file name\"\n        disabled\n        label=\"Controller file name\"\n        value={watch('controller') && `${watch('controller')}Controller`}\n        desc=\"In the code, you can find the Controller file same as the above name.\"\n      />\n      <Controller\n        control={control}\n        name=\"action\"\n        rules={{ required: true }}\n        defaultValue={editRouteData.action}\n        render={(controlProps) => (\n          <Input\n            {...controlProps}\n            placeholder=\"Enter action\"\n            label=\"Action*\"\n            customRegex={nodeKeyRegex}\n            maxLength={MAX_INPUT_FIELD_LIMIT.title}\n            desc=\"Enter function name you would like to create in the controller.\"\n            error={!controlProps.value && getError(errors, 'action', 'Action')}\n          />\n        )}\n      />\n      <div>\n        <TagGroup\n          titleKey=\"title\"\n          TagList={\n            watch('attributes')?.map?.((tag) => ({\n              title: tag,\n              tagVariant: 'secondary',\n              close: true,\n            }))\n          }\n          onClick={(index) => {\n            const attributes = getValues('attributes');\n            attributes.splice(index, 1);\n            setValue('attributes', attributes);\n          }}\n        />\n      </div>\n    </div>\n  );\n}\n\nexport default Basic;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/Configuration/index.js",
    "content": "import { parseInt } from 'lodash';\nimport React from 'react';\nimport { useFormContext } from 'react-hook-form';\nimport {\n  Select, Input, Description, Heading,\n  // RadioGroup, Radio,\n} from '../../../../../components';\nimport { FILE_TYPE_EXTENSIONS } from '../../../../../constant/fileTypeConstant';\nimport { UPLOAD_ATTACHMENT_OPTIONS } from '../../../../../constant/applicationConfigConstant';\n\nexport const Configuration = ({ value: uploadData = {} }) => {\n  const { setValue, watch } = useFormContext();\n\n  const onChangeUpload = (data = {}) => {\n    setValue('uploads', { ...watch('uploads'), ...data });\n  };\n\n  React.useEffect(() => {\n    setValue('uploads', { ...uploadData, isSingle: uploadData?.isSingle ?? true, storage: uploadData?.storage ?? 'local' });\n    // For set initial singlefile selection\n  }, []);\n\n  return (\n    <div className=\"py-3\">\n      <Heading variant=\"h5\">Upload configuration</Heading>\n      <Description className=\"w-10/12 xxl:w-8/12 mt-1\">\n        Configure type of upload, type of file, and maximum size of the file you want to set for your route.\n        {/* Configure type of uploads(single upload/multi file upload), type of file, and maximum size of the file you want to set for your route.\n        Content before single upload/multi file upload option got removed\n        */}\n      </Description>\n      <div className=\"grid grid-cols-2 gap-5 mt-8\">\n        <Select\n          placeholder=\"Select allow file type to upload\"\n          label=\"Allow file type to upload\"\n          isMulti\n          value={uploadData?.validationType}\n          options={FILE_TYPE_EXTENSIONS}\n          onChange={(validationType) => {\n            onChangeUpload({ validationType });\n          }}\n        />\n        <Input.Number\n          placeholder=\"Enter max. upload size limit\"\n          label=\"Max. upload size limit (in MB)\"\n          extension=\"MB\"\n          value={uploadData?.maxSize}\n          onChange={(maxSize) => {\n            onChangeUpload({ maxSize: maxSize ? parseInt(maxSize) : undefined });\n          }}\n        />\n        <Select\n          placeholder=\"Select type of upload\"\n          label=\"Type of upload\"\n          value={uploadData?.storage}\n          options={UPLOAD_ATTACHMENT_OPTIONS}\n          isClearable={false}\n          onChange={(storage) => {\n            onChangeUpload({ storage });\n          }}\n        />\n      </div>\n      {/* <div className=\"mt-6\">\n        <RadioGroup\n          selectedValue={uploadData?.isSingle}\n          onChange={(val) => {\n            onChangeUpload({ isSingle: val });\n          }}\n          className=\"flex\"\n          name=\"changedType\"\n        >\n          <Radio value name=\"changedType\">\n            Single file upload\n          </Radio>\n          <Radio value={false} name=\"changedType\">\n            Multi file upload\n          </Radio>\n        </RadioGroup>\n      </div> */}\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/ModelPermission/index.js",
    "content": "import React from 'react';\nimport { cloneDeep, last, lowerCase } from 'lodash';\nimport { useSelector } from 'react-redux';\nimport { useFormContext } from 'react-hook-form';\nimport { Select, SelectTree, TagGroup } from '../../../../../components';\nimport { OPERATION_TYPE } from '../../../../../constant/routes';\nimport { useRoute } from '../../RouteProvider';\nimport { getPolicies } from '../../../../../api/policy';\nimport { defaultAttributes } from '../../../../../components/SelectTree';\nimport { ORM_TYPE } from '../../../../../constant/Project/applicationStep';\nimport { CRUD_OPERATIONS } from '../../../../../constant/permission';\n\nexport const ModelPermission = ({ value: permission = {} }) => {\n  const [policyLists, setPolicyLists] = React.useState([]);\n  const currentApplicationId = useSelector((state) => state.projects.currentApplicationId);\n  const modelList = useSelector((state) => state.models.modelList);\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const { selectedModelId, editRouteData } = useRoute();\n  const { setValue } = useFormContext();\n\n  function fetchAllPolicies() {\n    getPolicies({\n      applicationId: currentApplicationId,\n    }).then(\n      (policyRes) => {\n        const policyList = policyRes?.data?.list;\n        setPolicyLists(policyList);\n      },\n    );\n  }\n\n  React.useEffect(() => {\n    fetchAllPolicies();\n  }, []);\n\n  return (\n    (\n      <div className=\"grid grid-cols-2 gap-5\">\n        <Select\n          placeholder=\"Select middleware\"\n          label=\"Middleware\"\n          desc={`Select the middleware you wanted to apply for the ${lowerCase(CRUD_OPERATIONS[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]])} operation.`}\n          value={permission?.additionalJson?.additionalSetting?.[editRouteData?.platform]?.[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]]?.policy}\n          options={policyLists}\n          valueKey=\"fileName\"\n          labelKey=\"fileName\"\n          isMulti\n          onChange={(value) => {\n            const updatedPermissionData = cloneDeep(permission);\n            updatedPermissionData.additionalJson.additionalSetting[editRouteData?.platform][OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]].policy = value;\n            setValue('permissionData', updatedPermissionData);\n          }}\n        />\n        <div>\n          <SelectTree\n            mode=\"multiSelect\"\n            placeholder=\"Select attribute\"\n            label=\"Attribute\"\n            desc={`Select the attribute of your model that you desire to get in ${lowerCase(CRUD_OPERATIONS[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]])} API response.`}\n            defaultValue={permission?.additionalJson?.additionalSetting?.[editRouteData?.platform]?.[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]]?.attributes}\n            noDataMessage=\"No attribute\"\n            data={{ ...defaultAttributes[ormType], ...modelList.find((model) => model._id === selectedModelId)?.schemaJson }}\n            disabledKey={['_id']}\n            WrapClassName=\"selectValue\"\n            handleChange={(allSelectedNode) => {\n              const updatedAttributes = cloneDeep(permission);\n              updatedAttributes.additionalJson.additionalSetting[editRouteData?.platform][OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]].attributes = allSelectedNode?.allSelectedNode?.map((node) => node?.fullName);\n              setValue('permissionData', updatedAttributes);\n            }}\n          />\n          <TagGroup\n            titleKey=\"title\"\n            TagList={permission?.additionalJson?.additionalSetting?.[editRouteData?.platform]?.[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]]?.attributes?.map((tag) => ({\n              title: tag,\n              tagVariant: 'secondary',\n              close: true,\n            }))}\n            disabledTag={ormType === ORM_TYPE.MONGOOSE ? [{\n              title: '_id',\n              tagVariant: 'secondary',\n              close: true,\n            }] : []}\n            onClick={(index) => {\n              const updatedAttributes = cloneDeep(permission);\n              updatedAttributes?.additionalJson?.additionalSetting?.[editRouteData?.platform]?.[OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))]]?.attributes?.splice(ormType === ORM_TYPE.MONGOOSE ? (index - 1) : index, 1);\n              setValue('permissionData', updatedAttributes);\n            }}\n          />\n        </div>\n      </div>\n    )\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/AddResponse.js",
    "content": "import React from 'react';\nimport { Controller, useForm, useFormContext } from 'react-hook-form';\nimport {\n  Popup, Input,\n} from '../../../../../components';\nimport { useBoolean } from '../../../../../components/hooks';\nimport { ROUTE_VALIDATION_MESSAGE } from '../../../../../constant/routes';\nimport useToastNotifications from '../../../../hooks/useToastNotifications';\nimport { nodeKeyRegex } from '../../../../../utils/regex';\nimport { getError } from '../../../../../utils/validationMsgs';\n// import { useAddRoute } from '../AddRouteProvider';\nimport { useQueryResponse } from './ResponseProvider';\n\nexport const AddResponse = ({ addModalRef }) => {\n  const [responseModal, showResponseModal, hideResponseModal] = useBoolean(false);\n\n  const methods = useFormContext();\n  const {\n    getValues, setValue,\n  } = methods;\n  const { addErrorToast } = useToastNotifications();\n  const defaultQueryBuilder = getValues('queryBuilder');\n  // const [loading,,, setToggle] = useBoolean();\n\n  React.useImperativeHandle(addModalRef, () => ({ showResponseModal }));\n  const {\n    errors, control, handleSubmit,\n  } = useForm({ mode: 'all' });\n  const { setResponseId } = useQueryResponse();\n  const onSubmit = (data) => {\n    const queryBuilderData = defaultQueryBuilder;\n    const newQueryBuilderData = queryBuilderData ? [...queryBuilderData, { outputVariable: data.outputVariable, _id: queryBuilderData.length, filterJson: { id: Math.random(), type: 'group' } }]\n      : [{ outputVariable: data.outputVariable, _id: 0, filterJson: { id: Math.random(), type: 'group' } }];\n    const queryName = queryBuilderData?.map((q) => q.outputVariable) ?? [];\n    if (queryName.includes(data.outputVariable)) {\n      addErrorToast(ROUTE_VALIDATION_MESSAGE.uniqResponseKey);\n      hideResponseModal();\n      return;\n    }\n    // queryBuilderData ? [,\n    //   ...queryBuilderData]\n    //   : [{\n    //     queryMode: 'find', outputVariable: data.outputVariable, _id: 0, filterJson: undefined,\n    //   }];\n\n    setValue('queryBuilder', newQueryBuilderData);\n    setResponseId(newQueryBuilderData.length - 1);\n    hideResponseModal();\n\n    // // TODO:maintain loading state isSuccess flag manage\n    // loadingCallBack(({ isLoading = false, isFailed = false }) => {\n    //   setToggle(); if (!isLoading) {\n    //     hideResponseModal();\n    //     if (isFailed) { setValue('queryBuilder', newQueryBuilderData.splice(0, newQueryBuilderData.length - 1)); } else {\n    //       setResponseId(newQueryBuilderData.length - 1);\n    //     }\n    //   }\n    // });\n    // handleSave();\n  };\n  return (\n    <div>\n      <Popup\n        // submitLoading={loading}\n        isOpen={responseModal}\n        handleSubmit={handleSubmit(onSubmit)}\n        closeModal={hideResponseModal}\n        handleCancel={hideResponseModal}\n        title=\"Create response\"\n        cancel=\"Cancel\"\n        submit=\"Create response\"\n        bodyClass=\"xxl:max-h-110 overflow-auto xl:max-h-96\"\n        isAutoFocusOnSave\n      >\n        <div>\n          <div className=\"grid grid-cols-1 gap-5\">\n            <Controller\n              control={control}\n              name=\"outputVariable\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Input\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                  {...controlProps}\n                  autoFocus\n                  label=\"Add response *\"\n                  desc=\"Give a name to your query logic you are trying to add.\"\n                  placeholder=\"Enter response\"\n                  error={!controlProps.value && getError(errors, 'outputVariable', 'Response')}\n                  customRegex={nodeKeyRegex}\n                />\n              )}\n            />\n          </div>\n        </div>\n      </Popup>\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/NestedQueryBuilder.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { isEmpty, last } from 'lodash';\nimport {\n  Query, Builder, BasicConfig, Utils as QbUtils,\n} from 'react-awesome-query-builder';\nimport 'react-awesome-query-builder/lib/css/styles.css';\nimport 'react-awesome-query-builder/lib/css/compact_styles.css';\nimport { useFormContext } from 'react-hook-form';\nimport { useSelector } from 'react-redux';\nimport { OPERATION_TYPE } from '../../../../../constant/routes';\nimport { useRoute } from '../../RouteProvider';\nimport { recursiveTree } from './QueryBuilderDetail';\nimport { useQueryResponse } from './ResponseProvider';\nimport { LabelBox, NoData } from '../../../../../components';\nimport { defaultAttributes } from '../../../../../components/SelectTree';\n\nconst InitialConfig = BasicConfig; // optional, for more compact styles\n\nconst RenderBuilder = (props) => (\n  <div className=\"query-builder-container w-full mt-5\">\n    <div className=\"query-builder qb-lite customThemeQueryBuilder\">\n      <Builder {...props} />\n    </div>\n  </div>\n);\n\nconst NestedQueryBuilderLogic = React.memo(({ queryJson }) => {\n  const { currentResponseId } = useQueryResponse();\n  const { setValue, watch } = useFormContext();\n  const { editRouteData } = useRoute();\n  const defaultQueryBuilder = watch('nestedQueryBuilder') ? watch('nestedQueryBuilder') : editRouteData?.nestedQueryBuilder?.map((query, index) => ({ filterJson: { id: Math.random(), type: 'group' }, ...query, _id: index }));\n  const currentQueryData = defaultQueryBuilder?.[currentResponseId];\n\n  const onChange = (immutableTree, configData) => {\n    // Tip: for better performance you can apply `throttle` - see `examples/demo`\n    currentQueryData.filterJson = QbUtils.getTree(immutableTree, false); // For Retrieve when update\n    currentQueryData.filter = QbUtils.mongodbFormat(immutableTree, configData);\n    setValue('nestedQueryBuilder', defaultQueryBuilder?.map((qb) => (qb._id === currentResponseId ? currentQueryData : qb)));\n  };\n\n  return (\n    <Query\n      // eslint-disable-next-line react/jsx-props-no-spreading\n      {...InitialConfig}\n      fields={queryJson}\n      value={QbUtils.loadTree(currentQueryData.filterJson)}\n      onChange={onChange}\n      renderBuilder={RenderBuilder}\n    />\n\n  );\n});\n\nexport const NestedQueryBuilder = () => {\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const { setResponseId } = useQueryResponse();\n  const { selectedModelId, editRouteData } = useRoute();\n  const methods = useFormContext();\n  const {\n    watch, setValue,\n  } = methods;\n\n  const modelList = useSelector(({ models }) => (models.modelList.map((d) => ({ ...d, queryJson: recursiveTree({ ...defaultAttributes[ormType], ...d.schemaJson }) }))));\n\n  // eslint-disable-next-line no-nested-ternary\n  const defaultQueryBuilder = watch('nestedQueryBuilder') ? watch('nestedQueryBuilder') : editRouteData?.nestedQueryBuilder?.map((query, index) => ({\n    // eslint-disable-next-line no-nested-ternary\n    filterJson: { id: Math.random(), type: 'group' }, ...query, _id: index, filter: query?.filter ? (typeof query?.filter === typeof 'string' ? JSON.parse(query?.filter) : query?.filter) : undefined,\n  }));\n  const currentQueryData = defaultQueryBuilder?.[0] ?? {};\n\n  React.useEffect(() => {\n    const queryBuilderData = defaultQueryBuilder;\n    const newQueryBuilderData = queryBuilderData ? [...queryBuilderData]\n      : [{\n        existingVariable: 'query',\n        _id: 0,\n        filterJson: { id: Math.random(), type: 'group' },\n        modelId: selectedModelId || undefined,\n        model: modelList.find((md) => md._id === selectedModelId)?.name || undefined,\n        platform: editRouteData?.platform,\n        operation: (editRouteData?.method === 'get' && last(editRouteData?.route?.split('/')) === '{{id}}') ? 'SR' : OPERATION_TYPE[editRouteData?.method][last(editRouteData?.route?.split('/'))],\n        operationMode: 'pre',\n        queryMode: 'find',\n      }];\n\n    setValue('nestedQueryBuilder', newQueryBuilderData);\n    setResponseId(newQueryBuilderData.length - 1);\n  }, []);\n\n  return (\n    <>\n      {\n        (!isEmpty(currentQueryData) && !isEmpty(modelList.find((md) => md._id === currentQueryData?.modelId)?.schemaJson)) ? (\n          <>\n            <LabelBox>Query</LabelBox>\n            <NestedQueryBuilderLogic\n              queryJson={modelList.find((md) => md._id === currentQueryData?.modelId)?.queryJson}\n            />\n          </>\n        ) : (\n          <NoData\n            title=\"No attributes available in model.\"\n          />\n        )\n      }\n    </>\n  );\n};\nNestedQueryBuilderLogic.displayName = 'NestedQueryBuilderLogic';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/QueryBuilder.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport {\n  Query, Builder, BasicConfig, Utils as QbUtils,\n} from 'react-awesome-query-builder';\nimport 'react-awesome-query-builder/lib/css/styles.css';\nimport 'react-awesome-query-builder/lib/css/compact_styles.css';\n// import { useSelector } from 'react-redux';\nimport { useFormContext } from 'react-hook-form';\nimport { useQueryResponse } from './ResponseProvider';\n// import { InputCss } from '../../../../../components/Input/inputCss';\n// Choose your skin (ant/material/vanilla):\nconst InitialConfig = BasicConfig; // optional, for more compact styles\n\n// You need to provide your own config. See below 'Config format'\n\nconst RenderBuilder = (props) => (\n  <div className=\"query-builder-container w-full mt-5\">\n    <div className=\"query-builder qb-lite customThemeQueryBuilder\">\n      <Builder {...props} />\n    </div>\n  </div>\n);\nfunction QueryBuilderLogic({ queryJson }) {\n  const { currentResponseId } = useQueryResponse();\n  const { setValue, watch } = useFormContext();\n  const defaultQueryBuilder = watch('queryBuilder');\n  const currentQueryData = defaultQueryBuilder?.[currentResponseId];\n\n  const onChange = (immutableTree, configData) => {\n    // Tip: for better performance you can apply `throttle` - see `examples/demo`\n    currentQueryData.filterJson = QbUtils.getTree(immutableTree, false); // For Retrieve when update\n    currentQueryData.filter = QbUtils.mongodbFormat(immutableTree, configData);\n    setValue('queryBuilder', defaultQueryBuilder?.map((qb) => (qb._id === currentResponseId ? currentQueryData : qb)));\n    // setQuery(immutableTree);\n  };\n\n  return (\n    <Query\n    // eslint-disable-next-line react/jsx-props-no-spreading\n      {...InitialConfig}\n      fields={queryJson}\n      value={QbUtils.loadTree(currentQueryData.filterJson)}\n      onChange={onChange}\n      renderBuilder={RenderBuilder}\n    />\n\n  );\n}\n\nexport default React.memo(QueryBuilderLogic);\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/QueryBuilderDetail.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport { useFormContext } from 'react-hook-form';\nimport { isEmpty } from 'lodash';\nimport { LabelBox, Select } from '../../../../../components';\nimport QueryBuilderLogic from './QueryBuilder';\nimport { useQueryResponse } from './ResponseProvider';\nimport { ORM_TYPE } from '../../../../../constant/Project/applicationStep';\nimport { defaultAttributes } from '../../../../../components/SelectTree';\n\nconst TABLE_TYPES = {\n  [ORM_TYPE.MONGOOSE]: {\n    Email: 'text',\n    String: 'text',\n    Number: 'number',\n    Boolean: 'boolean',\n    Array: 'text', // If blank array than text other select bix\n    JSON: 'text',\n    Mixed: 'text',\n    Date: 'date',\n    Buffer: 'text',\n    Map: 'text',\n    ObjectId: 'text',\n    SingleLine: 'text',\n    MultiLine: 'text',\n    URL: 'text',\n    Decimal: 'number',\n    Percentage: 'number', // slider config add\n  },\n  [ORM_TYPE.SEQUELIZE]: {\n    EMAIL: 'text',\n    STRING: 'text',\n    NUMBER: 'number',\n    BOOLEAN: 'boolean',\n    ARRAY: 'text', // If blank array than text other select bix\n    JSON: 'text',\n    MIXED: 'text',\n    DATE: 'date',\n    BUFFER: 'text',\n    MAP: 'text',\n    OBJECTID: 'text',\n    SINGLELINE: 'text',\n    MULTILINE: 'text',\n    URL: 'text',\n    DECIMAL: 'number',\n    PERCENTAGE: 'number', // slider config add\n    INTEGER: 'number',\n  },\n};\n\nconst validateObject = (data) => {\n  if (!data) return false;\n  return (Object.values(data)?.findIndex((value) => typeof (value) === 'object') > -1);\n};\nconst validateArray = (data) => Array.isArray(data);\n\nexport const recursiveTree = (JsonData) => {\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const object = {};\n  if (!isEmpty(JsonData)) {\n    Object.keys(JsonData).forEach((jsonKey) => {\n      if (jsonKey !== 'type') {\n        object[jsonKey] = {\n          label: jsonKey,\n          // ...(TABLE_TYPES[json[jsonKey]?.type] === 'text' && { excludeOperators: ['proximity'] }),\n          valueSources: ['value'],\n          excludeOperators: ['proximity'],\n          ...(JsonData[jsonKey]?.type === ((ormType === ORM_TYPE.MONGOOSE) ? 'Percentage' : 'PERCENTAGE') && { preferWidgets: ['slider'] }),\n          type: validateArray(JsonData[jsonKey]) ? '!group' : validateObject(JsonData[jsonKey]) ? '!struct' : JsonData[jsonKey]?.type ? TABLE_TYPES[ormType][JsonData[jsonKey]?.type] : 'text',\n          ...(validateObject(JsonData[jsonKey]) && { subfields: recursiveTree(JsonData[jsonKey]) }),\n          ...(validateArray(JsonData[jsonKey]) && { subfields: recursiveTree({ ...JsonData[jsonKey]?.[0] }) }),\n        };\n      }\n    });\n  }\n  return { ...object };\n};\n\nexport const QueryBuilderDetail = () => {\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const modelList = useSelector(({ models }) => (models.modelList.map((d) => ({ ...d, queryJson: recursiveTree({ ...defaultAttributes[ormType], ...d.schemaJson }) }))));\n  const { currentResponseId } = useQueryResponse();\n\n  const methods = useFormContext();\n\n  const {\n    getValues, setValue,\n  } = methods;\n  const defaultQueryBuilder = getValues('queryBuilder');\n  const currentQueryData = defaultQueryBuilder?.[currentResponseId] ?? {};\n  const handleModalChange = (modelId) => {\n    currentQueryData.modelId = modelId || undefined;\n    currentQueryData.model = modelList.find((md) => md._id === modelId)?.name || undefined;\n    currentQueryData.queryMode = 'find';\n    if (!modelId) {\n      currentQueryData.filter = undefined;\n      currentQueryData.filterJson = { id: Math.random(), type: 'group' };\n    }\n    setValue('queryBuilder', defaultQueryBuilder?.map((query) => (query._id === currentResponseId ? currentQueryData : query)));\n  };\n  return (\n    <div className=\"overflow-auto p-5 w-full\">\n      <Select\n        WrapClassName=\"w-6/12\"\n        options={modelList}\n        value={currentQueryData?.modelId}\n        placeholder=\"Select model\"\n        onChange={handleModalChange}\n        label=\"Model\"\n        valueKey=\"_id\"\n        labelKey=\"name\"\n      />\n      <div className=\"mt-10\">\n        <LabelBox>Query</LabelBox>\n        {!isEmpty(modelList.find((md) => md._id === currentQueryData?.modelId)?.schemaJson) ? (\n          <QueryBuilderLogic\n            queryJson={modelList.find((md) => md._id === currentQueryData?.modelId)?.queryJson}\n          />\n        ) : 'No collection available in model.'}\n      </div>\n      {/* <div className=\"mt-10\">\n        <div className=\"flex items-center\">\n          <div className=\"w-4/12\">\n            <LabelBox>Populate</LabelBox>\n          </div>\n          <div className=\"w-8/12 items-center grid grid-cols-2 gap-5\">\n            <Select options={[]} placeholder=\"Select attr\" />\n            <Select options={[]} placeholder=\"Select attr in response\" isMulti />\n          </div>\n        </div>\n        <QueryBuilderLogic />\n      </div> */}\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/QueryBuilderList.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { useFormContext } from 'react-hook-form';\nimport { SidebarList } from '../../../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../../../../components';\nimport { useQueryResponse } from './ResponseProvider';\nimport { useRoute } from '../../RouteProvider';\n\nexport const QueryBuilderList = ({ addModalRef }) => {\n  const methods = useFormContext();\n  const { editRouteData } = useRoute();\n\n  const {\n    watch,\n  } = methods;\n\n  const { currentResponseId, setResponseId } = useQueryResponse();\n  React.useEffect(() => {\n    setResponseId(0);\n  }, []);\n\n  return (\n\n    <SidebarList addClick={() => { addModalRef.current?.showResponseModal(); }} isAddButton style={{ width: '16rem', position: 'inherit' }} title=\"Response\" tooltip=\"Add response\">\n      <Menu iconShape=\"square\" className=\"p-2\">\n        <SidebarMenuList\n          mainMenuList={watch('queryBuilder') || editRouteData.queryBuilder?.map((query, index) => ({ filterJson: { id: Math.random(), type: 'group' }, ...query, _id: index }))}\n          titleKey=\"outputVariable\"\n          onClick={(id) => { setResponseId(id); }}\n          initialSelectedId={currentResponseId}\n        />\n      </Menu>\n    </SidebarList>\n\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/ResponseProvider.js",
    "content": "import React from 'react';\n\nexport const ResponseContext = React.createContext();\n\nconst ResponseProvider = ({ children }) => {\n  const [currentResponseId, setResponseId] = React.useState(0);\n  const value = {\n    currentResponseId,\n    setResponseId,\n  };\n  return <ResponseContext.Provider value={value}>{children}</ResponseContext.Provider>;\n};\nfunction useQueryResponse() {\n  const context = React.useContext(ResponseContext);\n  if (context === undefined) {\n    throw new Error('useSmsData must be used within a SMSProvider');\n  }\n  return context;\n}\n\nexport { ResponseProvider, useQueryResponse };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/index.js",
    "content": "import React from 'react';\nimport { isEmpty } from 'lodash';\nimport { QueryBuilderList } from './QueryBuilderList';\nimport { QueryBuilderDetail } from './QueryBuilderDetail';\nimport './queryBuilder.css';\nimport { BoxLayout, NoData } from '../../../../../components';\nimport { ResponseProvider, useQueryResponse } from './ResponseProvider';\nimport { AddResponse } from './AddResponse';\n\nconst QueryBuilderTab = () => {\n  const { currentResponseId } = useQueryResponse();\n  return <QueryBuilderDetail key={currentResponseId} />;\n};\n\nexport const QueryBuilder = ({ value }) => {\n  const addModalRef = React.useRef();\n\n  return (\n    <div className=\"flex h-full\">\n      <ResponseProvider>\n        {!isEmpty(value) ? (\n          <>\n            <QueryBuilderList addModalRef={addModalRef} />\n            <BoxLayout variant=\"subRight\">\n              <QueryBuilderTab />\n            </BoxLayout>\n          </>\n        )\n          : (\n            <NoData\n              onClick={() => { addModalRef.current?.showResponseModal(); }}\n              btnText=\"Add response\"\n              title=\"No response found\"\n            />\n          )}\n        <AddResponse addModalRef={addModalRef} />\n\n      </ResponseProvider>\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/QueryBuilder/queryBuilder.css",
    "content": ".group{\n    background-color: transparent;\n    border: none;\n}\n.customThemeQueryBuilder .group{\n    background-color: transparent;\n    border: 1px solid var(--color-gray-100);\n    padding: 0.5rem;\n    font-family: var(--font-famliy);\n}\n.qb-lite .group--header:not(:hover) .group--actions{\n    opacity: 1;\n}\n.customThemeQueryBuilder .group--header{\n    justify-content: space-between;\n}\n.customThemeQueryBuilder .group--actions{\n    padding: 0.5rem 0;\n    border-radius: 3px;\n    background-color: var(--color-gray-200);\n    width: max-content;\n    flex: initial;\n}\n.customThemeQueryBuilder .group--actions button{\n    padding: 0.2rem 1rem;\n    font-size: 1rem;\n    font-family: var(--font-famliy);\n    background-color: var(--color-gray-200);\n    cursor: pointer;\n    border-left: 1px solid var(--color-gray-100);\n}\n.customThemeQueryBuilder .group--actions button:first-child{\n    border-left: none;\n}\n.customThemeQueryBuilder .group--actions button:focus{\n    outline: none;\n}\n.customThemeQueryBuilder .group--children.hide--line>.group-or-rule-container>.group-or-rule::before, \n.customThemeQueryBuilder .group--children.hide--line>.group-or-rule-container>.group-or-rule::after,\n.customThemeQueryBuilder .group--children>.group-or-rule-container>.group-or-rule::before, \n.customThemeQueryBuilder .group--children>.group-or-rule-container>.group-or-rule::after{\n    border-color:var(--color-gray-100)\n}\n.customThemeQueryBuilder .rule{\n    background-color: var(--color-gray-200);\n}\n.customThemeQueryBuilder input, \n.customThemeQueryBuilder optgroup, \n.customThemeQueryBuilder select, \n.customThemeQueryBuilder textarea{\n    background-color:var(--color-gray-inputSub);\n    padding: 0.625rem;\n    border-radius: 3px;\n    color: var(--color-text-primary);\n    margin-right: 0.2rem;\n}\n.customThemeQueryBuilder select{\n    min-width: 120px;\n}\n\n.customThemeQueryBuilder select:focus{\n    outline: none;\n}\n.customThemeQueryBuilder select option{\n    border: none;\n}\n.customThemeQueryBuilder .group--conjunctions{\n    display: flex;\n    align-items: center;\n    /* background: var(--color-gray-200); */\n    /* padding: 0.4rem; */\n    font-size: 14px;\n}\n.customThemeQueryBuilder .group--conjunctions label{\n    margin-left: 4px;\n    margin-right: 1.5rem;\n}\n.customThemeQueryBuilder .rule--operator, \n.customThemeQueryBuilder .widget--widget, \n.customThemeQueryBuilder .widget--valuesrc, \n.customThemeQueryBuilder .widget--sep {\n    margin-left: 5px;\n    display: flex;\n    align-items: center;\n}\n.customThemeQueryBuilder .rule--body {\n    display: flex;\n    align-items: center;\n}\n.query-builder{\n    margin: 0;\n}\n.customThemeQueryBuilder .rule--header button{\n    width: 24px;\n    height: 24px;\n    background: var(--color-gray-300);\n    border-radius: 3px;\n    cursor: pointer;\n}\n.customThemeQueryBuilder .widget--widget label{\n    margin-right: 0.2rem;\n}"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddRoutes/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport { last } from 'lodash';\nimport { useSelector } from 'react-redux';\nimport { TabCSs } from '../../../../assets/css/tab';\nimport {\n  BoxLayout,\n  Button,\n  Heading,\n} from '../../../../components';\nimport { QueryBuilder } from './QueryBuilder';\nimport { RouteTabIndexName, useAddRoute } from './AddRouteProvider';\nimport { useAddToggle } from '../AddToggleProvider';\nimport Basic from './Basic';\nimport Advance from './Advance';\nimport { useRoute } from '../RouteProvider';\nimport { useBoolean } from '../../../../components/hooks';\nimport { ModelPermission } from './ModelPermission';\nimport { ROUTE_GENERATE_TYPE } from '../../../../constant/routes';\nimport { NestedQueryBuilder } from './QueryBuilder/NestedQueryBuilder';\nimport { ResponseProvider } from './QueryBuilder/ResponseProvider';\nimport { getModelPermissions } from '../../../../api/models';\n\nexport const AddRoutes = () => {\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const { addModal, hideAddModal } = useAddToggle();\n  const {\n    setTabIndex, handleSave, loadingCallBack, tabIndex, resetData,\n  } = useAddRoute();\n  const { dispatch, editRouteData } = useRoute();\n  const methods = useFormContext();\n  const [loading,,, setToggle] = useBoolean();\n  const { control, reset } = methods;\n\n  const [permissionData, setPermissionData] = React.useState([]);\n\n  React.useEffect(() => {\n    if (!addModal) {\n      dispatch({ type: 'ResetEditRouteData' });\n      // TODO:Make provide\n      setTabIndex(0);\n      resetData();\n      reset();\n    }\n  },\n  [addModal]);\n\n  React.useEffect(() => {\n    if (editRouteData?.type === ROUTE_GENERATE_TYPE.AUTO && editRouteData?.modelId) {\n      getModelPermissions({ applicationId, _id: editRouteData?.modelId })\n        .then((data) => {\n          setPermissionData(data.data?.list?.[0] || []);\n        });\n    }\n  }, [editRouteData]);\n\n  return (\n    addModal && (\n      <BoxLayout variant=\"subRight\">\n        <div className=\"w-full flex flex-col\">\n          <div className=\"w-full flex justify-between items-center px-5 py-3 headTop flex-shrink-0\">\n            <Heading variant=\"h4\" className=\"mr-2\">\n              {editRouteData._id ? 'Edit routes' : 'Add routes'}\n            </Heading>\n            <div className=\"flex justify-end items-center\">\n              <Button\n                onClick={() => {\n                  hideAddModal();\n                  // props.routesListRef.current?.fetchAllModelRoutes();\n                }}\n                type=\"cancel\"\n                size=\"medium\"\n                shape=\"rounded\"\n                variant=\"outline\"\n                className=\"mr-2\"\n              >\n                Cancel\n              </Button>\n              <Button\n                onClick={() => { loadingCallBack(setToggle); handleSave(); }}\n                type=\"submit\"\n                size=\"medium\"\n                shape=\"rounded\"\n                loading={loading}\n              >\n                Save\n              </Button>\n            </div>\n          </div>\n\n          <Tabs selectedTabPanelClassName=\"flex-grow h-0\" className=\"flex-grow flex flex-col\" selectedIndex={tabIndex} selectedTabClassName={TabCSs.selectTab} onSelect={(index) => { setTabIndex(index); }}>\n            <TabList className={`${TabCSs.tabHead} routesTab flex-shrink-0`}>\n              { Object.values(((editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL) === ROUTE_GENERATE_TYPE.MANUAL) ? (RouteTabIndexName[editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL]) : (RouteTabIndexName[editRouteData?.type][editRouteData?.method][['{{id}}', 'list', '{{}}', 'updateBulk'].includes(last(editRouteData?.route?.split('/'))) ? last(editRouteData?.route?.split('/')) : 'default']))?.map((tab) => (\n                <Tab\n                  key={tab}\n                  className={`${TabCSs.tabTitle}`}\n                >\n                  {tab}\n                </Tab>\n              ))}\n            </TabList>\n\n            {/* Tabs for Manual routes */}\n            {(editRouteData?.type ?? ROUTE_GENERATE_TYPE.MANUAL) === ROUTE_GENERATE_TYPE.MANUAL\n              && (\n              <>\n                <TabPanel>\n                  <div className=\"px-5 overflow-auto h-full\">\n                    <Basic />\n                  </div>\n                </TabPanel>\n                <TabPanel>\n                  <div className=\"px-5 overflow-auto h-full\">\n                    <Advance />\n                  </div>\n                </TabPanel>\n                <TabPanel>\n                  <Controller\n                    control={control}\n                    name=\"queryBuilder\"\n                    defaultValue={editRouteData?.queryBuilder?.map((query, index) => ({ filterJson: { id: Math.random(), type: 'group' }, ...query, _id: index }))}\n                      // rules={{ required: true }}\n                    render={(controlProps) => (\n                      <QueryBuilder {...controlProps} />\n                    )}\n                  />\n                </TabPanel>\n              </>\n              )}\n\n            {/* Tabs for Auto generated routes */}\n            {editRouteData?.type === ROUTE_GENERATE_TYPE.AUTO && (\n            <>\n              {(Object.values((RouteTabIndexName[editRouteData?.type][editRouteData?.method][['{{id}}', 'list', '{{}}', 'updateBulk'].includes(last(editRouteData?.route?.split('/'))) ? last(editRouteData?.route?.split('/')) : 'default']))?.includes('Query builder'))\n                    && (\n                    <TabPanel>\n                      <div className=\"overflow-hidden h-full\">\n                        <Controller\n                          control={control}\n                          name=\"nestedQueryBuilder\"\n                          defaultValue={editRouteData.nestedQueryBuilder?.map((query, index) => ({ filterJson: { id: Math.random(), type: 'group' }, ...query, _id: index }))}\n                          // rules={{ required: true }}\n                          render={(controlProps) => (\n                            <ResponseProvider>\n                              <NestedQueryBuilder {...controlProps} />\n                            </ResponseProvider>\n                          )}\n                        />\n                      </div>\n                    </TabPanel>\n                    )}\n              <TabPanel>\n                <div className=\"p-5 overflow-auto h-full\">\n                  <Controller\n                    control={control}\n                    name=\"permissionData\"\n                    defaultValue={permissionData}\n                    render={(controlProps) => (\n                      <ModelPermission {...controlProps} />\n                    )}\n                  />\n                </div>\n              </TabPanel>\n            </>\n            )}\n          </Tabs>\n        </div>\n      </BoxLayout>\n    )\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/AddToggleProvider.js",
    "content": "import React from 'react';\nimport { useBoolean } from '../../../components/hooks';\n\nexport const AddRouteTabContext = React.createContext();\n\nconst AddToggleProvider = ({ children }) => {\n  const [addModal, showAddModal, hideAddModal] = useBoolean(false);\n  const [openModelCount, setOpenModelCount] = React.useState(0);\n\n  React.useEffect(() => {\n    setOpenModelCount(openModelCount + 1);\n  }, [addModal]);\n  const value = {\n    addModal,\n    showAddModal,\n    hideAddModal,\n    openModelCount,\n  };\n  return <AddRouteTabContext.Provider value={value}>{children}</AddRouteTabContext.Provider>;\n};\nfunction useAddToggle() {\n  const context = React.useContext(AddRouteTabContext);\n  if (context === undefined) {\n    throw new Error('useSmsData must be used within a SMSProvider');\n  }\n  return context;\n}\n\nexport { AddToggleProvider, useAddToggle };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/ModuleList/index.js",
    "content": "import React from 'react';\nimport { sortBy, isEmpty, concat } from 'lodash';\nimport { Menu, MenuItem } from 'react-pro-sidebar';\nimport { useSelector } from 'react-redux';\nimport { SidebarList } from '../../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuListCss } from '../../../../components/SidebarMenuList/sidebarMenuListCss';\nimport { useAddToggle } from '../AddToggleProvider';\nimport { useRoute } from '../RouteProvider';\n\nexport const ModuleList = () => {\n  const modelList = useSelector((state) => state.models.modelList);\n  const { hideAddModal, addModal } = useAddToggle();\n  const { dispatch, selectedModelId, generalizedModel } = useRoute();\n\n  React.useEffect(() => {\n    const randomObject = { name: 'General', _id: Math.random().toString() };\n\n    isEmpty(generalizedModel) && dispatch({ type: 'SetGeneralizedModel', payload: randomObject });\n\n    isEmpty(modelList) ? dispatch({ type: 'SetSelectionModel', payload: generalizedModel }) : dispatch({ type: 'SetSelectionModel', payload: modelList?.[0] });\n  }, [modelList]);\n\n  return (\n    <SidebarList\n      style={{ top: '0' }}\n      isAddButton={false}\n      title=\"Models\"\n    >\n      <Menu iconShape=\"square\" className=\"p-2\">\n        {concat(sortBy(modelList, ['name']), [generalizedModel])?.map((model) => (\n          <MenuItem\n            key={`model${model._id}`}\n            onClick={() => {\n              if (addModal)hideAddModal();\n              dispatch({ type: 'SetSelectionModel', payload: model });\n            }}\n            className={`${SidebarMenuListCss.menuList} ${\n              selectedModelId === model._id && SidebarMenuListCss.menuActive\n            }`}\n          >\n            <span\n              className={`text-primary-text text-sm ${\n                selectedModelId === model._id && 'text-defaultWhite'\n              }`}\n            >\n              {model?.name}\n            </span>\n          </MenuItem>\n        ))}\n      </Menu>\n    </SidebarList>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/RouteProvider.js",
    "content": "import React from 'react';\n\nexport const RouteContext = React.createContext();\n\nfunction selectionReducer(state, { type, payload = {} }) {\n  switch (type) {\n    case 'SetGeneralizedModel': {\n      // Set generalized model data\n      return { ...state, generalizedModel: payload };\n    }\n    case 'SetSelectionModel': {\n      // For selected model id set\n      return { ...state, selectedModelId: payload?._id };\n    }\n    case 'SetEditRouteData': {\n      // For selected Route EditData\n      return { ...state, editRouteData: payload };\n    }\n    case 'ResetEditRouteData': {\n      return { ...state, editRouteData: {} };\n    }\n    case 'SetRouteList': {\n      // Set routeList\n      return { ...state, routeList: payload };\n    }\n    case 'AddRoute': {\n      // Add new Route List\n      const { routeList } = state;\n      routeList.unshift({ ...payload });\n      return { ...state, routeList };\n    }\n    case 'EditRoute': {\n      // Edit new Route List\n      const routeList = state.routeList.map((route) => {\n        if (route._id === payload._id) {\n          return payload;\n        }\n        return route;\n      });\n      return { ...state, routeList };\n    }\n\n    case 'DeleteRoute': {\n      return { ...state, routeList: state.routeList.filter((route) => route._id !== payload._id) };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\n\nconst RouteProvider = ({ children }) => {\n  const [stateData, dispatch] = React.useReducer(selectionReducer, {\n    selectedModelId: '', editRouteData: '', routeList: [], generalizedModel: {},\n  });\n  const value = {\n    generalizedModel: stateData.generalizedModel,\n    selectedModelId: stateData.selectedModelId,\n    editRouteData: stateData.editRouteData,\n    routeList: stateData.routeList,\n    dispatch,\n  };\n  return <RouteContext.Provider value={value}>{children}</RouteContext.Provider>;\n};\nfunction useRoute() {\n  const context = React.useContext(RouteContext);\n  if (context === undefined) {\n    throw new Error('useRoute must be used within a RouteProvider');\n  }\n  return context;\n}\n\nexport { RouteProvider, useRoute };\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/RouteView/Route.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 5)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          className=\"mt-5\"\n          width=\"100%\"\n          height=\"50px\"\n          // viewBox=\"0 0 100% 50px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"80px\" height=\"6\" />\n          <rect x=\"110\" y=\"8\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n          <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"50%\" height=\"6\" />\n\n          <rect x=\"90%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          <rect x=\"95%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/RouteView/index.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { deleteModelRoute, getModelRoutes } from '../../../../api/routes';\nimport {\n  Description,\n  Heading,\n  Button,\n  ListBoxWrap,\n  SearchBox,\n  IconBox,\n  DropdownMenu,\n  Checkbox,\n  LinkTag,\n  NoData,\n  ConfirmationAlert,\n  Select,\n  BoxLayout,\n} from '../../../../components';\nimport Spinner from './Route.loader';\nimport { useBoolean } from '../../../../components/hooks';\nimport { ROUTE_TYPES, ROUTE_GENERATE_TYPE } from '../../../../constant/routes';\nimport { useAddToggle } from '../AddToggleProvider';\nimport { useRoute } from '../RouteProvider';\nimport { useToastNotifications } from '../../../hooks';\nimport { getApplicationPlatforms } from '../../../../utils/applicationPlatform';\n\nexport const RoutesView = React.forwardRef(({\n  applicationId,\n}, ref) => {\n  const projectDetail = useSelector((state) => state.projects.currentProjectDetail);\n  const applicationLoginAccess = projectDetail?.applicationList?.find((d) => d._id === applicationId)?.configInput?.platform;\n  const searchKeywords = React.useRef('');\n  const [routeFilters, setRouteFilters] = React.useState([]);\n  const [platformFilters, setPlatformFilters] = React.useState([]);\n  const [loader, setLoader, hideLoader] = useBoolean(false);\n  const { showAddModal, addModal } = useAddToggle();\n  const {\n    dispatch, selectedModelId, routeList, generalizedModel,\n  } = useRoute();\n  const isResetFilterFlag = React.useRef(null);\n  const { addErrorToast } = useToastNotifications();\n\n  function fetchAllModelRoutes(data = {}) {\n    const {\n      search = searchKeywords.current,\n      platformsFilterData = platformFilters,\n      routeFilterData = routeFilters,\n    } = data;\n    setLoader();\n    getModelRoutes({\n      applicationId,\n      ...(!isEmpty(search) && { search: { keyword: search.trim(), keys: ['route'] } }),\n      find: { modelId: (selectedModelId === generalizedModel?._id) ? null : selectedModelId, ...(!isEmpty(routeFilterData) && { method: routeFilterData }) },\n      ...(!isEmpty(platformsFilterData) && { in: [{ platform: platformsFilterData }] }),\n    }).then(\n      (routeRes) => {\n        dispatch({ type: 'SetRouteList', payload: routeRes?.data?.list });\n        // setAppRoutes(routeRes?.data?.list || []);\n        hideLoader();\n      },\n    )\n      .catch(addErrorToast).finally(hideLoader);\n  }\n\n  function handleRouteFilters(value) {\n    let newRouteFilter = routeFilters;\n    if (value && isResetFilterFlag.current === null) {\n      if (!routeFilters.includes(value)) {\n        newRouteFilter = [...newRouteFilter, value];\n      } else {\n        newRouteFilter = newRouteFilter.filter((oldRouteFilter) => oldRouteFilter !== value);\n      }\n      fetchAllModelRoutes({ routeFilterData: newRouteFilter });\n      setRouteFilters(newRouteFilter);\n    }\n  }\n  React.useEffect(() => {\n    searchKeywords.current = '';\n    setPlatformFilters([]);\n    setRouteFilters([]);\n    if (selectedModelId) fetchAllModelRoutes({ platformsFilterData: [], routeFilterData: [] });\n    // setHeight();\n  }, [selectedModelId]);\n  const setEditData = (route) => {\n    dispatch({ type: 'SetEditRouteData', payload: route });\n    showAddModal();\n  };\n  React.useEffect(() => {\n    isResetFilterFlag.current = null;\n  }, [routeFilters]);\n  React.useImperativeHandle(ref, () => ({ fetchAllModelRoutes }));\n  return (\n\n    !addModal && (\n    <BoxLayout variant=\"subRight\">\n      <div className=\"w-full flex flex-col\">\n        <div className=\"px-5 py-3 pb-0 flex justify-between headTop flex-shrink-0\">\n          <div className=\"flex items-center\">\n            <Heading variant=\"h4\" className=\"mr-2\">\n              Routes\n            </Heading>\n            {/* <Tag variant=\"active\" title=\"Active\" /> */}\n          </div>\n          <div className=\"flex items-center\">\n            <SearchBox\n              className=\"w-40\"\n              key={selectedModelId}\n              placeholder=\"Search..\"\n              onSearch={(search) => {\n                if (searchKeywords.current !== search.trim()) fetchAllModelRoutes({ search });\n                searchKeywords.current = search.trim();\n              }}\n            />\n            <div className=\"ml-2 w-56\">\n              <Select\n                sizeMedium\n                options={getApplicationPlatforms(applicationLoginAccess)} // to fetch all the platforms\n                value={platformFilters}\n                onChange={(platformsFilterData) => {\n                  setPlatformFilters(platformsFilterData);\n                  fetchAllModelRoutes({ platformsFilterData });\n                }}\n                placeholder=\"Select Platform\"\n                isMulti\n              />\n            </div>\n            <DropdownMenu\n            // wrapClass={memberCss.filterDropdown}\n              position=\"right\"\n              placeholder={() => (\n                <IconBox size=\"medium\" variant=\"primary\" shape=\"rounded\" icon={<Icons.Filter color=\"#fff\" />} className=\"ml-2\" tooltip=\"Filter\" />\n              )}\n              className=\"h-full flex items-center\"\n              dropdownMenu=\"h-auto smallCheckbox\"\n            >\n              <div className=\"flex justify-between\">\n                <Heading variant=\"h6\">Filter</Heading>\n                <LinkTag\n                  onClick={() => {\n                    isResetFilterFlag.current = [];\n                    // To set empty filter as well as stop multiple call\n                    setRouteFilters([]);\n                    if (!isEmpty(routeFilters))fetchAllModelRoutes({ routeFilterData: [] });\n                  }}\n                >\n                  Reset filter\n                </LinkTag>\n              </div>\n              <hr className=\"mt-2 mb-2\" />\n              <div className=\"gap-2 grid grid-cols-2\">\n                {\n                ROUTE_TYPES.map((route) => (\n                  <Checkbox\n                    checked={routeFilters.includes(route.id)}\n                    key={route.id}\n                    onChange={() => { handleRouteFilters(route.id); }}\n                  >\n                    {route?.name}\n                  </Checkbox>\n                ))\n              }\n              </div>\n            </DropdownMenu>\n            <Button\n              onClick={showAddModal}\n              variant=\"primary\"\n              size=\"medium\"\n              className=\"ml-2\"\n              shape=\"rounded\"\n            >\n              Add route\n            </Button>\n          </div>\n        </div>\n        <div className=\"p-5 pt-0 overflow-auto flex-grow\">\n          <div className=\"grid grid-cols-1 mt-5\">\n            {loader && <Spinner />}\n            { !loader && (\n              <>\n                { !isEmpty(routeList)\n                  ? routeList.map((route) => (\n                    <SingleRoute\n                      route={route}\n                      editRoute={() => setEditData(route)}\n                      onDelete={() => { dispatch({ type: 'DeleteRoute', payload: route }); }}\n                      key={route?._id}\n                    />\n                  ))\n                  : (\n                    <div style={{ minHeight: 'calc(100vh - 215px)' }} className=\"flex items-center h-full\">\n                      <NoData title=\"No routes found\" />\n                    </div>\n                  )}\n              </>\n            )}\n          </div>\n        </div>\n      </div>\n    </BoxLayout>\n    )\n  );\n});\nRoutesView.displayName = 'RoutesView';\nconst SingleRoute = React.memo(({ route, editRoute, onDelete }) => {\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const [isDelete, setIsDelete] = React.useState(false);\n\n  const { addSuccessToast } = useToastNotifications();\n  const [deleteLoader, setDeleteLoader, hideDeleteLoader] = useBoolean(false);\n\n  const handleSubmit = React.useCallback(() => {\n    setDeleteLoader();\n    deleteModelRoute({\n      id: route._id,\n      isHardDelete: true,\n      definitionType: currentApplicationCode,\n\n    }).then((res) => {\n      onDelete();\n      addSuccessToast(res.message);\n    }).catch(() => {\n    }).finally(hideDeleteLoader);\n  }, [route]);\n\n  const handleDelete = () => {\n    setIsDelete(true);\n  };\n\n  const handleClose = () => {\n    setIsDelete(false);\n  };\n\n  return (\n    <>\n      <ConfirmationAlert isLoading={deleteLoader} isOpen={isDelete} handleSubmit={handleSubmit} handleClose={handleClose} description=\"Route will be deleted permanently and cannot be restored in the future. Are you sure do you want to delete this route?\" />\n\n      <ListBoxWrap variant=\"normal\" className=\"flex justify-between items-center\">\n        <div className=\"w-8/12\">\n          <div className=\"flex items-center\">\n            <div className={`methodList mr-2 w-16 text-center flex-shrink-0 ${route.method}`}>{route.method?.toUpperCase()}</div>\n            <LinkTag className=\"ml-1 text-base flex-grow-0 word-break\" whiteText>{route.route}</LinkTag>\n          </div>\n          {route?.description && <Description className=\"mt-2\">{route?.description}</Description>}\n        </div>\n        <div className=\"w-4/12 flex justify-end\">\n          {route?.type === ROUTE_GENERATE_TYPE.MANUAL && (\n          <Button\n            variant=\"outline\"\n            size=\"small\"\n            className=\"ml-2\"\n            shape=\"rounded\"\n            // loading={deleteLoader}\n            onClick={handleDelete}\n          >\n            Delete\n          </Button>\n          )}\n          { !(route?.type === ROUTE_GENERATE_TYPE.AUTO && route?.method === 'put' && route?.route?.endsWith('upsert')) && ( // don't provide edit option for auto generated route with \"put\" method that ends with \"upsert\"\n            <Button\n              onClick={editRoute}\n              variant=\"primary\"\n              size=\"small\"\n              className=\"ml-2\"\n              shape=\"rounded\"\n            >\n              Edit\n            </Button>\n          )}\n        </div>\n      </ListBoxWrap>\n    </>\n  );\n});\nSingleRoute.displayName = 'SingleRoute';\n"
  },
  {
    "path": "packages/client/src/container/CRUD/Routes/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport * as React from 'react';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { unwrapResult } from '@reduxjs/toolkit';\nimport { isEmpty } from 'lodash';\nimport { useHistory } from 'react-router';\nimport { AddRoutes } from './AddRoutes';\nimport { RoutesView } from './RouteView';\nimport { ModuleList } from './ModuleList';\nimport { BoxLayout, StepFooter } from '../../../components';\nimport Spinner from './RouteView/Route.loader';\nimport { listModels } from '../../../redux/thunks/models';\nimport { useBoolean } from '../../../components/hooks';\nimport { AddToggleProvider, useAddToggle } from './AddToggleProvider';\nimport { RouteProvider, useRoute } from './RouteProvider';\nimport { AddRouteTabProvider } from './AddRoutes/AddRouteProvider';\nimport LayoutStepUrl from '../../Shared/LayoutStepUrl';\nimport { StepHeader } from '../../Shared/Layout/StepHeader';\nimport { encryptStorage } from '../../../utils/localStorage';\nimport { LAYOUT_STEP_MODULE_NAME, RedirectUrl } from '../../../constant/Nodecrud';\nimport { BuildCodeStructure } from '../BuildCodeStructure';\nimport { getModelRoutes } from '../../../api/routes';\nimport { useToastNotifications } from '../../hooks';\nimport { codeGenerator } from '../../../redux/thunks/buildCode';\n\nconst RouteFooter = () => {\n  // to hide footer in add popup\n  const {\n    isBuildLoading, buildArchitecture, generatedId, applicationId, currentApplicationCode, modelList,\n  } = useSelector(({ models, buildCode, projects }) => ({\n    buildArchitecture: buildCode.buildArchitecture,\n    generatedId: buildCode.generatedId,\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n    modelList: models.modelList,\n    isBuildLoading: buildCode.isBuildLoading,\n  }), shallowEqual);\n  const history = useHistory();\n  const openBuildRef = React.useRef();\n  const { addModal } = useAddToggle();\n  const { routeList } = useRoute();\n\n  // to disable Create build button\n  const [hasRoutes, setHasRoutes, unsetHasRoutes] = useBoolean(true);\n\n  const { addErrorToast } = useToastNotifications();\n  const dispatch = useDispatch();\n  React.useEffect(() => {\n    if (isEmpty(modelList)) {\n      getModelRoutes({ applicationId, find: { modelId: null } }).then((routesRes) => {\n        isEmpty(routesRes?.data?.list) ? unsetHasRoutes() : setHasRoutes();\n      }).catch(addErrorToast);\n    }\n  }, [modelList, addModal, routeList]);\n\n  return (\n    !addModal && (\n    <>\n      <StepFooter\n        backClick={() => {\n          history.push(RedirectUrl[currentApplicationCode].route.previousUrl);\n        }}\n        nextClick={() => {\n          generatedId ? dispatch(codeGenerator({ applicationId, projectType: buildArchitecture }))\n            : openBuildRef.current?.handelOpen();\n        }}\n        Back=\"Previous\"\n        Next=\"Create Build\"\n        nextLoading={isBuildLoading}\n        isNextDisable={isEmpty(modelList) ? !hasRoutes : false}\n      />\n      <BuildCodeStructure openBuildRef={openBuildRef} />\n    </>\n    )\n  );\n};\n\nexport default function Routes() {\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const [loader, setLoader, hideLoader] = useBoolean(false);\n\n  const dispatch = useDispatch();\n  const routesListRef = React.useRef();\n\n  React.useEffect(() => {\n    setLoader();\n    dispatch(listModels({ applicationId })).then(unwrapResult)\n      .finally(hideLoader);\n  }, []);\n\n  const handleSubmit = () => {\n    routesListRef.current?.fetchAllModelRoutes();\n  };\n\n  React.useEffect(() => () => {\n    // Remove\n    // to maintain remove toggle from sidebar when crud in url\n    !window.location.pathname.includes('crud') && encryptStorage.remove('sidebarToggle');\n  }, []);\n\n  return (\n    <div className=\"flex flex-col h-screen\">\n      <StepHeader backTitle=\"Back to screen\" headTitle=\"CRUD\" link={RedirectUrl[currentApplicationCode].route.backScreenUrl} />\n      <LayoutStepUrl isOpenBigLayout={false} isBuildShow moduleName={LAYOUT_STEP_MODULE_NAME[currentApplicationCode]}>\n\n        {/* Context for  Route Selection and routeList Data Manage */}\n        <RouteProvider>\n          {/* Context for  Add  Route Toggle */}\n          <AddToggleProvider>\n            <div className=\"flex flex-grow h-0\">\n\n              <ModuleList />\n\n              {loader && (\n                <BoxLayout variant=\"subRight\" className=\"sm:h-auto\">\n                  <div className=\"w-full\">\n                    <Spinner />\n                  </div>\n                </BoxLayout>\n              )}\n\n              {!(loader) && (\n\n              <RoutesView\n                applicationId={applicationId}\n                ref={routesListRef}\n              />\n              )}\n\n              {/* Context for  Add  Route Tab Provider */}\n              <AddRouteTabProvider>\n                <AddRoutes\n                  handleSubmit={handleSubmit}\n                  routesListRef={routesListRef}\n                />\n              </AddRouteTabProvider>\n\n            </div>\n            <RouteFooter />\n          </AddToggleProvider>\n        </RouteProvider>\n      </LayoutStepUrl>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/CodeGenConfigHelperFunctions.js",
    "content": "import { isEmpty, compact } from 'lodash';\nimport { QUERY_PARAMETER_SUPPORTED_TYPES } from '../../../constant/applicationConfigConstant';\n\nexport const getSelectedPlatformObject = (selectedPlatforms, platformAccess) => {\n  // to create selected platform object (used in two factor authentication)\n  const output = {};\n  selectedPlatforms?.forEach((platform) => { output[platform] = platformAccess?.includes(platform); });\n  return output;\n};\n\n// to get fields name\nexport const getFieldName = (mastersList, id) => mastersList?.find((master) => master._id === id)?.customJson?.fieldName;\n\nexport const getMediumObject = (selectedMediums, mastersList, updatedData, templatesList, templateType) => {\n  // to create selected medium object (used in two factor authentication and reset password link)\n  const output = {};\n  if (!isEmpty(selectedMediums)) { output.masterIds = selectedMediums; }\n  selectedMediums?.forEach((medium) => {\n    output[getFieldName(mastersList, medium)] = true;\n    output[`${getFieldName(mastersList, medium)}TemplateId`] = updatedData?.[`${templateType}-${medium}`];\n    output[`${getFieldName(mastersList, medium)}Template`] = templatesList?.find((template) => template?._id === updatedData?.[`${templateType}-${medium}`])?.name;\n  });\n  return output;\n};\n\nexport const getCustomJson = (customJson, updatedData, sub) => {\n  // to create dynamic object of input fields' data (used in notification provider and social auth)\n  const output = {};\n  customJson?.forEach((json) => {\n    output[json?.fieldName] = updatedData?.[`${json?.fieldName}-${sub?._id}`] || '';\n  });\n  return output;\n};\n\nexport const getSocialAuthData = (socialMastersList, updatedData) => {\n  // to create social auth request data (used in social auth)\n  const output = [];\n  socialMastersList?.forEach((master) => {\n    const obj = {};\n    obj.typeId = master?._id;\n    obj.type = master?.code;\n    obj.platform = updatedData?.[`platform-${master?._id}-selection`] ? updatedData?.[`platform-${master?._id}`] : [];\n    obj.isChecked = updatedData?.[`platform-${master?._id}-selection`] || false;\n    obj.credential = updatedData?.[`platform-${master?._id}-selection`] ? getCustomJson(master?.customJson, updatedData, master) : {};\n    output.push(obj);\n  });\n  return output;\n};\n\nexport const getServiceProvideData = (mastersList, updatedData) => {\n  // to create external service provider request data (used in notification provider)\n  const output = [];\n  mastersList?.forEach((master) => master?.subMaster?.forEach((sub) => {\n    if (sub?._id === updatedData?.[`notification-${sub?.parentCode}`]) {\n      const obj = {};\n      obj.typeId = sub?.parentId;\n      obj.type = sub?.parentCode;\n      obj.serviceProviderId = sub?._id;\n      obj.serviceProvide = sub?.name;\n      obj.customJson = getCustomJson(sub?.customJson, updatedData, sub);\n      output.push(obj);\n    }\n  }));\n  return output;\n};\n\n// to prepare list of supported data types for Query parameters accroding to selected model\nexport const prepareQueryParameters = (schemaJSON, ormType) => {\n  const result = {};\n\n  if (!isEmpty(schemaJSON)) {\n    Object.keys(schemaJSON)?.forEach((key) => {\n      if (QUERY_PARAMETER_SUPPORTED_TYPES[ormType]?.includes(schemaJSON[key]?.type)) {\n        result[key] = schemaJSON[key];\n      }\n      if (Array.isArray(schemaJSON[key])) {\n        result[key] = prepareQueryParameters(schemaJSON[key][0], ormType);\n        return;\n      }\n      if (compact(Object.values(schemaJSON[key]))?.findIndex((value) => typeof (value) === 'object') > -1) {\n        result[key] = prepareQueryParameters(schemaJSON[key], ormType);\n      }\n    });\n  }\n  return result;\n};\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/CodeGenerateConfiguration.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 1)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          width=\"100%\"\n          height=\"350px\"\n          // viewBox=\"0 0 100% 350px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"2%\" y=\"12\" rx=\"3\" ry=\"3\" width=\"25%\" height=\"300\" />\n          <rect x=\"30%\" y=\"12\" rx=\"3\" ry=\"3\" width=\"70%\" height=\"300\" />\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/DataFormatConfig/AddDataFormat.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport Drawer from 'rc-drawer';\nimport {\n  capitalize, cloneDeep, isEmpty, omit, toLower,\n} from 'lodash';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport omitDeep from 'omit-deep-lodash';\nimport {\n  DrawerClose, DrawerHead, Radio, RadioGroup, Input, Select, DrawerFooter, SelectTree,\n} from '../../../../components';\nimport {\n  ATTRIBUTE_FORMAT_DATA_TYPE, MODEL_TYPE, DATE_OPTIONS, STR_OPERATORS,\n} from '../../../../constant/applicationConfigConstant';\nimport { getError } from '../../../../utils/validationMsgs';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../constant/common';\nimport { useToastNotifications } from '../../../hooks';\n\nconst options = [\n  { name: capitalize(ATTRIBUTE_FORMAT_DATA_TYPE.DATE), id: ATTRIBUTE_FORMAT_DATA_TYPE.DATE },\n  { name: capitalize(ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN), id: ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN },\n  { name: capitalize(ATTRIBUTE_FORMAT_DATA_TYPE.STRING), id: ATTRIBUTE_FORMAT_DATA_TYPE.STRING },\n];\n\n// const dateOpts = DATE_OPTIONS.map((x) => ({ id: x, name: x }));\nconst strOperatorOpts = STR_OPERATORS.map((x) => ({ id: x, name: x }));\n\nconst DEFAULT_KEYS = {\n  title: '',\n  dataType: ATTRIBUTE_FORMAT_DATA_TYPE.DATE,\n  isAllModels: MODEL_TYPE.ALL,\n  modelId: '',\n  targetAttr: '',\n  operand1: null,\n  operator: null,\n  operand2: null,\n  true: '',\n  false: '',\n  attribute: null,\n};\n\nexport const AddDataFormat = ({\n  isOpen, onClose, editData, onSubmit, loading,\n}) => {\n  const { modelList } = useSelector(({ models }) => ({\n    modelList: models.modelList,\n  }), shallowEqual);\n  const { addErrorToast } = useToastNotifications();\n  const buttonRef = React.useRef('');\n\n  const methods = useFormContext();\n  const {\n    errors, control, watch, handleSubmit, setValue, clearErrors,\n  } = methods;\n\n  React.useEffect(() => {\n    if (editData) {\n      // edit data\n      const {\n        title, isAllModels, dataType, attribute, targetAttr, operator, modelId,\n      } = editData;\n      setValue('title', title);\n      setValue('dataType', dataType);\n      setValue('isAllModels', isAllModels ? MODEL_TYPE.ALL : MODEL_TYPE.SINGLE);\n      setValue('modelId', modelId);\n      if (dataType === ATTRIBUTE_FORMAT_DATA_TYPE.DATE) { setValue('attribute', attribute); }\n      if (dataType === ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN) {\n        setValue('true', attribute?.true);\n        setValue('false', attribute?.false);\n      }\n      if (dataType === ATTRIBUTE_FORMAT_DATA_TYPE.STRING) {\n        setValue('operand1', attribute?.[0]);\n        setValue('operand2', attribute?.[1]);\n        setValue('operator', operator);\n        setValue('targetAttr', targetAttr);\n      }\n    } else {\n      setValue('isAllModels', MODEL_TYPE.ALL);\n      setValue('dataType', ATTRIBUTE_FORMAT_DATA_TYPE.DATE);\n    }\n  }, [editData]);\n\n  // React.useMemo(() => {\n  //   if (watch('isAllModels') && !editData) {\n  //     // set default data type while add\n  //     if (!watch('dataType') && watch('isAllModels') === MODEL_TYPE.SINGLE) { setValue('dataType', ATTRIBUTE_FORMAT_DATA_TYPE.STRING); }\n  //     if (watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.STRING && watch('isAllModels') === MODEL_TYPE.ALL) { setValue('dataType', ATTRIBUTE_FORMAT_DATA_TYPE.DATE); }\n  //   }\n  // }, [editData, watch('isAllModels')]);\n\n  React.useMemo(() => {\n    if (!isEmpty(errors)) {\n      // clear errors on type change\n      const type = watch('dataType');\n      Object.keys(errors).forEach((x) => {\n        if (type === ATTRIBUTE_FORMAT_DATA_TYPE.DATE) {\n          const resetErrArr = ['targetAttr', 'operand1', 'operand2', 'operator', 'true', 'false'];\n          resetErrArr.includes(x);\n          clearErrors(resetErrArr);\n        } else if (type === ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN) {\n          const resetErrArr = ['targetAttr', 'operand1', 'operand2', 'operator', 'attribute'];\n          resetErrArr.includes(x);\n          clearErrors(resetErrArr);\n        } else if (type === ATTRIBUTE_FORMAT_DATA_TYPE.STRING) {\n          const resetErrArr = ['true', 'false', 'attribute'];\n          resetErrArr.includes(x);\n          clearErrors(resetErrArr);\n        }\n      });\n    }\n  }, [watch('dataType')]);\n\n  React.useMemo(() => {\n    if (!isEmpty(errors) && watch('isAllModels') === MODEL_TYPE.ALL) {\n      // clear errors on model change\n      const isModelErr = Object.keys(errors).find((x) => x === 'modelId');\n      if (isModelErr) { clearErrors(['modelId']); }\n    }\n  }, [watch('isAllModels')]);\n\n  const handleChaneModelType = (val) => {\n    if (watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.STRING && val === MODEL_TYPE.ALL) {\n      setValue('dataType', ATTRIBUTE_FORMAT_DATA_TYPE.DATE);\n    }\n  };\n\n  const handleChangeModel = () => {\n    if (watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.STRING) {\n      setValue('operand1', null);\n      setValue('operand2', null);\n    }\n  };\n\n  const getOp2Opts = React.useMemo(() => {\n    //  attribute that is selected in first dropdown should be excluded from second dropdown\n    let obj = { ...modelList?.find((model) => model?._id === watch('modelId'))?.schemaJson } || {};\n    if (!isEmpty(obj)) {\n      obj = omitDeep(obj, [watch('operand1'), 'password', 'PASSWORD', 'Password']);\n    }\n    return obj;\n  }, [watch('operand1')]);\n\n  const getOp1Opts = React.useMemo(() => {\n    let obj = { ...modelList?.find((model) => model?._id === watch('modelId'))?.schemaJson } || {};\n    if (!isEmpty(obj)) {\n      obj = omitDeep(obj, ['password', 'PASSWORD', 'Password']);\n    }\n    return obj;\n  }, [watch('modelId')]);\n\n  const checkDuplicateKey = (data, obj, key = 'title') => {\n    const isExist = data?.responseFormatter?.find((x) => {\n      if (!editData) { return toLower(x[key]) === toLower(obj[key]); } // while add\n      if (editData[key] !== x[key]) return toLower(x[key]) === toLower(obj[key]); // while edit\n      return false;\n    });\n    if (isExist) { return addErrorToast('Title already exists.'); }\n    return true;\n  };\n\n  const checkDuplicateDataType = (data, obj) => {\n    const isExist = data?.responseFormatter?.find((x) => {\n      const modelCondi = obj.isAllModels ? x.isAllModels === obj.isAllModels : x.modelId === obj.modelId;\n      let condi = x.dataType === obj.dataType && modelCondi;\n\n      if (obj.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.STRING) {\n        const strCondi = x.targetAttr === obj.targetAttr;\n        // const strCondi = x.operator === obj.operator && isEqual(x.attribute, obj.attribute) && x.taregetAttr === obj.taregetAttr;\n        condi = condi && strCondi;\n      }\n      if (!editData) { return condi; } // while add\n      if (editData.title !== x.title) return condi; // while edit\n      return false;\n    });\n    if (isExist) { return addErrorToast('Record already exists.'); }\n    return true;\n  };\n\n  const resetFields = (isDefault) => {\n    Object.keys(DEFAULT_KEYS).map((x) => {\n      setValue(x, isDefault ? DEFAULT_KEYS[x] : undefined);\n      return x;\n    });\n  };\n\n  const handleCancel = () => {\n    resetFields();\n    onClose();\n    buttonRef.current = null;\n  };\n\n  const handleSave = (params, name) => {\n    let data = { ...params };\n    const obj = {\n      title: data.title,\n      isAllModels: data.isAllModels === MODEL_TYPE.ALL,\n      dataType: data.dataType,\n    };\n    if (!checkDuplicateKey(data, obj)) return; // validate unique title\n    if (!obj.isAllModels) { obj.modelId = data.modelId; }\n    if (data.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.DATE) {\n      obj.attribute = data.attribute;\n    }\n    if (data.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN) {\n      obj.attribute = { true: data.true, false: data.false };\n    }\n    if (!obj.isAllModels && data.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.STRING) {\n      // single model\n      obj.targetAttr = data.targetAttr;\n      obj.operator = data.operator;\n      obj.attribute = [data.operand1, data.operand2];\n    }\n    if (!checkDuplicateDataType(data, obj)) return; // validate unique data type model wise\n\n    data = omit(data, Object.keys(DEFAULT_KEYS));\n    if (editData) {\n      const index = data.responseFormatter?.findIndex((x) => x.title === editData.title);\n      data.responseFormatter[index] = obj;\n    } else {\n      const temp = cloneDeep(data.responseFormatter || []);\n      temp.push(obj);\n      data.responseFormatter = temp;\n    }\n    data.responseFormatter = data?.responseFormatter?.map((x) => omit(x, 'model'));\n    buttonRef.current = name;\n    onSubmit(data, () => {\n      if (name === 'save') {\n        handleCancel();\n      } else if (name === 'next') resetFields(true);\n    }, !editData, !!editData); // pass value to isCreate and isUpdate flags\n  };\n\n  return (\n    <Drawer\n      open={isOpen}\n      onClose={handleCancel}\n      handleCancel={handleCancel}\n      ease\n      level={null}\n      handler={false}\n      placement=\"right\"\n      wrapperClassName=\"\"\n    >\n      <DrawerClose onClick={handleCancel} />\n      <DrawerHead title={`${editData ? 'Update' : 'Add'} data format`} />\n      <div className=\"p-5 overflow-auto flex-grow\">\n        <Controller\n          control={control}\n          name=\"title\"\n          rules={{ required: true, maxLength: MAX_INPUT_FIELD_LIMIT.title }}\n          render={(controlProps) => (\n            <Input\n              {...controlProps}\n              placeholder=\"Enter title\"\n              size=\"medium\"\n              label=\"Title\"\n              error={getError(errors, 'title', (errors?.name?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.title : 'Title')}\n            />\n          )}\n        />\n        <div className=\"flex my-5\">\n          <Controller\n            control={control}\n            name=\"isAllModels\"\n            render={(controlProps) => (\n              <RadioGroup\n                {...controlProps}\n                className=\"flex\"\n                selectedValue={controlProps.value}\n                onChange={(val) => {\n                  controlProps.onChange(val);\n                  handleChaneModelType(val);\n                }}\n              >\n                <Radio value={MODEL_TYPE.ALL}>All model</Radio>\n                <Radio value={MODEL_TYPE.SINGLE}>Single model</Radio>\n              </RadioGroup>\n            )}\n          />\n        </div>\n        <div className=\"grid grid-cols-2 gap-5 mb-5\">\n          {watch('isAllModels') === MODEL_TYPE.SINGLE && (\n          <>\n            <div className=\"col-span-2\">\n              <Controller\n                control={control}\n                name=\"modelId\"\n                rules={{ required: true }}\n                render={(controlProps) => (\n                  <Select\n                    {...controlProps}\n                    isClearable={false}\n                    options={modelList?.map((x) => ({ id: x._id, name: x.name }))}\n                    placeholder=\"Select model\"\n                    label=\"Model\"\n                    sizeMedium\n                    onChange={(val) => {\n                      controlProps.onChange(val);\n                      handleChangeModel();\n                    }}\n                    error={getError(errors, 'modelId', 'Model')}\n                  />\n                )}\n              />\n            </div>\n          </>\n          )}\n          <Controller\n            control={control}\n            name=\"dataType\"\n            render={(controlProps) => (\n              <Select\n                {...controlProps}\n                isClearable={false}\n                options={watch('isAllModels') === MODEL_TYPE.ALL ? options.filter((x) => x.id !== ATTRIBUTE_FORMAT_DATA_TYPE.STRING) : options}\n                placeholder=\"Select data type\"\n                label=\"Data type\"\n                sizeMedium\n              />\n            )}\n          />\n          {watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.DATE && (\n            <>\n              <Controller\n                control={control}\n                name=\"attribute\"\n                rules={{ required: true }}\n                render={(controlProps) => (\n                  <Input\n                    {...controlProps}\n                    placeholder=\"Enter format\"\n                    size=\"medium\"\n                    label=\"Format\"\n                    list=\"format\"\n                    autoComplete=\"off\"\n                    error={getError(errors, 'attribute', 'Format')}\n                  />\n                  // <Select\n                  //   {...controlProps}\n                  //   options={dateOpts}\n                  //   placeholder=\"Enter format\"\n                  //   size=\"medium\"\n                  //   label=\"Format\"\n                  //   error={getError(errors, 'attribute', 'Format')}\n                  // />\n                )}\n              />\n              {\n           !isEmpty(watch('attribute'))\n            && (\n              <datalist id=\"format\">\n                {DATE_OPTIONS.map((option) => (\n                  option.toLowerCase().includes(watch('attribute')) && (\n                  <option key={option} value={option}>\n                    {option}\n                  </option>\n                  )\n                ))}\n              </datalist>\n            )\n          }\n            </>\n          )}\n          {watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN && (\n          <div className=\"grid grid-cols-2 gap-5 col-span-2\">\n            <Controller\n              control={control}\n              name=\"true\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Input\n                  {...controlProps}\n                  placeholder=\"Enter true value\"\n                  size=\"medium\"\n                  label=\"True value\"\n                  error={getError(errors, 'true', 'True value')}\n                />\n              )}\n            />\n            <Controller\n              control={control}\n              name=\"false\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Input\n                  {...controlProps}\n                  placeholder=\"Enter false value\"\n                  size=\"medium\"\n                  label=\"False value\"\n                  error={getError(errors, 'false', 'False value')}\n                />\n              )}\n            />\n          </div>\n          )}\n          {watch('dataType') === ATTRIBUTE_FORMAT_DATA_TYPE.STRING && (\n          <>\n            <Controller\n              control={control}\n              name=\"targetAttr\"\n              rules={{ required: true }}\n              render={(controlProps) => (\n                <Input\n                  {...controlProps}\n                  size=\"medium\"\n                  placeholder=\"Enter target\"\n                  label=\"Target\"\n                  sizeMedium\n                  error={getError(errors, 'targetAttr', 'Target attribute')}\n                />\n              )}\n            />\n            <div className=\"grid grid-cols-3 gap-5 mb-5 col-span-2\">\n              <Controller\n                control={control}\n                name=\"operand1\"\n                rules={{ required: true }}\n                render={(controlProps) => (\n                  <SelectTree\n                    {...controlProps}\n                    size=\"medium\"\n                    placeholder=\"Select attribute\"\n                    label=\"Attribute\"\n                    defaultValue={controlProps.value ? [controlProps.value] : []}\n                    mode=\"radioSelect\"\n                    data={getOp1Opts}\n                    handleChange={({ allSelectedNode }) => {\n                      controlProps.onChange(allSelectedNode?.[0]?.fullName);\n                    }}\n                    error={getError(errors, 'operand1', 'Attribute')}\n                  />\n                )}\n              />\n              <Controller\n                control={control}\n                name=\"operator\"\n                rules={{ required: true }}\n                render={(controlProps) => (\n                  <Select\n                    {...controlProps}\n                    options={strOperatorOpts}\n                    placeholder=\"Select operator\"\n                    sizeMedium\n                    label=\"Operator\"\n                    error={getError(errors, 'operator', 'Operator')}\n                  />\n                )}\n              />\n              <Controller\n                control={control}\n                name=\"operand2\"\n                rules={{ required: true }}\n                render={(controlProps) => (\n                  <SelectTree\n                    {...controlProps}\n                    size=\"medium\"\n                    options={options}\n                    placeholder=\"Select attribute\"\n                    label=\"Attribute\"\n                    defaultValue={controlProps.value ? [controlProps.value] : []}\n                    mode=\"radioSelect\"\n                    disabled={!watch('operand1')}\n                    data={getOp2Opts}\n                    handleChange={({ allSelectedNode }) => {\n                      controlProps.onChange(allSelectedNode?.[0]?.fullName);\n                    }}\n                    error={getError(errors, 'operand2', 'Attribute')}\n                  />\n                )}\n              />\n            </div>\n          </>\n          )}\n        </div>\n      </div>\n      <DrawerFooter\n        isAutoFocusOnSave\n        isSaveNext={!editData}\n        cancelTitle=\"Cancel\"\n        handleSubmit={handleSubmit((data) => handleSave(data, 'save'))}\n        handleNextSubmit={handleSubmit((data) => handleSave(data, 'next'))}\n        handleCancel={handleCancel}\n        saveNext={!editData ? 'Save' : ''}\n        submitTitle={!editData ? 'Save & Add more' : 'Update'}\n        isSubmitting={buttonRef?.current === 'next' ? false : loading}\n        isNextSubmitting={buttonRef?.current === 'next' ? loading : false}\n      />\n    </Drawer>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/DataFormatConfig/DataFormat.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 5)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          className=\"mt-5\"\n          width=\"100%\"\n          height=\"50px\"\n          // viewBox=\"0 0 100% 50px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n          <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"50%\" height=\"6\" />\n\n          <rect x=\"90%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          <rect x=\"95%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/DataFormatConfig/Head/index.js",
    "content": "import React from 'react';\nimport { Description, Heading, Button } from '../../../../../components';\n\nexport const Head = ({ handleShow }) => (\n  <div className=\"flex justify-between p-3 w-full items-center\">\n    <div className=\"w-8/12\">\n      <Heading variant=\"h5\">Data format</Heading>\n      <Description className=\"mt-1 xl:text-xs\">\n        Configure a global data format for your model attributes.\n      </Description>\n    </div>\n    <div className=\"w-4/12 flex justify-end\">\n      <Button variant=\"primary\" size=\"medium\" shape=\"rounded\" onClick={handleShow}>Add format</Button>\n    </div>\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/DataFormatConfig/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport { isEmpty, omit } from 'lodash';\nimport { useFormContext } from 'react-hook-form';\nimport Spinner from './DataFormat.loader';\nimport {\n  ListBoxWrap, ListTitle, Button, NoData, ConfirmationAlert,\n} from '../../../../components';\nimport { AddDataFormat } from './AddDataFormat';\nimport { Head } from './Head';\nimport { ATTRIBUTE_FORMAT_DATA_TYPE } from '../../../../constant/applicationConfigConstant';\nimport { useBoolean } from '../../../hooks';\n\nconst DataFormatItem = ({\n  handleShow, handleDelete, itemFormat,\n}) => (\n  <ListBoxWrap className=\"flex justify-between items-center\">\n    <div className=\"mr-5\">\n      <ListTitle smallTitle={`${itemFormat?.title} - ${itemFormat?.isAllModels ? 'All model' : itemFormat?.model?.name}`} />\n      <div className=\"flex flex-wrap items-center\">\n        {itemFormat?.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.STRING\n          && (\n          <>\n            <div className=\"flex mt-1 items-center\">\n              <span className=\"text-body-text text-sm mr-2\">Target:</span>\n              <span className=\"text-xs\">{itemFormat?.targetAttr}</span>\n            </div>\n            <hr className=\"mx-4 w-px h-4 my-1 bg-gray-80 block\" />\n            <div className=\"flex mt-1 items-center\">\n              <span className=\"text-body-text text-sm mr-2\">Concat operator:</span>\n              <span className=\"text-xs\">{itemFormat?.attribute?.join(` ${itemFormat?.operator === 'space' ? '' : itemFormat?.operator} `)}</span>\n            </div>\n          </>\n          )}\n        {itemFormat?.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.BOOLEAN\n        && (\n        <div className=\"flex mt-1 items-center\">\n          <span className=\"text-body-text text-sm mr-2\">Boolean true:</span>\n          <span className=\"text-xs\">\n            {itemFormat?.attribute?.true}\n          </span>\n          <hr className=\"mx-4 w-px h-4 my-1 bg-gray-80 block\" />\n          <span className=\"text-body-text text-sm mr-2\">Boolean false:</span>\n          <span className=\"text-xs\">\n            {itemFormat?.attribute?.false}\n          </span>\n        </div>\n        )}\n        {itemFormat?.dataType === ATTRIBUTE_FORMAT_DATA_TYPE.DATE\n        && (\n        <div className=\"flex mt-1 items-center\">\n          <span className=\"text-body-text text-sm mr-2\">Date:</span>\n          <span className=\"text-xs\">{itemFormat?.attribute}</span>\n        </div>\n        )}\n      </div>\n    </div>\n    <div className=\"flex justify-end\">\n      <Button variant=\"outline\" className=\"mr-2\" shape=\"rounded\" size=\"small\" onClick={handleDelete}>Delete</Button>\n      <Button variant=\"primary\" shape=\"rounded\" size=\"small\" onClick={handleShow}>Edit</Button>\n    </div>\n  </ListBoxWrap>\n);\n\nexport const DataFormatConfig = ({\n  loading, onSubmit,\n}) => {\n  const [isOpen, openPopUp, closePopUp] = useBoolean();\n  const [isDeletePopupOpen, openDeletePopUp, closeDeletePopUp] = useBoolean(false);\n\n  const methods = useFormContext();\n\n  const { watch } = methods;\n\n  const detailRef = React.useRef();\n\n  return (\n    <>\n      <div className=\"flex flex-col h-full\">\n        <Head handleShow={() => {\n          openPopUp();\n        }}\n        />\n        {loading ? <Spinner />\n          : (\n            !isEmpty(watch('responseFormatter')) ? (\n              <div className=\"px-3 overflow-auto flex-grow\">\n                {\n              watch('responseFormatter')?.map((itemFormat) => (\n                <DataFormatItem\n                  key={itemFormat.title}\n                  handleShow={() => {\n                    detailRef.current = itemFormat;\n                    openPopUp();\n                  }}\n                  handleDelete={() => {\n                    detailRef.current = itemFormat;\n                    openDeletePopUp();\n                  }}\n                  itemFormat={itemFormat}\n                />\n              ))\n            }\n              </div>\n            ) : (\n              <NoData\n                title=\"No data found\"\n                description=\"Create a global data format with our many customization options.\"\n              />\n            )\n          )}\n      </div>\n\n      <ConfirmationAlert\n        isOpen={isDeletePopupOpen}\n        description=\"Do you want to delete the selected data format of your model attribute?\"\n        handleSubmit={() => {\n          const updatedData = watch();\n          const updatedResponseFormatter = updatedData?.responseFormatter?.filter((itemFormat) => itemFormat?.title !== detailRef.current?.title);\n          updatedData.responseFormatter = updatedResponseFormatter?.map((itemFormat) => omit(itemFormat, 'model'));\n          onSubmit(updatedData, () => {}, false, false, true); // pass value to callback, isCreate isUpdate and isDelete flags\n          detailRef.current = null;\n          closeDeletePopUp();\n        }}\n        handleClose={closeDeletePopUp}\n        isLoading={loading}\n      />\n\n      {isOpen && (\n      <AddDataFormat\n        isOpen={isOpen}\n        loading={loading}\n        onClose={() => {\n          detailRef.current = null;\n          closePopUp();\n        }}\n        onSubmit={onSubmit}\n        editData={detailRef?.current}\n      />\n      )}\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/UploadAttachmentSetting.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport ReactTooltip from 'react-tooltip';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Button,\n  Checkbox,\n  Description,\n  Heading,\n  Input, Select,\n  // Radio, RadioGroup,\n} from '../../../components';\nimport { FILE_TYPE_EXTENSIONS } from '../../../constant/fileTypeConstant';\nimport { UPLOAD_ATTACHMENT_OPTIONS } from '../../../constant/applicationConfigConstant';\n\nexport const UploadAttachmentSetting = (props) => {\n  const methods = useFormContext();\n\n  const { control, watch, handleSubmit } = methods;\n\n  return (\n    <>\n      <div className=\"px-5 py-3 flex justify-between headerTop items-center\">\n        <div className=\"w-8/12 xxl:w-6/12\">\n          <Heading variant=\"h4\">Upload attachment setting</Heading>\n          <Description className=\"mt-1\">\n            Configure type of upload, type of file, and maximum size of the file you want to allow in your system.\n          </Description>\n        </div>\n        <div className=\"flex justify-end w-4/12 xxl:w-6/12\">\n          <Button size=\"medium\" variant=\"primary\" shape=\"rounded\" onClick={handleSubmit(props?.onSubmit)} loading={props?.loading}>Update</Button>\n        </div>\n      </div>\n      <div className=\"overflow-auto p-5 pt-0 border-t border-gray-100 flex-grow\">\n        <div className=\"grid grid-cols-2 xxl:grid-cols-3 gap-5 py-4\">\n          <Controller\n            control={control}\n            name=\"uploadPlatform\"\n            render={(controlProps) => (\n              <Select\n                {...controlProps}\n                placeholder=\"Select platforms\"\n                label=\"Platforms\"\n                options={props?.platforms}\n                isMulti\n              />\n            )}\n          />\n          <Controller\n            control={control}\n            name=\"uploadFileType\"\n            render={(controlProps) => (\n              <Select\n                {...controlProps}\n                placeholder=\"Select allow file type to upload\"\n                label=\"Allow file type to upload\"\n                options={FILE_TYPE_EXTENSIONS}\n                isMulti\n                valueKey=\"name\"\n              />\n            )}\n          />\n          <Controller\n            control={control}\n            name=\"uploadMaxSize\"\n            render={(controlProps) => (\n              <Input.Number\n                {...controlProps}\n                placeholder=\"Enter max. upload size limit\"\n                label=\"Max. upload size limit (in MB)\"\n                extension=\"MB\"\n              />\n            )}\n          />\n          <Controller\n            control={control}\n            name=\"uploadStorageType\"\n            render={(controlProps) => (\n              <Select\n                {...controlProps}\n                placeholder=\"Select type of upload\"\n                label=\"Type of upload\"\n                options={UPLOAD_ATTACHMENT_OPTIONS}\n                isClearable={false}\n              />\n            )}\n          />\n        </div>\n        {/* <div className=\"mt-4 mb-8\">\n          <Controller\n            control={control}\n            name=\"isSingleFileUpload\"\n            render={(controlProps) => (\n              <RadioGroup\n                {...controlProps}\n                selectedValue={controlProps.value}\n                className=\"flex\"\n              >\n                <Radio value>\n                  Single file upload\n                </Radio>\n                <Radio value={false}>\n                  Multi file upload\n                </Radio>\n              </RadioGroup>\n            )}\n          />\n        </div> */}\n        <div className=\"mt-4 mb-8\">\n          <Controller\n            control={control}\n            name=\"uploadTimeAuth\"\n            defaultValue={watch('uploadTimeAuth')}\n            render={(controlProps) => (\n              <Checkbox\n                {...controlProps}\n                checked={controlProps.value}\n                WrapclassName=\"inline-flex items-center\"\n                labelClass=\"flex items-center\"\n              >\n                Auth?\n                <div className=\"w-4 h-4 ml-2\" data-tip data-for=\"tooltip1\">\n                  <Icons.Info />\n                  <ReactTooltip id=\"tooltip1\" type=\"dark\">\n                    Auth middleware apply on method or not!\n                  </ReactTooltip>\n                </div>\n              </Checkbox>\n            )}\n          />\n        </div>\n      </div>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Configuration/CodeGenerateConfiguration/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport {\n  get, isEmpty, omit, pick,\n} from 'lodash';\nimport { useForm, Controller, FormProvider } from 'react-hook-form';\nimport { useSelector } from 'react-redux';\nimport {\n  Tab, Tabs, TabList, TabPanel,\n} from 'react-tabs';\nimport ScrollArea from 'react-scrollbar';\nimport { TabCSs } from '../../../assets/css/tab';\nimport {\n  Select, Input, Checkbox, SelectTree, Button, Heading, BoxLayout, Description,\n} from '../../../components';\nimport { getError } from '../../../utils/validationMsgs';\nimport { COMPONENT_TYPE, MASTER_PARENT_CODE } from '../../../constant/master';\nimport { fetchByCode } from '../../../api/master';\nimport { createApplicationConfig, updateApplicationConfig } from '../../../api/applicationConfig';\nimport { useBoolean } from '../../../components/hooks';\nimport useToastNotifications from '../../hooks/useToastNotifications';\nimport Spinner from './CodeGenerateConfiguration.loader';\nimport { UploadAttachmentSetting } from './UploadAttachmentSetting';\nimport {\n  APPLICATION_CONFIG_TABS, DISABLED_QUERY_PARAMETER_KEYS,\n} from '../../../constant/applicationConfigConstant';\nimport { getApplicationPlatforms } from '../../../utils/applicationPlatform';\nimport { defaultAttributes } from '../../../components/SelectTree';\nimport { DataFormatConfig } from './DataFormatConfig/index';\nimport {\n  getMediumObject, getServiceProvideData, getSocialAuthData, prepareQueryParameters,\n} from './CodeGenConfigHelperFunctions';\n\nexport const CodeGenerateConfiguration = (props) => {\n  // const { userData } = useCurrentUser();\n  const modelList = useSelector((state) => state.models.modelList);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const projectDetail = useSelector((state) => state.projects.currentProjectDetail);\n  const ormType = useSelector((state) => state.projects.applicationDatabase.ormType);\n  const currentApplicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const applicationLoginAccess = projectDetail?.applicationList?.find((d) => d._id === applicationId)?.configInput?.platform;\n\n  const [isLoading, setLoading, unsetLoading] = useBoolean(false);\n  const [isSubmitting, setSubmitting, unsetSubmitting] = useBoolean(false);\n\n  const [mastersList, setMastersList] = React.useState([]); // notification master data\n  const [updatedProjectId, setUpdatedProjectId] = React.useState(null);\n  const [socialMastersList, setSocialMastersList] = React.useState([]); // social auth master data\n  const [callMaster, setCallMaster] = React.useState(props?.fetchMasters); // to fetch notifications and social authentication masters' list based on flag\n  const { addSuccessToast, addErrorToast } = useToastNotifications();\n\n  const methods = useForm({ shouldUnregister: false, mode: 'onBlur' });\n  const {\n    handleSubmit, errors, control, reset, setValue, watch,\n  } = methods;\n\n  React.useEffect(() => {\n    // to fetch notifications and social authentication masters' list\n    const fetchData = async () => {\n      try {\n        setLoading();\n        const notificationData = await fetchByCode({ parentCode: MASTER_PARENT_CODE.NOTIFICATION, isSub: true });\n        const socialAuthData = await fetchByCode({ parentCode: MASTER_PARENT_CODE.SOCIAL_AUTH, isSub: true });\n        setMastersList(notificationData?.data?.list || []);\n        setSocialMastersList(socialAuthData?.data?.list || []);\n        setCallMaster(false); // to fetch notifications and social authentication masters' list only on first render\n        unsetLoading();\n      } catch (error) {\n        addErrorToast(error);\n      }\n    };\n    if (callMaster) {\n      fetchData();\n    }\n  }, []);\n\n  const setInitialData = (updatedData) => {\n    const projectConfig = updatedData || props?.projectConfig;\n    if (projectConfig?._id) {\n      setValue('authModuleId', projectConfig?.authModuleId);\n      setValue('username', projectConfig?.loginWith?.username?.filter((key) => !DISABLED_QUERY_PARAMETER_KEYS.includes(key)) ?? [...Object.keys(pick(modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson, ['username', 'email']))]); // to remove disabled query parameter keys from older applications // TODO: remove this filter condition after 2 sprints\n      setValue('password', projectConfig?.loginWith?.password ?? (Object.keys(modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson ?? {})?.includes('password') ? 'password' : ''));\n      setValue('loginRetryLimitMax', projectConfig?.loginRetryLimit?.max?.toString());\n      setValue('loginReActiveTime', projectConfig?.loginRetryLimit?.reActiveTime?.toString());\n      setValue('rateLimitMax', projectConfig?.loginRateLimit?.max?.toString());\n      setValue('rateReActiveTime', projectConfig?.loginRateLimit?.reActiveTime?.toString());\n      setValue('isRestrictDevice', projectConfig?.restrictNoOfDevice ?? false);\n      setValue('noOfDevice', projectConfig?.noOfDevice?.toString() || '1');\n      setValue('tokenExpireTime', projectConfig?.tokenExpiryTime?.toString());\n      setValue('uploadPlatform', projectConfig?.fileUpload?.uploads?.[0]?.platform);\n      setValue('uploadFileType', projectConfig?.fileUpload?.uploads?.[0]?.validationType);\n      setValue('uploadStorageType', projectConfig?.fileUpload?.uploads?.[0]?.storage ?? 'local');\n      setValue('uploadTimeAuth', projectConfig?.fileUpload?.uploads?.[0]?.authentication ?? false);\n      setValue('uploadMaxSize', projectConfig?.fileUpload?.uploads?.[0]?.maxSize?.toString());\n      setValue('isSingleFileUpload', projectConfig?.fileUpload?.uploads?.[0]?.isSingle ?? true);\n      setValue('responseFormatter', projectConfig?.responseFormatter ?? []);\n\n      setValue('platform', Object.keys(projectConfig?.twoFactorAuthentication?.platform || {}) || []);\n      setValue('resetPasswordMasterIds', projectConfig?.resetPassword?.link?.masterIds);\n\n      setValue('expireTime', projectConfig?.resetPassword?.expireTime?.toString());\n      if (!isLoading) {\n        mastersList?.forEach((master) => {\n          if (projectConfig?.externalServiceProviderData?.find((provider) => provider?.typeId === master?._id)) {\n            setValue(`notification-${master?.code}`, projectConfig?.externalServiceProviderData?.find((provider) => provider?.typeId === master?._id)?.serviceProviderId); // to get selected notification provider from dropdown\n          }\n          master?.subMaster?.forEach((sub) => {\n            sub?.customJson?.map((field) => (\n              setValue(`${field?.fieldName}-${sub?._id}`, get(projectConfig?.externalServiceProviderData?.find((provider) => provider?.typeId === master?._id)?.customJson, `${field?.fieldName}`)) // to get fields' data of selected notification provider\n            ));\n          });\n        });\n      }\n      if (!isLoading) {\n        socialMastersList?.forEach((socialMaster) => {\n          setValue(`platform-${socialMaster?._id}`, projectConfig?.socialPlatform?.find((platform) => platform?.typeId === socialMaster?._id)?.platform); // to get all the selected platforms for particular social auth medium\n          setValue(`platform-${socialMaster?._id}-selection`, projectConfig?.socialPlatform?.find((platform) => platform?.typeId === socialMaster?._id)?.isChecked); // to (un)check checkbox of particular social auth medium\n          socialMaster?.customJson?.forEach((field) => {\n            setValue(`${field?.fieldName}-${socialMaster?._id}`, !isEmpty(get(projectConfig?.socialPlatform?.find((platform) => platform?.typeId === socialMaster?._id)?.credential, `${field?.fieldName}`)) ? get(projectConfig?.socialPlatform?.find((platform) => platform?.typeId === socialMaster?._id)?.credential, `${field?.fieldName}`) : `${field?.defaultUrl}`); // to get fields' data of particular social auth medium\n          });\n        });\n      }\n    } else {\n      reset();\n    }\n  };\n\n  React.useEffect(() => {\n    setInitialData();\n  }, [props?.projectConfig?._id, isLoading]);\n\n  const onSubmit = (updatedData, cb) => {\n    const { projectConfig = {} } = props;\n    const apiData = {\n      applicationId,\n      authModuleId: updatedData?.authModuleId,\n      authModule: modelList?.find((model) => model?._id === updatedData?.authModuleId)?.name,\n      loginWith: {\n        username: updatedData?.username ?? [],\n        password: updatedData?.password ?? '',\n      },\n      isTwoFA: updatedData?.isTwoFA,\n      restrictNoOfDevice: updatedData?.isRestrictDevice,\n      noOfDevice: updatedData?.isRestrictDevice ? +updatedData?.noOfDevice || 1 : 1,\n\n      loginRetryLimit: {\n        max: updatedData?.loginRetryLimitMax && Number(updatedData?.loginRetryLimitMax),\n        reActiveTime: updatedData?.loginReActiveTime && Number(updatedData?.loginReActiveTime),\n      },\n      resetPassword: {\n        link: getMediumObject(updatedData?.resetPasswordMasterIds, mastersList, updatedData, [], 'resetPasswordTemplates'),\n        expireTime: updatedData?.expireTime && Number(updatedData?.expireTime),\n      },\n\n      loginRateLimit: {\n        max: updatedData?.rateLimitMax && Number(updatedData?.rateLimitMax),\n        reActiveTime: updatedData?.rateReActiveTime && Number(updatedData?.rateReActiveTime),\n      },\n      isSocialMediaAuth: getSocialAuthData(socialMastersList, updatedData)?.some((platform) => platform?.isChecked),\n      socialPlatform: getSocialAuthData(socialMastersList, updatedData)?.some((platform) => platform?.isChecked) ? getSocialAuthData(socialMastersList, updatedData) : [],\n      externalServiceProviderData: getServiceProvideData(mastersList, updatedData),\n      tokenExpiryTime: updatedData?.tokenExpireTime && Number(updatedData?.tokenExpireTime),\n      fileUpload: {\n        uploads: [{\n          platform: updatedData?.uploadPlatform,\n          validationType: updatedData?.uploadFileType,\n          storage: updatedData?.uploadStorageType,\n          authentication: updatedData?.uploadTimeAuth,\n          maxSize: updatedData?.uploadMaxSize && Number(updatedData?.uploadMaxSize),\n          isSingle: updatedData?.isSingleFileUpload ?? true,\n        }],\n      },\n      responseFormatter: updatedData?.responseFormatter?.map((x) => omit(x, 'model')) || [],\n    };\n    setSubmitting();\n    const promise = (projectConfig?._id || updatedProjectId) ? updateApplicationConfig((projectConfig?._id || updatedProjectId), apiData) : createApplicationConfig(apiData);\n    promise.then((applicationConfigRes) => {\n      if (applicationConfigRes?.data?._id) {\n        addSuccessToast(applicationConfigRes?.message);\n        setUpdatedProjectId(applicationConfigRes?.data?._id);\n        setInitialData(applicationConfigRes?.data);\n        unsetSubmitting();\n        cb && typeof cb === 'function' && cb();\n      }\n    }).catch((error) => {\n      addErrorToast(error);\n    }).finally(unsetSubmitting);\n  };\n  return (\n    <BoxLayout variant=\"mainRight\">\n      {isLoading ? <Spinner /> : (\n        <div className=\"flex w-full h-body\">\n          <FormProvider\n            {...methods}\n          >\n            <Tabs selectedTabPanelClassName=\"h-full flex flex-col\" className=\"flex w-full\" selectedTabClassName={TabCSs.tabVerselectTab}>\n              <TabList className={`${TabCSs.tabVerHead} xxl:w-1.5/12 w-2.5/12 flex flex-col`}>\n                <div className=\"flex justify-between p-3 items-center border-b-1 border-gray-100 relative configTop\">\n                  <div className=\"text-primary-text text-base font-semibold\">Configuration</div>\n                </div>\n                <div className=\"overflow-auto sticky top-0 p-2\">\n                  <ScrollArea\n                    speed={0.8}\n                    className=\"area h-full justify-between\"\n                    contentClassName=\"w-full\"\n                    smoothScrolling\n                  >\n                    {\n                      APPLICATION_CONFIG_TABS[currentApplicationCode]?.map((tab) => (\n                        <Tab key={tab} className={`${TabCSs.tabVerTitle}`}>\n                          <span className={TabCSs.tabverTitleName}>{tab}</span>\n                        </Tab>\n                      ))\n                    }\n                  </ScrollArea>\n                </div>\n              </TabList>\n              <div className=\"xxl:w-10.5/12 w-9.5/12\">\n                <TabPanel>\n                  <div className=\"px-5 py-3 flex justify-between headerTop items-center\">\n                    <div className=\"w-8/12 xxl:w-6/12\">\n                      <Heading variant=\"h4\">Authentication</Heading>\n                      <Description className=\"mt-1\">\n                        Configure authentication module and customize security for your project.\n                      </Description>\n                    </div>\n                    <div className=\"flex justify-end w-4/12 xxl:w-6/12\">\n                      <Button size=\"medium\" variant=\"primary\" shape=\"rounded\" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>Update</Button>\n                    </div>\n                  </div>\n                  <div className=\"overflow-auto flex-grow p-5 pt-0 border-t border-gray-100\">\n                    <div className=\"grid grid-cols-2 xxl:grid-cols-3 gap-5 items-start py-4\">\n                      <Controller\n                        control={control}\n                        name=\"authModuleId\"\n                        render={(controlProps) => (\n                          <Select\n                            {...controlProps}\n                            label=\"Auth model\"\n                            placeholder=\"Select Auth model\"\n                            options={modelList}\n                            onChange={(value) => {\n                              setValue('authModuleId', value);\n                              setValue('username', [...Object.keys(pick(modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson, ['username', 'email']))]); // select \"username\" and \"email\" if that attribute is available in selected auth model\n                              setValue('password', (Object.keys(modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson ?? {})?.includes('password') ? 'password' : '')); // select \"password\" if that attribute is available in selected auth model\n                            }}\n                            error={getError(errors, 'authModuleId', 'Auth Model')}\n                            valueKey=\"_id\"\n                          />\n                        )}\n                      />\n                      <Controller\n                        control={control}\n                        name=\"username\"\n                        render={(controlProps) => (\n                          <SelectTree\n                            {...controlProps}\n                            defaultValue={controlProps?.value}\n                            label=\"Login query parameter for username\"\n                            placeholder=\"Select login query parameter for username\"\n                            mode=\"multiple\"\n                            data={prepareQueryParameters({ ...(watch('authModuleId') && defaultAttributes[ormType]), ...modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson }, ormType)} // to display list of login query parameters according to selected model\n                            error={getError(errors, 'username', 'Login query parameter for username')}\n                            handleChange={(values) => {\n                              setValue('username', values?.allSelectedNode?.map((node) => node?.fullName));\n                            }}\n                            disabledKey={[...DISABLED_QUERY_PARAMETER_KEYS, 'password']}\n                          />\n                        )}\n                      />\n                      <Controller\n                        control={control}\n                        name=\"password\"\n                        render={(controlProps) => (\n                          <SelectTree\n                            {...controlProps}\n                            defaultValue={!isEmpty(controlProps?.value) ? [controlProps?.value] : []}\n                            label=\"Login query parameter for password\"\n                            placeholder=\"Select login query parameter for password\"\n                            mode=\"radioSelect\"\n                            data={prepareQueryParameters(modelList?.find((model) => model?._id === watch('authModuleId'))?.schemaJson, ormType)} // to display list of password query parameters according to selected model\n                            error={getError(errors, 'password', 'Login query parameter for password')}\n                            handleChange={(values) => {\n                              setValue('password', values?.allSelectedNode?.[0]?.fullName); // to keep the updated value of password query while changing values of other fields\n                            }}\n                            disabledKey={[...DISABLED_QUERY_PARAMETER_KEYS, 'username', 'email']}\n                          />\n                        )}\n                      />\n                      <Controller\n                        control={control}\n                        name=\"loginRetryLimitMax\"\n                        rules={{ min: 3, max: 5 }}\n                        render={(controlProps) => (\n                          <Input.Number\n                            {...controlProps}\n                            label=\"Login retry limit\"\n                            placeholder=\"Enter login retry limit\"\n                            error={getError(errors, 'loginRetryLimitMax', errors?.loginRetryLimitMax?.type === 'min' ? '3' : '5')}\n                          />\n                        )}\n                      />\n                      <Controller\n                        control={control}\n                        name=\"loginReActiveTime\"\n                        render={(controlProps) => (\n                          <Input.Number\n                            {...controlProps}\n                            label=\"Login re-active time (in minutes)\"\n                            placeholder=\"Enter login re-active time\"\n                            error={getError(errors, 'loginReActiveTime', 'Login re-active time')}\n                          />\n                        )}\n                      />\n                    </div>\n\n                    <hr className=\"border-t boredr-1 border-gray-100 my-6\" />\n                    <div className=\"py-4\">\n                      <div className=\"grid grid-cols-2 xxl:grid-cols-3 gap-5\">\n                        <Controller\n                          control={control}\n                          name=\"resetPasswordMasterIds\"\n                          render={(controlProps) => (\n                            <Select\n                              {...controlProps}\n                              label=\"Reset password link\"\n                              placeholder=\"Select reset password link\"\n                              isMulti\n                              options={mastersList?.filter((master) => master?.code !== 'PUSH_NOTIFICATION')}\n                              valueKey=\"_id\"\n                              labelKey=\"name\"\n                              error={getError(errors, 'resetPasswordMasterIds', 'Reset password medium')}\n                            />\n                          )}\n                        />\n                        <Controller\n                          control={control}\n                          name=\"expireTime\"\n                          render={(controlProps) => (\n                            <Input.Number\n                              {...controlProps}\n                              label=\"Expire time (in minutes)\"\n                              placeholder=\"Enter expire time\"\n                              error={getError(errors, 'expireTime', 'Expire time')}\n                            />\n                          )}\n                        />\n                      </div>\n\n                    </div>\n\n                    <div className=\"py-4\">\n                      <hr className=\"border-t boredr-1 border-gray-100 my-6\" />\n                      <div className=\"\">\n                        <Controller\n                          control={control}\n                          name=\"isRestrictDevice\"\n                          defaultValue={watch('isRestrictDevice')}\n                          render={(controlProps) => (\n                            <Checkbox\n                              {...controlProps}\n                              checked={controlProps.value}\n                            >\n                              Is restrict device?\n                            </Checkbox>\n                          )}\n                        />\n                      </div>\n                      {watch('isRestrictDevice')\n                            && (\n                            <div className=\"grid w-11/12 grid-cols-2 gap-5 mt-5\">\n                              <>\n                                <Controller\n                                  control={control}\n                                  name=\"noOfDevice\"\n                                  render={(controlProps) => (\n                                    <Input.Number\n                                      {...controlProps}\n                                      label=\"Number of device(s)\"\n                                      placeholder=\"Enter number of device(s)\"\n                                    />\n                                  )}\n                                />\n                              </>\n                            </div>\n                            )}\n                    </div>\n                  </div>\n                </TabPanel>\n                <TabPanel>\n                  <div className=\"px-5 py-3 flex justify-between headerTop items-center\">\n                    <div className=\"w-9/12 xxl:w-6/12\">\n                      <Heading variant=\"h4\">Social auth setting</Heading>\n                      <Description className=\"mt-1\">\n                        Fill details of the respective platforms you want to enable social authetication for. All details will be stored in the .env file. You can further update the detail in the same file after downloading the code.\n                      </Description>\n                    </div>\n                    <div className=\"flex justify-end w-3/12 xxl:w-6/12\">\n                      <Button size=\"medium\" variant=\"primary\" shape=\"rounded\" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>Update</Button>\n                    </div>\n                  </div>\n                  <div className=\"overflow-auto flex-grow p-5 pt-0 border-t border-gray-100\">\n                    {!isLoading && (\n                    <div className=\"\">\n                      { socialMastersList?.map((socialMaster) => (\n                        <div key={socialMaster?._id} className=\"py-5 border-b border-gray-200\">\n                          <div className=\"flex items-center\">\n                            <Controller\n                              control={control}\n                              name={`platform-${socialMaster?._id}-selection`}\n                              render={(controlProps) => (\n                                <Checkbox\n                                  {...controlProps}\n                                  checked={!!controlProps?.value}\n                                />\n                              )}\n                            />\n                            <Heading variant=\"h5\" className=\"ml-1\">{socialMaster?.name}</Heading>\n                          </div>\n                          {\n                              // watch(`platform-${socialMaster?._id}-selection`)\n                              // && (\n                            <div className={`grid-cols-2 xxl:grid-cols-3 gap-5 mt-2 ${watch(`platform-${socialMaster?._id}-selection`) ? 'grid' : 'hidden'}`}>\n                              {/* to get selection dropdown of platforms for social auth */}\n                              <Controller\n                                control={control}\n                                name={`platform-${socialMaster?._id}`}\n                                render={(controlProps) => (\n                                  <Select\n                                    {...controlProps}\n                                    placeholder=\"Select platform\"\n                                    options={getApplicationPlatforms(applicationLoginAccess)} // to fetch all the platforms\n                                    label=\"Platform\"\n                                    isMulti\n                                    error={getError(errors, `platform-${socialMaster?._id}`, 'Platform')}\n                                  />\n                                )}\n                              />\n                              {\n                                    socialMaster?.customJson?.map((field) => {\n                                      if (watch(`platform-${socialMaster?._id}-selection`)) {\n                                        return (\n                                          // to get fields' of all social auth\n                                          <Controller\n                                            control={control}\n                                            name={`${field?.fieldName}-${socialMaster?._id}`}\n                                            rules={{ required: !!watch(`platform-${socialMaster?._id}-selection`), ...(field?.pattern && { pattern: /^\\/[a-zA-Z0-9]+/ }) }}\n                                            render={(controlProps) => (\n                                              React.createElement(COMPONENT_TYPE[field?.inputType], {\n                                                ...controlProps,\n                                                key: `${field?.fieldName}-${socialMaster?._id}`,\n                                                label: `${field?.displayName}${field?.isRequired ? '*' : ''}`,\n                                                placeholder: `Enter ${field?.displayName}`,\n                                                error: !!watch(`platform-${socialMaster?._id}-selection`) && getError(errors, `${field?.fieldName}-${socialMaster?._id}`, (errors?.[`${field?.fieldName}-${socialMaster?._id}`]?.type === 'pattern') ? `Enter valid ${field?.displayName}` : field?.displayName),\n                                              })\n                                            )}\n                                          />\n                                        );\n                                      }\n                                      delete errors?.[`${field?.fieldName}-${socialMaster?._id}`]; // to remove errors from not selected social auth's fields'\n                                      return null;\n                                    })\n                                }\n                            </div>\n                              // )\n                            }\n                        </div>\n                      ))}\n                    </div>\n                    )}\n                  </div>\n                </TabPanel>\n                <TabPanel>\n                  <div className=\"px-5 py-3 flex justify-between headerTop items-center\">\n                    <div className=\"w-8/12 xxl:w-6/12\">\n                      <Heading variant=\"h4\">Security setting</Heading>\n                      <Description className=\"mt-1\">\n                        Manage number of API calls per minute to avoid undesired activity in your project.\n                      </Description>\n                    </div>\n                    <div className=\"flex justify-end w-4/12 xxl:w-6/12\">\n                      <Button size=\"medium\" variant=\"primary\" shape=\"rounded\" onClick={handleSubmit(onSubmit)} loading={isSubmitting}>Update</Button>\n                    </div>\n                  </div>\n                  <div className=\"overflow-auto flex-grow p-5 pt-0 border-t border-gray-100\">\n                    <div className=\"\">\n                      <div className=\"grid grid-cols-2 xxl:grid-cols-3 gap-5 py-4\">\n                        <Controller\n                          control={control}\n                          name=\"rateLimitMax\"\n                          render={(controlProps) => (\n                            <Input.Number\n                              {...controlProps}\n                              label=\"Rate limit\"\n                              placeholder=\"Enter rate limit\"\n                            />\n                          )}\n                        />\n                        <Controller\n                          control={control}\n                          name=\"rateReActiveTime\"\n                          render={(controlProps) => (\n                            <Input.Number\n                              {...controlProps}\n                              label=\"Rate limit re-active time (in minutes)\"\n                              placeholder=\"Enter rate limit re-active time (in minutes)\"\n                              error={getError(errors, 'rateReActiveTime', 'Rate limit re-active time')}\n                            />\n                          )}\n                        />\n                        <Controller\n                          control={control}\n                          name=\"tokenExpireTime\"\n                          render={(controlProps) => (\n                            <Input.Number\n                              {...controlProps}\n                              label=\"Token expiry time (in minutes)\"\n                              placeholder=\"Enter token expiry time (in minutes)\"\n                            />\n                          )}\n                        />\n                      </div>\n                    </div>\n\n                  </div>\n                </TabPanel>\n                <TabPanel>\n                  <UploadAttachmentSetting platforms={getApplicationPlatforms(applicationLoginAccess)} onSubmit={onSubmit} loading={isSubmitting} />\n                </TabPanel>\n                <TabPanel>\n                  <DataFormatConfig\n                    onSubmit={onSubmit}\n                    loading={isSubmitting}\n                  />\n                </TabPanel>\n              </div>\n            </Tabs>\n          </FormProvider>\n        </div>\n      )}\n    </BoxLayout>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Configuration/index.js",
    "content": "import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport Layout from '../Shared/Layout';\nimport { CodeGenerateConfiguration } from './CodeGenerateConfiguration';\nimport { useBoolean } from '../../components/hooks';\nimport { getApplicationConfig } from '../../api/applicationConfig';\nimport { listModels } from '../../redux/thunks/models';\nimport Spinner from './CodeGenerateConfiguration/CodeGenerateConfiguration.loader';\nimport { useToastNotifications } from '../hooks';\n\nconst Configuration = () => {\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const [isLoading, setLoading, unsetLoading] = useBoolean(false);\n  const [projectConfig, setProjectConfig] = React.useState([]);\n  const [fetchMasters, setFetchMasters] = React.useState(false); // to fetch master's list based on flag\n  const { addErrorToast } = useToastNotifications();\n  const dispatch = useDispatch();\n\n  function fetchApplicationConfig() {\n    if (applicationId) {\n      setLoading();\n      getApplicationConfig({ applicationId }).then(\n        (configRes) => {\n          setProjectConfig(configRes?.data?.list?.[0] || []);\n          setFetchMasters(true);\n          unsetLoading();\n        },\n      ).catch(addErrorToast).finally(unsetLoading);\n    }\n  }\n\n  React.useEffect(() => {\n    fetchApplicationConfig();\n  }, [applicationId]);\n\n  React.useEffect(() => {\n    if (applicationId) {\n      dispatch(listModels({ applicationId }));\n    }\n  }, [applicationId]);\n\n  return (\n    <Layout isSidebar>\n      {isLoading ? <Spinner /> : <CodeGenerateConfiguration projectConfig={projectConfig} applicationId={applicationId} fetchMasters={fetchMasters} />}\n    </Layout>\n  );\n};\nexport default Configuration;\n"
  },
  {
    "path": "packages/client/src/container/Constant/AddConstant/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport {\n  Input, Popup, Select,\n} from '../../../components';\nimport { getError } from '../../../utils/validationMsgs';\nimport { createConstant } from '../../../api/applicationConstant';\nimport { CONSTANT_GENERATE_TYPE } from '../../../constant/applicationConstant';\nimport useToastNotifications from '../../hooks/useToastNotifications';\nimport { useBoolean } from '../../../components/hooks';\nimport { addConstant } from '../../../redux/reducers/constants';\nimport { nodeKeyRegex } from '../../../utils/regex';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../constant/common';\n\nconst defaultValues = {\n  fileName: undefined,\n  modelId: undefined,\n  description: undefined,\n};\n\nexport const AddConstant = React.memo(({ addModalRef }) => {\n  const dispatch = useDispatch();\n  const [constantModal, showConstantModal, hideConstantModal] = useBoolean(false);\n\n  const { applicationId, modelList } = useSelector(({ projects, models }) => ({\n    applicationId: projects.currentApplicationId,\n    modelList: models.modelList,\n    applicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n  const {\n    handleSubmit, errors, control, setValue, trigger,\n  } = useForm({ defaultValues, mode: 'all' });\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const [isSubmitting, setSubmitting, removeSetSubmitting] = useBoolean(false);\n\n  React.useImperativeHandle(addModalRef, () => ({ showConstantModal }));\n  const onSubmit = (constantData) => {\n    if (isSubmitting) { return; }\n    setSubmitting();\n    const apiData = {\n      ...constantData,\n      applicationId,\n      type: CONSTANT_GENERATE_TYPE.MANUAL,\n      customJson: {},\n    };\n    createConstant(apiData).then((response) => {\n      addSuccessToast(response.message);\n      dispatch(addConstant(response.data));\n      hideConstantModal();\n    }).catch((error) => {\n      addErrorToast(error || 'Record with same route already exists');\n    }).finally(removeSetSubmitting);\n  };\n\n  return (\n    <Popup\n      isOpen={constantModal}\n      handleCancel={hideConstantModal}\n      closeModal={hideConstantModal}\n      handleSubmit={handleSubmit(onSubmit)}\n      title=\"Create constant\"\n      isCancel\n      cancel=\"Cancel\"\n      isSubmit\n      submit=\"Create constant\"\n      bodyClass=\"xxl:max-h-110 overflow-auto xl:max-h-96\"\n      submitLoading={isSubmitting}\n      isAutoFocusOnSave\n    >\n      <form onSubmit={handleSubmit(onSubmit)}>\n        <div className=\"grid grid-cols-1 gap-5\">\n\n          <Controller\n            control={control}\n            name=\"modelId\"\n            render={(controlProps) => (\n              <Select\n                {...controlProps}\n                autoFocus\n                onChange={(modelId) => {\n                  setValue('modelId', modelId ?? undefined);\n                  if (modelId) {\n                    setValue('fileName', modelList.find((d) => d._id === modelId)?.name);\n                    trigger('fileName');\n                  }\n                }}\n                placeholder=\"Select model\"\n                desc=\"Select a model name you wanted to create a constant file for.\"\n                options={modelList}\n                label=\"Select model for constant\"\n                valueKey=\"_id\"\n              />\n            )}\n          />\n\n          <Controller\n            control={control}\n            name=\"fileName\"\n            rules={{ required: true }}\n            render={(controlProps) => (\n              <Input\n                {...controlProps}\n                {...({ autoFocus: true })}\n                placeholder=\"Enter constant name\"\n                maxLength={MAX_INPUT_FIELD_LIMIT.title}\n                desc=\"Give your constant an appropriate name.\"\n                label=\"Constant name*\"\n                error={getError(errors, 'fileName', (errors?.fileName?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.title : 'Constant name')}\n                customRegex={nodeKeyRegex}\n              />\n            )}\n          />\n\n          {/* <Controller\n            control={control}\n            name=\"description\"\n            rules={{ required: true }}\n            render={(controlProps) => (\n              <TextArea\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...controlProps}\n                placeholder=\"Enter description\"\n                label=\"Description*\"\n                defaultValues={controlProps.value}\n                maxLength={MAX_INPUT_FIELD_LIMIT.description}\n                // desc=\"Briefly describe your constant.\"\n                error={getError(errors, 'description', (errors?.description?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.description : 'Description')}\n              />\n            )}\n          /> */}\n        </div>\n      </form>\n    </Popup>\n  );\n});\nAddConstant.displayName = 'AddConstant';\n"
  },
  {
    "path": "packages/client/src/container/Constant/ConstantView/ConstantHead/index.js",
    "content": "import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { isBoolean } from 'lodash';\nimport { useBoolean } from '../../../../components/hooks';\nimport { updateConstant } from '../../../../api/applicationConstant';\nimport { updateCurrentConstant } from '../../../../redux/reducers/constants';\nimport { InlineHeader } from '../../../../components/InlineHeader';\nimport { useToastNotifications } from '../../../hooks';\nimport { nodeConstantName } from '../../../../constant/applicationConstant';\n\nexport const ConstantHead = React.memo(({ updateRef, isDisable }) => {\n  const [edit, setShowEdit, setHideEdit] = useBoolean(false);\n  const { addSuccessToast, addErrorToast } = useToastNotifications();\n\n  const selectedConstant = useSelector((state) => state.constants.currentId);\n  const constantList = useSelector((state) => state.constants.constantList);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const dispatch = useDispatch();\n\n  const [state, _setState] = React.useState(() => ({ fileName: '', description: '', isActive: false }));\n  const setState = React.useCallback((data) => {\n    _setState((prevState) => ({ ...prevState, ...data }));\n  }, [_setState]);\n\n  const currentConstantData = constantList.find((d) => d._id === selectedConstant);\n\n  React.useEffect(() => {\n    setState({\n      fileName: currentConstantData?.fileName,\n      description: currentConstantData?.description,\n      isActive: currentConstantData?.isActive,\n    });\n    setHideEdit();\n  }, [selectedConstant]);\n\n  const handelConstantProperty = async (key, value, isShowNotification = true) => {\n    const data = { [key]: isBoolean(value) ? value : value || currentConstantData?.[key] };\n    setState({ ...data });\n    const request = {\n      ...state,\n      customJson: currentConstantData?.customJson || {},\n      // TODO:Remove if customJson come in List\n      ...data,\n      applicationId,\n      type: currentConstantData?.type,\n    };\n    if (value || isBoolean(value)) {\n      try {\n        const response = await updateConstant(selectedConstant, request);\n        if (response.data) {\n          if (isShowNotification)addSuccessToast(response.message);\n          dispatch(updateCurrentConstant(response.data));\n        }\n      } catch (error) {\n        addErrorToast(error);\n        setState({\n          fileName: currentConstantData?.fileName,\n          description: currentConstantData?.description,\n          isActive: currentConstantData?.isActive,\n        });\n      }\n    }\n  };\n\n  React.useImperativeHandle(updateRef, () => ({ handelConstantProperty, setHideEdit }));\n\n  return (\n    <InlineHeader\n      defaultValue={state}\n      currentId={selectedConstant}\n      onBlurEvent={handelConstantProperty}\n      isDisable={isDisable}\n      isActiveButton\n      edit={edit}\n      titleRegex={nodeConstantName}\n      setShowEdit={setShowEdit}\n      setHideEdit={setHideEdit}\n      titlePlaceHolder=\"Constant\"\n    />\n  );\n});\nConstantHead.displayName = 'ConstantHead';\n"
  },
  {
    "path": "packages/client/src/container/Constant/ConstantView/TableView/EditableCell.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\n/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport { useSelector } from 'react-redux';\nimport Popover from 'react-popover';\nimport { uniq } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { Input, Select } from '../../../../components';\nimport { InputCss } from '../../../../components/Input/inputCss';\nimport { CONSTANT_GENERATE_TYPE, NODE_DATA_TYPE, NODE_DATA_TYPE_OPTION } from '../../../../constant/applicationConstant';\nimport { useBoolean } from '../../../hooks';\nimport { keyBoardShortcut } from '../../../../utils/domMethods';\nimport { modelAttrRegex, removeLeadingSpace } from '../../../../utils/regex';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../../constant/common';\n\nconst TotalColumns = 3;\nconst ArrayOfValue = ({\n  onChange, defaultValue = [], isDisable, id, onKeyDown, dark,\n}) => {\n  const [value, setValue] = React.useState('');\n  const [multiValue, setMulti] = React.useState(defaultValue || []);\n  const [isMore, setMore, removeMore] = useBoolean(false);\n  React.useEffect(() => {\n    setMulti(defaultValue || []);\n  }, [defaultValue]);\n  return (\n    <div className=\" flex\">\n      <input\n        disabled={isDisable}\n        value={value}\n        id={id}\n        name=\"value\"\n        className={`${InputCss.inputBlock} ${dark && InputCss.darkInput} px-2 truncate inputBlock flex`}\n        style={{ height: '36px', width: '180px' }}\n          // className={`${InputCss.inputBlock} py-1.5 px-2.5 truncate  inputBlock`}\n        onChange={(e) => {\n          setValue(e.target.value.replace(removeLeadingSpace, ''));\n        }}\n        placeholder=\"press `Enter` after input.\"\n        onKeyDown={(e) => {\n          onKeyDown(e);\n          if (e.code === 'Enter' && e.target.value) {\n            const multiValueDemo = [...multiValue];\n            const arrayValue = e.target.value;\n            // if typef number than store like number\n            multiValueDemo.unshift(+arrayValue ? +arrayValue : arrayValue);\n            setMulti(uniq(multiValueDemo));\n            onChange(uniq(multiValueDemo));\n            setValue('');\n          }\n        }}\n      />\n      <div className=\"flex items-center ml-2\">\n        {multiValue?.slice(0, 2)?.map?.((v) => (\n          <>\n            <div key={v} className=\"border-gray-100 border-1 rounded-3 text-xs text-primary-text w-max-w flex items-center my-1 py-0.5 mx-0.5\">\n              <span className=\"px-2 truncate block\">{v}</span>\n              <div\n                className=\"w-2 h-2 mr-2 cursor-pointer\"\n                onClick={() => {\n                  const mulValue = multiValue.findIndex((multiv) => multiv === v);\n                  const deleteMul = [...multiValue];\n                  deleteMul.splice(mulValue, 1);\n                  setMulti([...deleteMul]);\n                  onChange([...deleteMul]);\n                }}\n              >\n                <Icons.Close />\n              </div>\n            </div>\n          </>\n        ))}\n        { multiValue.length > 2 && (\n        <Popover\n          isOpen={isMore}\n          body={[\n            <div key={id} className=\"flex items-center cursor-pointer flex-wrap\">\n              {multiValue.slice(2)?.map?.((v) => (\n                <div key={v} className=\"border-gray-100 bg-gray-200 border-1 rounded-3 text-xs text-primary-text w-max-w flex items-center my-1 py-0.5 mx-0.5\">\n                  <span className=\"px-2 truncate block\">{v}</span>\n                  <div\n                    className=\"w-2 h-2 mr-2 cursor-pointer\"\n                    onClick={() => {\n                      const mulValue = multiValue.findIndex((multiv) => multiv === v);\n                      multiValue.splice(mulValue, 1);\n                      setMulti([...multiValue]);\n                      onChange([...multiValue]);\n                    }}\n                  >\n                    <Icons.Close />\n                  </div>\n\n                </div>\n              ))}\n            </div>,\n          ]}\n          onOuterAction={removeMore}\n          style={{ maxWidth: '500px' }}\n          className=\"popupCustom\"\n        >\n          <div className=\"text-primary hover:underline ml-1 cursor-pointer\" onClick={setMore}>More</div>\n        </Popover>\n        )}\n      </div>\n    </div>\n  );\n};\n\nconst ValueComponent = ({\n  type, value, onChange, isDisable, dark = false, id, onKeyDown,\n}) => {\n  switch (type) {\n    case 'string':\n      return (\n        <div style={{ width: '180px' }}>\n          <Input\n            disabled={isDisable}\n            id={id}\n            name=\"value\"\n            onKeyDown={onKeyDown}\n            dark={dark}\n            placeholder=\"Value\"\n            onChange={onChange}\n            value={value || ''}\n            size=\"small\"\n          />\n        </div>\n      );\n    case 'number': return (\n      <div style={{ width: '180px' }}>\n        <Input.Decimal\n          placeholder=\"Value\"\n          disabled={isDisable}\n          id={id}\n          name=\"value\"\n          onKeyDown={onKeyDown}\n          dark={dark}\n          size=\"small\"\n          fixLength={20}\n          value={![null, undefined].includes(value) ? value.toString() : ''}\n          onChange={(val) => {\n            onChange(val ? +val : null);\n          }}\n        />\n      </div>\n    );\n    case 'array': return (\n      <ArrayOfValue\n        onChange={onChange}\n        onKeyDown={onKeyDown}\n        id={id}\n        isDisable={isDisable}\n        dark={dark}\n        defaultValue={value}\n      />\n      // <TagNameSelect\n      //   isMulti\n      //   options={[]}\n      //   onChange={(val) => {\n      //     console.log('value', val);\n      //     setState();\n      //   }}\n      // />\n    );\n    default:\n      return <div style={{ width: '180px' }}>-</div>;\n  }\n};\n\nfunction EditableCell({\n  value: initialValue,\n  row: { index, original },\n  column: { id },\n  onInputChange,\n  totalRowCount,\n  ...rest\n}) {\n  const FiledPosition = {\n    attribute: +original?.focusIndex + 1,\n    type: +original?.focusIndex + 2,\n    value: +original?.focusIndex + 3,\n  };\n  const handleAutoFocus = (focusFiled) => {\n    const field = document.querySelector(`#r${FiledPosition[focusFiled]}`);\n    field?.focus();\n  };\n  const onKeyDownHandel = (e, focusField) => {\n    keyBoardShortcut({\n      keyEvent: e,\n      focusIndex: FiledPosition[focusField || e.target.name],\n      totalColumns: TotalColumns,\n      totalRows: +totalRowCount,\n    });\n  };\n  const [value, setValue] = React.useState(initialValue);\n  const isDisable = useSelector(({ constants }) => constants.constantList.find((d) => d._id === constants.currentId)?.type === CONSTANT_GENERATE_TYPE.AUTO);\n  // const onBlur = () => {\n  //   onInputChange(index, id, value);\n  // };\n  React.useEffect(() => {\n    setValue(initialValue);\n  }, [initialValue]);\n\n  const onChange = (val, focusFiled) => {\n    if (value === val) return;\n    setValue(val);\n    onInputChange(index, id, val, rest?.mainRowIndex);\n    if (focusFiled === 'type' && val === NODE_DATA_TYPE.JSON) return;\n    requestAnimationFrame(() => {\n      if (focusFiled) handleAutoFocus(focusFiled); // manage auto focus\n    });\n  };\n  switch (id) {\n    case 'attribute': return (\n      <div className=\"w-48\">\n        <Input\n          {...(rest?.isSubRow && { dark: true })}\n          size=\"small\"\n          disabled={isDisable}\n          customRegex={modelAttrRegex}\n          name=\"attribute\"\n          onKeyDown={onKeyDownHandel}\n          id={`r${FiledPosition.attribute}`}\n          // dark\n          maxLength={MAX_INPUT_FIELD_LIMIT.key}\n          defaultValue={initialValue}\n          value={value}\n          placeholder=\"Key\"\n          onChange={(e) => { onChange(e, 'attribute'); }}\n        />\n      </div>\n    );\n    case 'type': return (\n      <div className=\"w-48\">\n        <Select\n          sizeSmall\n          {...(rest?.isSubRow && { dark: true })}\n          valueKey=\"value\"\n          onKeyDown={(e) => {\n            if (e.ctrlKey || e.keyCode === 13) {\n              onKeyDownHandel(e, 'type');\n              if (e.ctrlKey) e.preventDefault();\n            }\n          }}\n          disabled={isDisable}\n          inputId={`r${FiledPosition.type}`}\n          isClearable={false}\n          defaultValue={initialValue}\n          value={value}\n          options={rest?.isSubRow ? NODE_DATA_TYPE_OPTION.filter((opt) => opt.value !== NODE_DATA_TYPE.JSON) : NODE_DATA_TYPE_OPTION}\n          onChange={(e) => { onChange(e, 'type'); }}\n        />\n      </div>\n    );\n    case 'value': return (\n      <ValueComponent\n        isDisable={isDisable}\n        onKeyDown={onKeyDownHandel}\n        type={original.type}\n        id={`r${FiledPosition.value}`}\n        {...(rest?.isSubRow && { dark: true })}\n        value={value}\n        onChange={(e) => { onChange(e, 'value'); }}\n\n      />\n\n    );\n\n    default: return null;\n  }\n}\n\nexport default EditableCell;\n"
  },
  {
    "path": "packages/client/src/container/Constant/ConstantView/TableView/SubRow.js",
    "content": "/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useTable, useExpanded } from 'react-table';\n// import { TableViewCss } from '@assets/css/tableViewCss';\n// import '@assets/css/Table.css';\nimport '../../../../assets/css/Table.css';\n// import HTML5Backend from 'react-dnd-html5-backend';\n// import { DndProvider } from 'react-dnd';\nimport { useSelector } from 'react-redux';\nimport { Icons } from '@dhiwise/icons';\nimport { last } from 'lodash';\nimport {\n  DeleteIcon,\n} from '../../../../components';\nimport EditableCell from './EditableCell';\nimport { CONSTANT_GENERATE_TYPE } from '../../../../constant/applicationConstant';\n\nconst defaultColumn = {\n  Cell: EditableCell,\n};\n\nfunction Table({\n  // eslint-disable-next-line no-unused-vars\n  columns, data, onInputChange, onAddSubRow, mainRowIndex, onSubRowDelete, totalRowCount,\n}) {\n  // Use the state and functions returned from useTable to build your UI\n  const {\n    getTableProps,\n    getTableBodyProps,\n    // headerGroups,\n    rows,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn,\n    onInputChange,\n    mainRowIndex,\n    isSubRow: true,\n    totalRowCount,\n  },\n  useExpanded);\n  // Render the UI for your table\n  const isDisable = useSelector(({ constants }) => constants.constantList.find((d) => d._id === constants.currentId)?.type === CONSTANT_GENERATE_TYPE.AUTO);\n\n  return (\n  // <DndProvider backend={HTML5Backend}>\n    <table {...getTableProps()} className=\"w-full\">\n      {/* <thead>\n        {headerGroups.map((headerGroup) => (\n          <tr {...headerGroup.getHeaderGroupProps()} className=\"relative\">\n            {headerGroup.headers.map((column) => (\n              <th {...column.getHeaderProps()}>{column.render('Header')}</th>\n            ))}\n          </tr>\n        ))}\n      </thead> */}\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row) => {\n          prepareRow(row);\n          return (\n            <>\n              <tr {...row.getRowProps()} className=\"relative align-middle\">\n\n                <td style={{ minWidth: '60px', maxHeight: '60px', width: '60px' }}>\n                  {!isDisable && (\n                  <div className=\"flex justify-start items-center h-full\">\n                    {/* <DragHandle style={{\n                        position: 'relative', top: 'auto', left: 'auto', right: '0', margin: '0',\n                      }}\n                      /> */}\n                    <DeleteIcon\n                      onClick={() => onSubRowDelete(mainRowIndex, row.id)}\n                      size=\"small\"\n                      icon={<Icons.Close />}\n                      tooltip=\"Delete\"\n                      className=\"mx-2\"\n                    />\n                  </div>\n                  )}\n                </td>\n                {row.cells.map((cell, index) => <td key={index} className=\"text-left\" {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n              </tr>\n\n            </>\n          );\n        })}\n      </tbody>\n      {!isDisable && (\n        <td colSpan=\"5\">\n          <div\n            className=\"ml-16 pb-2 text-sm text-gray-white flex underline items-center cursor-pointer labelGroup focus:outline-none focus:text-primary-dark\"\n          >\n            <div\n              className=\"w-4 h-4 mr-2\"\n              onClick={onAddSubRow}\n            >\n              <Icons.Add />\n            </div>\n            <span onClick={onAddSubRow}>Add row</span>\n          </div>\n        </td>\n      )}\n    </table>\n  // </DndProvider>\n  );\n}\n\nexport const SubRow = ({\n  subRows, onAddSubRow, onSubRowInputChange, mainRowIndex, onSubRowDelete, totalRowCount,\n}) => {\n  const isAutoGenerated = useSelector(({ constants }) => constants.constantList.find((d) => d._id === constants.currentId)?.type === CONSTANT_GENERATE_TYPE.AUTO);\n\n  const columns = React.useMemo(\n    () => [\n      {\n        Header: 'Attribute/Key',\n        accessor: 'attribute',\n        minWidth: 230,\n        width: 230,\n        maxWidth: 230,\n      },\n      {\n        Header: 'Type',\n        accessor: 'type',\n        minWidth: 240,\n        width: 240,\n        maxWidth: 240,\n      },\n      {\n        Header: 'Value',\n        accessor: 'value',\n        minWidth: 250,\n        width: 250,\n        maxWidth: 250,\n      },\n    ],\n    [],\n  );\n  React.useEffect(() => {\n    if (last(subRows)?.attribute?.length > 0 && !isAutoGenerated) onAddSubRow();\n  }, []);\n  return (\n    <>\n      <td colSpan=\"4\" className=\"subRow\">\n        <Table\n          columns={columns}\n          data={subRows}\n          totalRowCount={totalRowCount}\n          mainRowIndex={mainRowIndex}\n          onInputChange={onSubRowInputChange}\n          onAddSubRow={onAddSubRow}\n          onSubRowDelete={onSubRowDelete}\n        />\n      </td>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Constant/ConstantView/TableView/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\nimport React from 'react';\nimport { useTable } from 'react-table';\nimport { cloneDeep, isEmpty, last } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport '../../../../assets/css/Table.css';\nimport {\n  ConfirmationAlert,\n  DeleteIcon, IconBox,\n} from '../../../../components';\nimport { SubRow } from './SubRow';\nimport EditableCell from './EditableCell';\nimport { CONSTANT_GENERATE_TYPE, NODE_DATA_TYPE } from '../../../../constant/applicationConstant';\nimport { useBoolean, useToastNotifications } from '../../../hooks';\n\nconst subEmptyRow = { attribute: '', value: '', type: 'string' };\nconst mainEmptyRow = {\n  attribute: '',\n  value: '',\n  type: 'json',\n  isExpanded: true,\n};\n\nconst defaultColumn = {\n  Cell: EditableCell,\n};\nexport const RowDeleteMessage = 'The constant attribute has been deleted successfully.';\n\nconst checkType = (data) => {\n  if ([NODE_DATA_TYPE.STRING, NODE_DATA_TYPE.NUMBER].includes(typeof data)) {\n    return typeof data;\n  }\n  if (data === null) {\n    return NODE_DATA_TYPE.NUMBER;\n  }\n  if (!Array.isArray(data) && typeof data === 'object') {\n    return NODE_DATA_TYPE.JSON;\n  }\n  if (Array.isArray(data)) {\n    return NODE_DATA_TYPE.ARRAY;\n  }\n  return null;\n};\n\nconst jsonToTableParser = (jsonData) => Object.keys(jsonData).map((key) => ({\n  isInitial: true,\n  attribute: key,\n  type: checkType(jsonData[key]),\n  value: jsonData[key] === null ? null : !Array.isArray(jsonData[key]) && typeof jsonData[key] === 'object' ? '-' : jsonData[key],\n  ...(!Array.isArray(jsonData[key]) && typeof jsonData[key] === 'object' && { subRows: isEmpty(jsonData[key]) ? [{ ...subEmptyRow }] : jsonToTableParser(jsonData[key]) }),\n\n}));\n\nconst Row = ({\n  row,\n  onExpand, onAddSubRow, totalRowCount, onSubRowInputChange, isDisable, onDeleteRow, onSubRowDelete,\n}) => (\n  <>\n    <tr\n      {...row.getRowProps()}\n      className=\"align-middle\"\n    >\n      <td style={{ minWidth: '80px', maxHeight: '80px', width: '80px' }}>\n        <div className=\"flex justify-start items-center h-full\">\n          {!isDisable && (\n            <>\n              <DeleteIcon\n                size=\"small\"\n                onClick={() => onDeleteRow(row.id)}\n                icon={<Icons.Close />}\n                tooltip=\"Delete\"\n                className=\"mx-1\"\n              />\n            </>\n          )}\n          {row.original.type === NODE_DATA_TYPE.JSON && (\n            <span onClick={() => onExpand(row)}>\n              <IconBox size=\"small\" icon={row.original.isExpanded ? <Icons.DownArrow /> : <Icons.RightArrow />} variant=\"ghost\" />\n            </span>\n          )}\n        </div>\n      </td>\n      {row.cells.map((cell, index) => <td key={index} style={['attribute', 'type'].includes(cell.column.id) ? { minWidth: '208px', maxWidth: '208px', width: '208px' } : {}} className=\"sm:text-left\" {...cell.getCellProps()}>{cell.render('Cell')}</td>)}\n    </tr>\n    {\n    row.original.isExpanded\n    && (\n    <tr>\n      <SubRow\n        subRows={[...row.original.subRows]}\n        isDisable={isDisable}\n        mainRowIndex={row.id}\n        totalRowCount={totalRowCount}\n        onAddSubRow={() => onAddSubRow(row.id)}\n        onSubRowDelete={onSubRowDelete}\n        onSubRowInputChange={onSubRowInputChange}\n      />\n    </tr>\n    )\n}\n  </>\n);\nfunction Table({\n  columns, data, onInputChange, onAddRow, onExpand, onAddSubRow,\n  onSubRowInputChange, onDeleteRow, onSubRowDelete, totalRowCount,\n}) {\n  // Use the state and functions returned from useTable to build your UI\n  const {\n    getTableProps,\n    getTableBodyProps,\n    headerGroups,\n    rows,\n    prepareRow,\n  } = useTable({\n    columns,\n    data,\n    defaultColumn,\n    onInputChange,\n    onAddRow,\n    totalRowCount,\n  });\n  const isDisable = useSelector(({ constants }) => constants.constantList.find((d) => d._id === constants.currentId)?.type === CONSTANT_GENERATE_TYPE.AUTO);\n  // Render the UI for your table\n  return (\n\n    <table {...getTableProps()} className=\"w-full\">\n      <thead>\n        {headerGroups.map((headerGroup, index) => (\n          <tr key={index} {...headerGroup.getHeaderGroupProps()}>\n            <th key=\"col-icon\" style={{ minWidth: '80px', maxHeight: '80px', width: '80px' }}>\n              {!isDisable && (\n                <IconBox\n                  size=\"small\"\n                  className=\"\"\n                  icon={<Icons.Plus color=\"#ffffff\" />}\n                  onClick={onAddRow}\n                  tooltip=\"Add Constant\"\n                />\n              )}\n            </th>\n            {headerGroup.headers.map((column) => (\n              <th key={column.id} {...column.getHeaderProps()}>{column.render('Header')}</th>\n            ))}\n          </tr>\n        ))}\n      </thead>\n      <tbody {...getTableBodyProps()}>\n        {rows.map((row, index) => (\n          prepareRow(row)\n          || (\n            row.depth === 0\n          && (\n          <Row\n            key={`row${index}`}\n            index={index}\n            totalRowCount={totalRowCount}\n            row={row}\n            isDisable={isDisable}\n            tableJson={data}\n            onAddSubRow={onAddSubRow}\n            onSubRowInputChange={onSubRowInputChange}\n            onDeleteRow={onDeleteRow}\n            onSubRowDelete={onSubRowDelete}\n            onExpand={onExpand}\n            {...row.getRowProps()}\n          />\n          )\n          )\n        ))}\n      </tbody>\n    </table>\n  // </DndProvider>\n\n  );\n}\n\n// eslint-disable-next-line no-unused-vars\nexport const TableView = ({\n  setTableJsonRef,\n  defaultTableJson = [],\n  handleUpdate,\n  onSaveRef,\n}) => {\n  const [tableJson, setTableJson] = React.useState(defaultTableJson);\n  const [totalRowCount, setTotalRowCount] = React.useState(0);\n  const { currentConstant, constantList, isAutoGenerated } = useSelector(({ constants }) => ({\n    currentConstant: constants.currentId,\n    constantList: constants.constantList,\n    isAutoGenerated: constants.constantList.find((d) => d._id === constants.currentId)?.type === CONSTANT_GENERATE_TYPE.AUTO,\n  }), shallowEqual);\n  const [isDelete, setDelete, hideDelete] = useBoolean(false);\n  const deleteRowIndex = React.useRef({ mainRow: '', subRow: '' });\n  const jsonData = constantList.find((constant) => constant._id === currentConstant)?.customJson ?? {};\n\n  const { addSuccessToast } = useToastNotifications();\n  const keyBoardIndexSet = (paramTableJson) => {\n    let focusIndex = 0;\n    const temp = paramTableJson || tableJson;\n    temp.forEach((json, index) => {\n      temp[index].focusIndex = focusIndex * 3;\n      focusIndex += 1;\n      if (json.subRows) {\n        json.subRows.forEach((sub, jsonIndex) => {\n          temp[index].subRows[jsonIndex] = { ...temp[index].subRows[jsonIndex], focusIndex: focusIndex * 3 };\n          focusIndex += 1;\n        });\n      }\n    });\n    setTotalRowCount(focusIndex);\n  };\n  const handleCurEleFocus = (key) => {\n    // handle new row focus\n    requestAnimationFrame(() => {\n      const nextFiled = document.querySelector(`#r${(key) + 1}`);\n      nextFiled?.focus();\n    });\n  };\n  React.useEffect(() => {\n    if (!isEmpty(defaultTableJson.filter((dt) => (dt.attribute && dt.type) || dt.value))) {\n      keyBoardIndexSet(defaultTableJson);\n      handleCurEleFocus(last(defaultTableJson)?.focusIndex);\n\n      setTableJson([...defaultTableJson]);\n      return;\n    }\n    const tableData = !isEmpty(Object.keys(jsonData)) ? [...jsonToTableParser(jsonData)] : [];\n    if (!isAutoGenerated)tableData.push({ ...mainEmptyRow, subRows: [{ ...subEmptyRow }] });\n    keyBoardIndexSet(tableData);\n    handleCurEleFocus(last(tableData)?.focusIndex);\n\n    setTableJson(tableData);\n  }, [currentConstant]);\n  const columns = React.useMemo(() => [\n    {\n      key: 'Attribute/Key',\n      Header: 'Key',\n      accessor: 'attribute',\n      minWidth: 250,\n      width: 250,\n      maxWidth: 250,\n    },\n    {\n      Header: 'Data type',\n      accessor: 'type',\n      minWidth: 250,\n      width: 250,\n      maxWidth: 250,\n    },\n    {\n      Header: 'Value',\n      accessor: 'value',\n      minWidth: 150,\n      // width: 500,\n      // width: 'auto',\n      maxWidth: 300,\n    },\n  ], []);\n\n  React.useEffect(() => {\n    setTableJsonRef(tableJson);\n  }, [tableJson]);\n  const onAddRow = () => {\n    tableJson.push({ ...mainEmptyRow, subRows: [{ ...subEmptyRow }] });\n    keyBoardIndexSet(tableJson);\n\n    setTableJsonRef(tableJson);\n    handleCurEleFocus(last(tableJson)?.focusIndex);\n    setTableJson([...tableJson]);\n  };\n  React.useImperativeHandle(onSaveRef, () => ({\n    updateTableJson: () => {\n      const newTable = jsonToTableParser(jsonData);\n      newTable.push({ ...mainEmptyRow, subRows: [{ ...subEmptyRow }] });\n      setTableJson(newTable);\n    },\n  }));\n  const onInputChange = (index, columnName, value) => {\n    tableJson[index][columnName] = value;\n    if (columnName === 'type') {\n      tableJson[index].value = value === NODE_DATA_TYPE.ARRAY ? [] : value === NODE_DATA_TYPE.NUMBER ? null : '';// default value type wise store\n      tableJson[index].isExpanded = value === NODE_DATA_TYPE.JSON;\n      tableJson[index].subRows = null;\n      if (value === NODE_DATA_TYPE.JSON && !tableJson[index].subRows) {\n        tableJson[index].subRows = [{ ...subEmptyRow }];\n        keyBoardIndexSet(tableJson);\n        handleCurEleFocus(last(tableJson[index].subRows)?.focusIndex);\n      }\n\n      setTableJson([...tableJson]);\n      return;\n    }\n    if (columnName === 'attribute') {\n      if (last(tableJson)?.[columnName]?.length > 0) { onAddRow(); return; }\n    }\n    setTableJsonRef(tableJson);\n    setTableJson(tableJson);\n  };\n  const onExpand = (row) => {\n    tableJson[row.index].isExpanded = !row.original.isExpanded;\n    handleCurEleFocus(last(tableJson[row.index]?.subRows)?.focusIndex);\n\n    setTableJson([...tableJson]);\n  };\n\n  const onAddSubRow = (index) => {\n    tableJson[index].subRows?.push({ ...subEmptyRow });\n    keyBoardIndexSet(tableJson);\n    handleCurEleFocus(last(tableJson[index].subRows)?.focusIndex);\n    setTableJsonRef(tableJson);\n    setTableJson([...tableJson]);\n  };\n  const onSubRowInputChange = (index, columnName, value, mainRowIndex) => {\n    tableJson[mainRowIndex].subRows[index][columnName] = value;\n    if (columnName === 'type') {\n      tableJson[mainRowIndex].subRows[index].value = value === NODE_DATA_TYPE.ARRAY ? [] : value === NODE_DATA_TYPE.NUMBER ? null : '';\n      setTableJson([...tableJson]);\n      return;\n    }\n    if (columnName === 'attribute') {\n      if (last(tableJson[mainRowIndex].subRows)?.[columnName]?.length > 0) { onAddSubRow(mainRowIndex); return; }\n    }\n    setTableJsonRef(tableJson);\n    setTableJson(tableJson);\n  };\n\n  const onRowDelete = async () => {\n    const newTable = [...tableJson];\n    newTable.splice(deleteRowIndex.current.mainRow, 1);\n    if (tableJson[deleteRowIndex.current.mainRow]?.isInitial) {\n      handleUpdate(newTable);\n      deleteRowIndex.current = {};\n      hideDelete();\n      return;\n    }\n    setTableJson(isEmpty(newTable) ? [{ ...mainEmptyRow, subRows: [{ ...subEmptyRow }] }] : newTable);\n    deleteRowIndex.current = {};\n    hideDelete();\n    addSuccessToast(RowDeleteMessage);\n  };\n\n  const onSubRowDelete = () => {\n    // cloneDeep to clone subRow also\n    const newTable = cloneDeep(tableJson);\n\n    newTable[deleteRowIndex.current.mainRow].subRows.splice(deleteRowIndex.current.subRow, 1);\n    if (tableJson[deleteRowIndex.current.mainRow].subRows[deleteRowIndex.current.subRow]?.isInitial) {\n      handleUpdate(newTable);\n      deleteRowIndex.current = {};\n      hideDelete();\n      return;\n    }\n    if (isEmpty(newTable[deleteRowIndex.current.mainRow].subRows))newTable[deleteRowIndex.current.mainRow].subRows = [{ ...subEmptyRow }];\n    setTableJson(newTable);\n    deleteRowIndex.current = {};\n    hideDelete();\n    addSuccessToast(RowDeleteMessage);\n  };\n\n  React.useEffect(() => {\n    keyBoardIndexSet();\n  }, [tableJson]);\n  return (\n\n    <div className=\"dhiTable reactTable relative text-left flex-grow h-full w-7/12\">\n      <Table\n        columns={columns}\n        data={tableJson || []}\n        totalRowCount={totalRowCount}\n        onExpand={onExpand}\n        onAddRow={onAddRow}\n        onInputChange={onInputChange}\n        onAddSubRow={onAddSubRow}\n        onDeleteRow={(rowIndex) => {\n          deleteRowIndex.current = { mainRow: rowIndex };\n          setDelete();\n        }}\n        onSubRowDelete={(mainRow, subRow) => {\n          deleteRowIndex.current = { mainRow, subRow };\n          setDelete();\n        }}\n        onSubRowInputChange={onSubRowInputChange}\n      />\n      {isDelete && (\n      <ConfirmationAlert\n        description=\"Constant attribute will be deleted permanently and cannot be restored in the future.Are you sure do you want to delete this constant attribute?\"\n        handleSubmit={deleteRowIndex.current.subRow ? onSubRowDelete : onRowDelete}\n        isOpen={isDelete}\n        handleClose={hideDelete}\n      />\n      )}\n    </div>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Constant/ConstantView/index.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport { Button } from '../../../components';\nimport { ConstantHead } from './ConstantHead';\nimport { useBoolean } from '../../../components/hooks';\nimport { CONSTANT_GENERATE_TYPE, NODE_DATA_TYPE } from '../../../constant/applicationConstant';\nimport { CodeEditor } from '../../../components/CodeEditor';\nimport { Error } from '../../../components/Error';\nimport DeleteConstant from '../DeleteConstant';\nimport { RowDeleteMessage, TableView } from './TableView';\nimport { useToastNotifications } from '../../hooks';\n\nconst jsonLint = require('jsonlint');\n\nconst tableToJsonParser = (table) => {\n  const a = {};\n  table.forEach((tb) => {\n    if (isEmpty(tb.attribute) || isEmpty(tb.type)) return;\n    a[tb.attribute] = tb.type !== NODE_DATA_TYPE.JSON ? tb.value : tableToJsonParser(tb.subRows);\n  });\n  return a;\n};\nexport const ConstantView = React.memo(() => {\n  const selectedConstant = useSelector((state) => state.constants.currentId);\n  const constantList = useSelector((state) => state.constants.constantList);\n  const currentConstantData = constantList.find((d) => d._id === selectedConstant);\n  const isDisable = currentConstantData?.type === CONSTANT_GENERATE_TYPE.AUTO;\n  const [code, setCode] = React.useState(JSON.stringify({}));\n  const [isError, setShowError, setHideError] = useBoolean(false);\n  const [jsonError, setJsonError] = React.useState(false);\n  const [loading, setLoading, hideLoading] = useBoolean(false);\n  const onSaveRef = React.useRef('');\n  const codeRef = React.useRef();\n  const updateRef = React.useRef();\n  const tableJsonRef = React.useRef([]);\n  const { addSuccessToast } = useToastNotifications();\n\n  const handleUpdate = async (deleteJson) => {\n    if (jsonError) {\n      setShowError();\n      return;\n    }\n    const tableToCode = tableToJsonParser(deleteJson || tableJsonRef.current);\n    if (isEmpty(tableToCode) && !deleteJson && isEmpty(currentConstantData?.customJson)) return;\n    setLoading();\n    await updateRef.current?.handelConstantProperty('customJson', tableToCode, !deleteJson);\n    await updateRef.current?.setHideEdit();\n    hideLoading();\n    onSaveRef.current?.updateTableJson();\n    if (deleteJson) {\n      addSuccessToast(RowDeleteMessage);\n    }\n    setCode(JSON.stringify(tableToCode, null, 2));\n  };\n\n  React.useEffect(() => {\n    codeRef.current = code;\n  }, [code]);\n\n  React.useEffect(() => {\n    setCode(isDisable && typeof currentConstantData?.customJson !== 'object' ? currentConstantData?.customJson : JSON.stringify(JSON.parse(JSON.stringify(currentConstantData?.customJson || {})), null, 2));\n  }, [selectedConstant]);\n  return (\n    <div className=\"flex flex-col w-full h-full\">\n      <div className=\"px-3 py-3 flex justify-between headTop\">\n        <ConstantHead updateRef={updateRef} isDisable={isDisable} />\n        <div className=\"flex items-center\">\n\n          <DeleteConstant selectedConstant={selectedConstant} isDisable={isDisable} />\n          {!isDisable && (\n            <Button\n              variant=\"primary\"\n              onClick={() => {\n                handleUpdate();\n              }}\n              shape=\"rounded\"\n              size=\"medium\"\n              className=\"ml-2\"\n              loading={loading}\n            >\n              Save\n            </Button>\n          )}\n        </div>\n      </div>\n\n      <div className=\"flex h-0 w-full flex-grow\">\n        <TableView\n          handelConstantProperty={updateRef.current}\n          defaultTableJson={tableJsonRef.current}\n          onSaveRef={onSaveRef}\n          handleUpdate={handleUpdate}\n          setTableJsonRef={(tableJson) => {\n            tableJsonRef.current = tableJson;\n            setCode(JSON.stringify(tableToJsonParser(tableJson), null, 2));\n          }}\n        />\n\n        <div className=\"w-5/12 h-full border-1 border-gray-200\">\n          <CodeEditor\n            readOnly\n            value={code}\n            className=\"bg-gray-black py-2\"\n            onChange={(tempCode) => {\n              try {\n                jsonLint.parse(tempCode);\n                setJsonError(false);\n                setHideError();\n                setCode(tempCode);\n              } catch (err) {\n                if (code && !tempCode) {\n                  setCode('{}');\n                }\n                setJsonError(err);\n              }\n            }}\n            onValidate={(errors) => {\n              if (isEmpty(errors)) {\n                setHideError();\n                setJsonError(false);\n              }\n            }}\n            isJSONStringify={false}\n          />\n        </div>\n      </div>\n\n      { isError\n        ? <Error isOpen={isError} error={jsonError} handleCancel={setHideError} /> : null}\n    </div>\n  );\n});\nConstantView.displayName = 'ConstantView';\n"
  },
  {
    "path": "packages/client/src/container/Constant/DeleteConstant/index.js",
    "content": "import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { deleteConstant } from '../../../api/applicationConstant';\nimport { Button, ConfirmationAlert } from '../../../components';\nimport { useBoolean, useToastNotifications } from '../../hooks';\nimport { deleteCurrentConstant } from '../../../redux/reducers/constants';\n\nfunction DeleteConstant({ selectedConstant, isDisable }) {\n  const dispatch = useDispatch();\n\n  const [isDelete, setDelete, removeSetDelete] = useBoolean(false);\n  const [isLoading, setLoading, removeLoading] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const handelDelete = React.useCallback(() => {\n    setLoading();\n    deleteConstant({ id: selectedConstant, isHardDelete: true }).then((response) => {\n      addSuccessToast(response.message);\n      dispatch(deleteCurrentConstant());\n    }).catch((err) => {\n      addErrorToast(err);\n    }).finally(() => {\n      removeSetDelete();\n      removeLoading();\n    });\n  }, [selectedConstant]);\n\n  return (\n    <>\n      {isDelete && (\n      <ConfirmationAlert\n        description=\"Constant file will be deleted permanently and cannot be restored in the future. Are you sure do you want to delete this constant file?\"\n        handleSubmit={handelDelete}\n        isOpen={isDelete}\n        handleClose={removeSetDelete}\n        isLoading={isLoading}\n        // description=\"Do you want to delete this constant ?\"\n      />\n      )}\n\n      {!isDisable && (\n\n      <Button\n        size=\"medium\"\n        variant=\"outline\"\n        className=\"ml-2\"\n        shape=\"rounded\"\n        onClick={setDelete}\n      >\n        Delete\n      </Button>\n\n      )}\n\n    </>\n  );\n}\n\nexport default DeleteConstant;\n"
  },
  {
    "path": "packages/client/src/container/Constant/LeftConstantList/index.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { SidebarList } from '../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../../components';\nimport { setCurrentConstant } from '../../../redux/reducers/constants';\n\nexport const LeftConstantList = React.memo(({\n  addConstant,\n}) => {\n  const dispatch = useDispatch();\n  const constantList = useSelector((state) => state.constants.constantList);\n  const currentConstant = useSelector((state) => state.constants.currentId);\n\n  return (\n    <SidebarList isAddButton title=\"Constant\" addClick={addConstant} tooltip=\"Add constant\">\n      <Menu iconShape=\"square\" className=\"p-2\">\n        <SidebarMenuList\n          mainMenuList={constantList}\n          titleKey=\"fileName\"\n          onClick={(data) => dispatch(setCurrentConstant(data))}\n          initialSelectedId={currentConstant || constantList?.[0]?._id}\n        />\n      </Menu>\n    </SidebarList>\n  );\n});\nLeftConstantList.displayName = 'LeftConstantList';\n"
  },
  {
    "path": "packages/client/src/container/Constant/index.js",
    "content": "import React from 'react';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport { ConstantView } from './ConstantView';\nimport Layout from '../Shared/Layout';\nimport { BoxLayout, NoData, Loader } from '../../components';\nimport { listConstants } from '../../redux/thunks/constants';\nimport { AddConstant } from './AddConstant';\nimport { LeftConstantList } from './LeftConstantList';\nimport { listModels } from '../../redux/thunks/models';\n\nexport default function Constant() {\n  const addModalRef = React.useRef();\n  const {\n    constantList, loading, applicationId, selectedConstants,\n  } = useSelector(({ constants, projects }) => ({\n    constantList: constants.constantList,\n    loading: constants.listConstantFetching,\n    applicationId: projects.currentApplicationId,\n    selectedConstants: constants.currentId,\n    currentApplicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n\n  const dispatch = useDispatch();\n  const fetchAllConstant = () => {\n    dispatch(listConstants({\n      applicationId,\n      isActiveDeactivateDisplay: true,\n    }));\n  };\n  React.useEffect(() => {\n    fetchAllConstant();\n    dispatch(listModels({ applicationId }));\n  }, []);\n  return (\n    <Layout isSidebar>\n\n      <div className=\"w-sidebarRight flex\">\n        {loading && <Loader style={{ minHeight: 'auto' }} className=\"w-full\" />}\n        { !loading && (\n        <>\n          {!isEmpty(constantList) ? (\n            <>\n              <LeftConstantList\n                addConstant={() => {\n                  addModalRef.current?.showConstantModal();\n                }}\n              />\n              <BoxLayout variant=\"subRight\">\n                <ConstantView key={selectedConstants} />\n              </BoxLayout>\n            </>\n          )\n            : (\n              <NoData\n                onClick={() => {\n                  addModalRef.current?.showConstantModal();\n                }}\n                btnText=\"Add constant\"\n                title=\"No constant found\"\n              />\n            )}\n          <AddConstant\n            addModalRef={addModalRef}\n          />\n        </>\n        )}\n      </div>\n\n    </Layout>\n\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/Dashboard/MenuShortCut/index.js",
    "content": "/* eslint-disable react/jsx-props-no-spreading */\nimport { Icons } from '@dhiwise/icons';\nimport React from 'react';\nimport { useHistory } from 'react-router';\nimport {\n  Button, CardView, Description, Heading,\n} from '../../../components';\nimport { RedirectUrl } from '../../../constant/Nodecrud';\nimport { APPLICATION_CODE } from '../../../constant/Project/applicationStep';\n\nconst NodeDashboard = [{\n  title: 'Models',\n  description: 'Create or upload your model data.',\n  pageUrl: RedirectUrl[APPLICATION_CODE.nodeExpress].model.pageUrl,\n  pageButtonName: 'Create model',\n  icon: <Icons.Model />,\n  isSetHistory: true,\n  countMapKey: 'schemas',\n\n}, {\n  title: 'Authentication',\n  description: 'Configure authentication module.',\n  pageUrl: '/node/configuration',\n  pageButtonName: 'Authentication',\n  icon: <Icons.Authentication />,\n  countMapKey: 'authentication',\n\n},\n{\n  title: 'Routes',\n  description: 'Add and customize your model(s) route.',\n  pageUrl: RedirectUrl[APPLICATION_CODE.nodeExpress].route.pageUrl,\n  pageButtonName: 'Create routes',\n  icon: <Icons.Routes />,\n  countMapKey: 'routes',\n\n},\n{\n  title: 'Platform Configuration',\n  description: 'Configure platform access.',\n  pageUrl: RedirectUrl[APPLICATION_CODE.nodeExpress].platformConfig.pageUrl,\n  pageButtonName: ' Set configuration',\n  icon: <Icons.Configuration />,\n  countMapKey: 'configuration',\n\n},\n{\n  title: 'Role access permission',\n  description: 'Configure role based access for model(s).',\n  pageUrl: '/node/role-access',\n  pageButtonName: 'Set role',\n  icon: <Icons.RoleAccess />,\n  countMapKey: 'role_access_permission',\n\n}];\n\nconst MenuShortCutItem = ({\n  title, description, pageButtonName, icon, pageUrl, isSetHistory = false,\n}) => {\n  const history = useHistory();\n  return (\n    <CardView variantHover=\"default\" leftCard className=\"bg-gray-300 hover:bg-gray-300 cursor-text sm:border-1 relative\">\n      <div className=\"flex items-center mb-2\">\n        <div className=\"w-5 h-5 mr-3\">\n          {icon}\n        </div>\n        <Heading variant=\"h5\">\n          {title}\n        </Heading>\n      </div>\n      <Description className=\"text-left\">\n        {description}\n      </Description>\n      <div className=\"flex items-center mt-3 flex-wrap\">\n        <Button\n          size=\"smallMedium\"\n          shape=\"rounded\"\n          variant=\"primary\"\n          className=\"mr-2 mt-2\"\n          onClick={() => {\n            history.push(pageUrl, isSetHistory ? { isOpenPopup: true } : undefined);\n          }}\n        >\n          {pageButtonName}\n        </Button>\n      </div>\n    </CardView>\n  );\n};\n\nexport const MenuShortCut = () => (\n  <div>\n    <Heading variant=\"h4\">Core features</Heading>\n    <div className=\"grid grid-cols-3 xxl:grid-cols-4 gap-5 mt-5\">\n      {NodeDashboard.map((dashboard) => (\n        <MenuShortCutItem key={dashboard.title} {...dashboard} />\n      ))}\n    </div>\n\n  </div>\n);\n"
  },
  {
    "path": "packages/client/src/container/Dashboard/index.js",
    "content": "/* eslint-disable no-nested-ternary */\nimport React from 'react';\nimport { Helmet } from 'react-helmet';\nimport Layout from '../Shared/Layout';\nimport {\n  BoxLayout,\n} from '../../components';\nimport { MenuShortCut } from './MenuShortCut';\n\nfunction Dashboard() {\n  return (\n    <>\n      <Layout isSidebar>\n        <Helmet>\n          <meta name=\"viewport\" content=\"width=1200, initial-scale=0, maximum-scale=0,user-scalable=0\" />\n        </Helmet>\n        <BoxLayout variant=\"mainRight\" className=\"flex\">\n          <div\n            className=\"overflow-auto py-5 px-5 w-full\"\n          >\n            <div className=\"flex\">\n              <div className=\"w-full\">\n                <div className=\"\">\n                  <MenuShortCut />\n                </div>\n\n              </div>\n            </div>\n          </div>\n        </BoxLayout>\n      </Layout>\n    </>\n  );\n}\nexport default Dashboard;\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/EnvironmentHead/index.js",
    "content": "import React from 'react';\nimport Popover from 'react-popover';\nimport { Icons } from '@dhiwise/icons';\nimport {\n  Button, ConfirmationAlert, Description, Heading, SearchBox, IconBox,\n} from '../../../components';\nimport { useBoolean } from '../../hooks';\n\nexport const EnvironmentHead = React.memo(({\n  onSave, upsertLoader, onDelete, onSearch, deleteLoader, isSearch, isSelected, isLastObj, title, desc, headTooltip,\n}) => {\n  const [isOtherProOpen, setisOtherProOpen] = React.useState(false);\n\n  const [isDelete, setIsDelete, hideDelete] = useBoolean(false);\n  const handleDelete = () => {\n    setIsDelete();\n  };\n  const handleClose = () => {\n    hideDelete();\n  };\n  const alertDescription = 'Environment variable will be deleted permanently and cannot be restored in the future.Are you sure do you want to delete this environment variable?';\n  return (\n    <>\n      <div className=\"p-3 flex justify-between items-center enviromentTop w-full\">\n        <div className=\"w-6/12\">\n          <Heading variant=\"h4\" className=\"flex items-center\">\n            {title || 'Environment variable'}\n            {!!headTooltip\n            && (\n              <div\n                onMouseOut={() => setisOtherProOpen(false)}\n                onMouseOver={() => setisOtherProOpen(true)}\n              >\n                <Popover\n                  place=\"below\"\n                  body={[\n                    <Description key={title} className=\"w-96 text-left\">{headTooltip}</Description>,\n                  ]}\n                  className=\"popupCustom\"\n                  isOpen={isOtherProOpen}\n                >\n\n                  <IconBox variant=\"ghost\" size=\"small\" className=\"\" icon={<Icons.Info />} />\n                </Popover>\n              </div>\n            )}\n          </Heading>\n          {!!desc && <Description className=\"\">{desc}</Description>}\n        </div>\n        <div className=\"w-6/12 flex justify-end items-center\">\n          <div className=\"h-8 w-48\">\n            <SearchBox placeholder=\"Search\" value={isSearch || undefined} onSearch={onSearch} />\n          </div>\n          <Button\n            size=\"medium\"\n            variant=\"outline\"\n            shape=\"rounded\"\n            className=\"ml-2\"\n            loading={deleteLoader}\n            onClick={handleDelete}\n            disabled={!isSelected || isLastObj}\n          >\n            Delete\n          </Button>\n          <Button\n            size=\"medium\"\n            variant=\"primary\"\n            shape=\"rounded\"\n            className=\"ml-2\"\n            disabled={deleteLoader}\n            loading={!deleteLoader && upsertLoader}\n            onClick={onSave}\n          >\n            Save\n          </Button>\n        </div>\n      </div>\n      <ConfirmationAlert\n        isOpen={isDelete}\n        description={alertDescription}\n        handleClose={handleClose}\n        handleSubmit={() => {\n          onDelete();\n          hideDelete();\n        }}\n      />\n    </>\n  );\n});\nEnvironmentHead.displayName = 'EnvironmentHead';\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/KeyValue.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable radix */\nimport React from 'react';\nimport { isEmpty, isNaN } from 'lodash';\nimport {\n  APIKeyValue,\n} from '../../components';\nimport { ValueComponent } from '../../components/APIKeyValue';\nimport { enviromentVaribleCss } from './enviromentVaribleCss';\nimport { ENV } from '../../constant/envVariable';\n\nimport { RESERVED_VARIABLES, RESERVED_VALIDATION_MESSAGE } from '../../constant/reservedVariable';\nimport { keyBoardShortcut } from '../../utils/domMethods';\n\nlet TotalColumns;\nexport const ValueItem = React.memo(({\n  disabled, value, envObj, error, name, onKeyDown, onChange, id, inputId,\n}) => (\n  <td className={enviromentVaribleCss.keyValueItem}>\n    <ValueComponent\n      disabled={disabled}\n      WrapClassName=\"w-full\"\n      placeholder=\"Enter value\"\n      value={value}\n      name={name}\n      inputId={inputId}\n      id={id}\n      onKeyDown={(e) => {\n        if (e.ctrlKey || e.keyCode === 13) {\n          onKeyDown(e);\n          if (e.ctrlKey) e.preventDefault();\n        }\n      }}\n      onChange={onChange}\n      type={envObj.dataType}\n      error={!disabled && error ? error : ''}\n    />\n  </td>\n));\nValueItem.displayName = 'ValueItem';\nexport const KeyValue = React.memo(({\n  envObj, environments, onChange, onSelect, onDelete, errors, isLastObj, applicationCode, lengthOfData, rowIndex,\n}) => {\n  if (!envObj) return null;\n  const FiledPosition = {\n    checkBox: rowIndex + 1,\n    key: rowIndex + 2,\n    development: rowIndex + 3,\n    qa: rowIndex + 4,\n    production: rowIndex + 5,\n  };\n\n  const handleRowAutoFocus = (focusFiled) => {\n    // eslint-disable-next-line radix\n    const field = document.querySelector(`#r${FiledPosition[focusFiled]}`);\n    field?.focus();\n  };\n\n  // eslint-disable-next-line consistent-return\n  const reservedVariableValidation = () => {\n    const errorMessage = RESERVED_VALIDATION_MESSAGE;\n    if (RESERVED_VARIABLES[applicationCode]?.NODE_EXPRESS?.includes(envObj.key.toLowerCase())) return errorMessage;\n    if (RESERVED_VARIABLES.COMMON?.includes(envObj.key.toLowerCase())) return errorMessage;\n  };\n\n  // eslint-disable-next-line consistent-return\n  const requiredValidation = (e) => {\n    const developmentObj = envObj.value.DEVELOPMENT;\n    if (envObj.key && e === ENV.DEVELOPMENT && (developmentObj === '' || developmentObj === null || developmentObj === undefined || isNaN(developmentObj))) {\n      return 'Value is required';\n    }\n    if (envObj.key && e === ENV.DEVELOPMENT && (developmentObj === 'true' || developmentObj === 'false')) {\n      return '';\n    }\n  };\n  const handleValue = (options) => {\n    const tempObj = { ...envObj };\n    tempObj.value[options.env] = options.value;\n    onChange(tempObj, options.key);\n  };\n\n  const handleKey = (options) => {\n    const tempObj = { ...envObj };\n    tempObj[options.key] = options.value;\n    if (options.key === 'dataType') {\n      // clear value on change data type\n      Object.keys(envObj.value)?.forEach((e) => {\n        tempObj.value[e] = '';\n      });\n    }\n    onChange(tempObj, options.key);\n    if (options.isFocus) {\n      requestAnimationFrame(() => {\n        handleRowAutoFocus(options.key);\n      });\n    }\n  };\n\n  const onKeyDownHandel = (e, focusField) => {\n    TotalColumns = 4;\n    const focusIndex = FiledPosition[focusField];\n\n    keyBoardShortcut({\n      keyEvent: e,\n      focusIndex,\n      totalColumns: TotalColumns,\n      totalRows: lengthOfData,\n    });\n  };\n\n  return (\n    <>\n      <td className={enviromentVaribleCss.keyValueItemFirst}>\n        <APIKeyValue\n          envVariable\n          isCheckBox\n          isDelete\n          deleteProps={{ onDelete: () => onDelete(envObj), disabled: isLastObj && !envObj.key }}\n          inputProps={{\n            id: `r${FiledPosition.key}`,\n            name: 'key',\n            value: envObj.key,\n            onChange: (e) => handleKey({ value: e.toUpperCase(), key: 'key' }),\n            onKeyDown: (e) => {\n              onKeyDownHandel(e, 'key');\n            },\n            autoComplete: 'off',\n            error: errors && (reservedVariableValidation() || ((Object.keys(environments)?.filter((e) => environments[e])?.some((env) => envObj?.value[env])) && isEmpty(envObj.key) ? 'Key is required.' : '')),\n          }}\n          checkboxProps={{\n            id: `r${FiledPosition.checkBox}`,\n            value: true,\n            checked: !!envObj.isSelected,\n            onChange: (val) => {\n              onSelect(envObj, val);\n            },\n            onKeyDown: (e) => {\n              if (e.keyCode === 13) { onSelect(envObj, !e.target.checked, `r${FiledPosition.checkBox}`); }\n            },\n          }}\n        />\n      </td>\n      <table>\n        <tr className=\"align-top\">\n          {\n            Object.keys(ENV).map((e) => (\n              <ValueItem\n                // eslint-disable-next-line no-nested-ternary\n                id={e === 'DEVELOPMENT' ? `r${FiledPosition.development}` : e === 'QA' ? `r${FiledPosition.qa}` : `r${FiledPosition.production}`}\n                // eslint-disable-next-line no-nested-ternary\n                inputId={e === 'DEVELOPMENT' ? `r${FiledPosition.development}` : e === 'QA' ? `r${FiledPosition.qa}` : `r${FiledPosition.production}`}\n                name={`value${e}`}\n                envObj={envObj}\n                key={e}\n                disabled={!environments[e]}\n                value={envObj.value ? envObj.value[e] : undefined}\n                onChange={(val) => handleValue({\n                  value: val, env: ENV[e], key: e === 'DEVELOPMENT' ? `r${FiledPosition.development}` : e === 'QA' ? `r${FiledPosition.qa}` : `r${FiledPosition.production}`, isFocus: true,\n                })}\n                onKeyDown={(event) => {\n                  // eslint-disable-next-line no-nested-ternary\n                  onKeyDownHandel(event, e === 'DEVELOPMENT' ? 'development' : e === 'QA' ? 'qa' : 'production');\n                }}\n                error={errors && requiredValidation(e)}\n              />\n            ))\n          }\n        </tr>\n      </table>\n    </>\n  );\n});\nKeyValue.displayName = 'KeyValue';\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/Permission.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 5)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          width=\"100%\"\n          height=\"80\"\n          // viewBox=\"0 0 100% 80\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n          <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"15%\" height=\"6\" />\n\n          <rect x=\"27%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"27%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n\n          <rect x=\"55%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"55%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n\n          <rect x=\"80%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          <rect x=\"80%\" y=\"25\" rx=\"3\" ry=\"3\" width=\"20%\" height=\"6\" />\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/enviromentVaribleCss.js",
    "content": "export const enviromentVaribleCss = {\n  // sticky -left-3\n  enviroTableHead: 'top-0 z-1 bg-gray-black cursor-pointer py-3 px-4 text-base text-primary-text',\n  enviroTableHeadFirst: 'sticky top-0 z-10 pl-12 bg-gray-black cursor-pointer py-3 px-4 w-100',\n  keyValueItem: 'border-t border-gray-200 py-4 pr-5 px-4',\n  keyValueItemFirst: 'bg-gray-black pl-5 border-t border-gray-200 py-4 pr-10 w-100',\n};\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/environmentValue.js",
    "content": "import React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport last from 'lodash/last';\nimport {\n  toLower, omit, cloneDeep, isNaN, compact,\n} from 'lodash';\nimport { KeyValue } from './KeyValue';\nimport {\n  Checkbox,\n} from '../../components';\nimport { enviromentVaribleCss } from './enviromentVaribleCss';\nimport { ENV } from '../../constant/envVariable';\nimport { EnvironmentHead } from './EnvironmentHead';\nimport { useToastNotifications, useBoolean } from '../hooks';\nimport Spinner from './Permission.loader';\nimport { RESERVED_VARIABLES } from '../../constant/reservedVariable';\nimport { capitalizeStr } from '../../utils';\n\nconst EnvironmentValue = React.forwardRef(({\n  envList, loader, upsertLoader, onSave, HeadTitle, Headdesc, headTooltip, EnvDeleteMessage,\n}, ref) => {\n  const applicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const initObj = {\n    value: {\n      DEVELOPMENT: '',\n      QA: '',\n      PRODUCTION: '',\n    },\n    key: '',\n    dataType: '',\n    indexKey: '',\n  };\n  const [isAll, setIsAll] = useState(false);\n  const [isSearch, setIsSearch] = useState(false);\n  const [envData, setEnvData] = useState([]);\n  const envRef = React.useRef(null);\n  const [environments, setEnvironments] = useState({});\n  const [selectedRows, setSelectedRows] = useState([]);\n  const [errors, setErrors] = useState({});\n  const [deleteLoader, setDelete, hideDelete] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const handleSave = (isDelete) => {\n    let isError = false;\n    const curEnv = compact(cloneDeep(envRef.current));\n    if (!isDelete && curEnv.length === 1 && !curEnv[0].key) {\n      addErrorToast('Please enter environment variable key');\n      return;\n    }\n    const newEnvironments = Object.keys(environments).filter((e) => environments[e]);\n    if (!isDelete && (!newEnvironments || newEnvironments?.length === 0)) {\n      addErrorToast('Please select environment value');\n      return;\n    }\n    const customJson = [];\n    const allKeys = curEnv.map((x) => toLower(x.key)) || [];\n    if (allKeys.some((x) => (x && allKeys.indexOf(x) !== allKeys.lastIndexOf(x)))) {\n      addErrorToast('Duplicate key found. Please enter unique key.');\n      return;\n    }\n    curEnv?.map((x, index) => {\n      if (isDelete && !x.key) return x;\n      let obj = {\n        ...x,\n        index,\n        indexKey: `e${index}`,\n      };\n\n      if ((newEnvironments.some((env) => obj?.value[env])) && !obj?.key) isError = true;\n      if (RESERVED_VARIABLES[applicationCode]?.NODE_EXPRESS?.includes(obj.key.toLowerCase())) isError = true;\n      if (RESERVED_VARIABLES.COMMON?.includes(obj.key.toLowerCase())) isError = true;\n\n      if (!isDelete && (!obj.key && !newEnvironments.every((env) => obj?.value[env]))) return x;\n\n      if (x.value) {\n        Object.keys(x.value).map((e) => {\n          if (!newEnvironments.includes(e)) delete obj.value[e];\n          if (e === 'DEVELOPMENT') {\n            if (!newEnvironments.includes(e)) delete obj.value[e];\n            else if (!isDelete && obj.key && (obj.value[e] === undefined || obj.value[e] === null || obj.value[e] === '' || isNaN(obj.value[e]))) isError = true;\n          }\n          return e;\n        });\n      } else isError = true;\n      obj = omit(obj, ['indexKey', 'index', 'isSelected', 'isExist']);\n      customJson.push(obj);\n      return x;\n    });\n\n    if (!isDelete) {\n      setErrors(isError);\n      if (isError) {\n        return;\n      }\n    }\n    const request = {\n      environments: newEnvironments,\n      customJson,\n    };\n\n    isDelete && setDelete();\n    onSave(request, isDelete);\n  };\n\n  React.useImperativeHandle(ref, () => ({\n    envData, environments, selectedRows, setEnvData, setSelectedRows,\n  }));\n\n  const handleCurEleFocus = (key) => {\n    // handle new row focus\n    if (!key) return;\n    requestAnimationFrame(() => {\n      const nextfield = document.querySelector(`#${key} input[name=\"key\"]`);\n      nextfield?.focus();\n    });\n  };\n\n  const addNewData = (lists) => {\n    if (errors) setErrors(false);\n    // add blank new row\n    const tempData = cloneDeep(lists);\n    const obj = {\n      ...initObj,\n      indexKey: `e${isSearch ? envRef.current.length : tempData.length}`,\n      index: isSearch ? envRef.current.length : tempData.length,\n    };\n    tempData.push(obj);\n    if (isSearch) {\n      envRef.current[envRef.current.length] = obj;\n    }\n    return tempData;\n  };\n\n  const setEnvRefData = (lists, indexes, callback) => {\n    const tempData = lists.length === 0 ? addNewData(lists) : cloneDeep(lists);\n    setEnvData(() => tempData);\n    if (lists.length === 0) {\n      requestAnimationFrame(() => {\n        handleCurEleFocus(tempData[tempData.length - 1]?.indexKey);\n      });\n    }\n    if (isSearch) {\n      indexes?.map((i) => {\n        const obj = tempData.find((x) => x.indexKey === envRef.current[i]?.indexKey);\n        envRef.current[i] = obj;\n        return i;\n      });\n    } else envRef.current = tempData;\n\n    if (callback) callback();\n  };\n\n  const prepareData = () => {\n    // Prepare data for env key-value\n    hideDelete();\n    setErrors(false);\n    setIsSearch();\n    if (!envList) return;\n    let tempData = []; const tempEnv = {};\n    Object.keys(ENV).map((e) => {\n      tempEnv[e] = !!envList.environments?.includes(e);\n      return e;\n    });\n    if (envList.customJson?.length > 0) {\n      envList.customJson.map((x, index) => {\n        const tempObj = {\n          ...x,\n          indexKey: `e${index}`,\n          index,\n          isSelected: false,\n        };\n        let tempValue = {};\n        Object.keys(ENV).map((e) => {\n          // prepare env var (qa,production) data\n          if (x.value) {\n            tempValue[e] = x.value[e];\n          } else tempValue = {};\n          return e;\n        });\n\n        tempObj.value = tempValue;\n        tempObj.isExist = true;\n        tempData.push(tempObj);\n        return x;\n      });\n    }\n    if (Object.values(tempEnv)?.every((e) => !e)) {\n      tempEnv[ENV.DEVELOPMENT] = true;\n    }\n    setEnvironments(tempEnv);\n    tempData = [...tempData, { ...initObj, index: tempData.length, indexKey: `e${tempData.length}` }];\n    // tempData = addNewData(tempData);\n    setEnvRefData(tempData);\n    setIsAll(false);\n    requestAnimationFrame(() => {\n      handleCurEleFocus(tempData[tempData.length - 1]?.indexKey);\n    });\n  };\n\n  React.useEffect(() => {\n    prepareData();\n  }, [envList]);\n\n  const handleAutoFocus = (focusIndex) => {\n    // eslint-disable-next-line radix\n    const field = document.querySelector(focusIndex);\n    field?.focus();\n  };\n  const handleRowCheckBoxFocus = (focusIndex) => {\n    const field = document.getElementById(focusIndex);\n    field?.focus();\n  };\n\n  const handleEnvChange = (key, value, focusField) => {\n    // on change environments\n    const tempObj = { ...environments };\n    tempObj[key] = value;\n    setEnvironments(tempObj);\n    requestAnimationFrame(() => {\n      if (focusField) {\n        handleAutoFocus(focusField);\n      }\n    });\n  };\n\n  const handleAll = (key, val, focusField) => {\n    setIsAll(val);\n    const tempData = cloneDeep(envData);\n    tempData.map((x) => {\n      // eslint-disable-next-line no-param-reassign\n      x.isSelected = val;\n      return x;\n    });\n    setEnvRefData(tempData);\n    requestAnimationFrame(() => {\n      if (focusField) {\n        handleAutoFocus(focusField);\n      }\n    });\n  };\n\n  const handleChangeInputs = (obj, updateKey) => {\n    if (errors) setErrors(false);\n    let tempData = cloneDeep(envData); const indexes = [obj.index];\n    const index = tempData.findIndex((x) => x.indexKey === obj.indexKey);\n    if (index > -1) {\n      tempData[index] = obj;\n    }\n    if (updateKey === 'key' && last(tempData)?.key?.length > 0) {\n      // add blank new row\n      tempData = addNewData(tempData);\n      setEnvRefData(tempData, indexes);\n    } else setEnvRefData(tempData, indexes);\n  };\n\n  const handleSelect = React.useCallback((obj, value, focusField) => {\n    const tempData = cloneDeep(envData);\n    const i = tempData.findIndex((x) => x.indexKey === obj.indexKey);\n    tempData[i].isSelected = value;\n    const tempAll = tempData?.every((p) => p.isSelected);\n    setIsAll(tempAll);\n    setEnvData(tempData);\n    requestAnimationFrame(() => {\n      if (focusField) handleRowCheckBoxFocus(focusField); // manage auto focus\n    });\n  }, [envData]);\n\n  const handleDelete = (obj) => {\n    let tempData = cloneDeep(envData);\n    tempData = tempData.filter((x) => x.indexKey !== obj.indexKey);\n\n    setEnvRefData(tempData, [obj.index], () => {\n      if (obj.isExist) {\n        setDelete();\n        handleSave(true);\n      } else {\n        setIsSearch(false);\n        setIsAll(false);\n        // re-arrange indexKey, index, isSelected\n        const updatedEnvData = compact(envRef.current)?.map((env, index) => ({\n          ...env,\n          indexKey: `e${index}`,\n          index,\n          isSelected: false,\n        }));\n        envRef.current = updatedEnvData;\n        setEnvData(updatedEnvData);\n        addSuccessToast(EnvDeleteMessage);\n      }\n    });\n  };\n\n  const handleDeleteAll = () => {\n    let tempData = cloneDeep(envData);\n    const isExist = tempData?.some((x) => x.isExist);\n    tempData = tempData.filter((x) => !x.isSelected);\n    const selectedIndexes = cloneDeep(envData)?.filter((env) => env?.isSelected)?.map((selectedEnv) => selectedEnv?.index);\n\n    setEnvRefData(tempData, selectedIndexes, () => {\n      if (isExist) {\n        setDelete();\n        handleSave(true);\n      } else {\n        setIsSearch(false);\n        setIsAll(false);\n        // re-arrange indexKey, index, isSelected\n        const updatedEnvData = compact(envRef.current)?.map((env, index) => ({\n          ...env,\n          indexKey: `e${index}`,\n          index,\n          isSelected: false,\n        }));\n        envRef.current = updatedEnvData;\n        setEnvData(updatedEnvData);\n        addSuccessToast(EnvDeleteMessage);\n      }\n    });\n  };\n\n  const handleSearch = (searchVal) => {\n    setIsSearch(searchVal);\n    // when search selected reset\n    if (isAll) handleAll('', false);\n    const val = toLower(searchVal);\n    let tempData = cloneDeep(envRef.current);\n    if (val) {\n      tempData = tempData.filter((x) => toLower(x.key).includes(val.trim()));\n      tempData.push(envRef.current[envRef.current?.length - 1]);\n    }\n    setEnvData(tempData);\n  };\n\n  const EnvCheckbox = React.useCallback((options) => {\n    const { children, value, id } = options;\n    return (\n      <Checkbox\n        id={id}\n        className=\"text-center\"\n        checked={!!environments[value]}\n        onChange={(val) => handleEnvChange(value, val, value)}\n        onKeyDown={(e) => {\n          if (e.keyCode === 13 && e.target) {\n            handleEnvChange(value, !e.target.checked, `#${id}`);\n          }\n        }}\n      >\n        {children}\n      </Checkbox>\n    );\n  }, [environments]);\n\n  const AllCheckbox = React.useCallback((options) => {\n    const { children, value, id } = options;\n    return (\n      <Checkbox\n        id={id}\n        className=\"text-center\"\n        checked={!!isAll}\n        onChange={(val) => {\n          handleAll(value, val, value);\n        }}\n        onKeyDown={(e) => {\n          if (e.keyCode === 13) {\n            handleAll(value, !e.target.checked, `#${id}`);\n          }\n        }}\n      >\n        {children}\n      </Checkbox>\n    );\n  }, [isAll, envData]);\n\n  const isSelected = React.useMemo(() => envData?.some((x) => x?.isSelected), [envData]);\n  const totalColumns = 4;\n\n  return (\n    <>\n      <EnvironmentHead\n        title={HeadTitle}\n        desc={Headdesc}\n        headTooltip={headTooltip}\n        onSave={() => handleSave()}\n        upsertLoader={upsertLoader}\n        deleteLoader={deleteLoader}\n        onDelete={handleDeleteAll}\n        onSearch={handleSearch}\n        isSearch={isSearch}\n        isSelected={isSelected}\n        isLastObj={envData.length === 1}\n      />\n      <div className=\"overflow-auto envTable flex-grow\">\n        <div className=\"\">\n          {\n            (loader || upsertLoader) ? <Spinner />\n              : (\n                <table>\n                  <tr>\n                    <td className={enviromentVaribleCss.enviroTableHeadFirst}>\n                      <AllCheckbox value id=\"allCheckBox\">Select all</AllCheckbox>\n                    </td>\n                    <td className=\"sticky -left-3 top-0 z-1 bg-gray-black\">\n                      <table>\n                        <tr>\n                          {\n                            Object.keys(ENV).map((e) => (\n                              <td className={enviromentVaribleCss.enviroTableHead} key={e}>\n                                <div className=\"flex items-center\">\n                                  <EnvCheckbox value={ENV[e]} id={e} />\n                                  {e === 'QA' ? e : capitalizeStr(e)}\n                                </div>\n                              </td>\n                            ))\n                          }\n                        </tr>\n                      </table>\n                    </td>\n                  </tr>\n                  <>\n                    {/* //TO Render Key value rows  */}\n                    { envData?.length > 0\n                      && envData.map((e, i) => (\n                        <tr key={e.indexKey} id={e.indexKey} className=\"align-top envTableHead\">\n                          <KeyValue\n                            lengthOfData={envData.length}\n                            envObj={e}\n                            environments={environments}\n                            onChange={handleChangeInputs}\n                            onSelect={handleSelect}\n                            isLastObj={i === envData.length - 1}\n                            onDelete={() => handleDelete(e)}\n                            selectedRows={selectedRows}\n                            applicationCode={applicationCode}\n                            errors={errors}\n                            setErrors={setErrors}\n                            rowIndex={i * totalColumns}\n                          />\n                        </tr>\n                      ))}\n                  </>\n                </table>\n              )\n          }\n        </div>\n      </div>\n    </>\n  );\n});\nEnvironmentValue.displayName = 'EnvironmentValue';\nexport { EnvironmentValue };\n"
  },
  {
    "path": "packages/client/src/container/EnvironmentVariable/index.js",
    "content": "import React, { useRef, useState } from 'react';\nimport { shallowEqual, useSelector } from 'react-redux';\nimport { isEmpty } from 'lodash';\nimport Layout from '../Shared/Layout';\nimport { EnvironmentValue } from './environmentValue';\nimport { BoxLayout } from '../../components';\nimport { getEnvs, upsertEnvs } from '../../api/envVariable';\nimport { useToastNotifications, useBoolean } from '../hooks';\n\nexport const EnvDeleteMessage = 'The environment variable has been deleted successfully.';\n\nconst EnvironmentVariable = () => {\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const envRef = useRef(null);\n  const { applicationId, currentApplicationCode } = useSelector(({ projects }) => ({\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n  const [loader, setLoader, hideLoader] = useBoolean(false);\n  const [upsertLoader, setUpsertLoader, hideUpsertLoader] = useBoolean(false);\n  const [envList, setEnvList] = useState([]);\n\n  const fetch = () => {\n    setLoader();\n    getEnvs({ applicationId }).then((data) => {\n      setEnvList(data?.data);\n      hideLoader();\n    }).catch(() => {\n      hideLoader();\n      setEnvList();\n    });\n  };\n\n  React.useEffect(() => {\n    fetch();\n  }, []);\n\n  const handleSave = (request, isDelete) => {\n    if (!envRef?.current) return;\n    if (!isDelete && isEmpty(request?.customJson)) return;\n\n    setUpsertLoader();\n    upsertEnvs({ ...request, applicationId, definitionType: currentApplicationCode }).then((data) => {\n      addSuccessToast(isDelete ? EnvDeleteMessage : data.message);\n      hideUpsertLoader();\n      setEnvList(data?.data);\n    }).catch((e) => {\n      addErrorToast(e);\n      hideUpsertLoader();\n      setEnvList();\n    });\n  };\n\n  return (\n    <Layout isSidebar>\n      <BoxLayout variant=\"mainRight\" className=\"flex flex-col\">\n        <EnvironmentValue\n          ref={envRef}\n          envList={envList}\n          loader={loader}\n          onSave={handleSave}\n          upsertLoader={upsertLoader}\n          EnvDeleteMessage={EnvDeleteMessage}\n        />\n      </BoxLayout>\n    </Layout>\n  );\n};\nexport default EnvironmentVariable;\n"
  },
  {
    "path": "packages/client/src/container/Policy/AddPolicy/index.js",
    "content": "import React from 'react';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { Controller, useForm } from 'react-hook-form';\nimport {\n  Input, Popup,\n} from '../../../components';\nimport { POLICY_GENERATE_TYPE } from '../../../constant/policy';\nimport { createPolicy } from '../../../api/policy';\nimport { getError } from '../../../utils/validationMsgs';\nimport { useBoolean } from '../../../components/hooks';\nimport { addPolicy } from '../../../redux/reducers/policy';\nimport { nodeKeyRegex } from '../../../utils/regex';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../constant/common';\nimport { useToastNotifications } from '../../hooks';\n\nconst defaultValues = {\n  fileName: undefined,\n  modelId: undefined,\n  description: undefined,\n};\n\nexport const AddPolicy = React.memo(({ addModalRef }) => {\n  const dispatch = useDispatch();\n  const [policyModal, showPolicyModal, hidePolicyModal] = useBoolean(false);\n\n  const { applicationId } = useSelector((state) => ({ applicationId: state.projects.currentApplicationId, currentApplicationCode: state.projects.currentApplicationCode }));\n  const {\n    handleSubmit, errors, control,\n  } = useForm({ defaultValues, mode: 'all' });\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const [isSubmitting, setSubmitting, removeSetSubmitting] = useBoolean(false);\n\n  React.useImperativeHandle(addModalRef, () => ({ showPolicyModal }));\n  const onSubmit = (constantData) => {\n    setSubmitting();\n    const apiData = {\n      ...constantData,\n      applicationId,\n      type: POLICY_GENERATE_TYPE.MANUAL,\n      customJson: `module.exports = async (req, res, next) => {\n        // start writing your code from here do not remove above code\n    \n        return next();\n      }`,\n    };\n    createPolicy(apiData).then((response) => {\n      addSuccessToast(response.message);\n      dispatch(addPolicy(response.data));\n      hidePolicyModal();\n    }).catch((err) => {\n      addErrorToast(err);\n    }).finally(removeSetSubmitting);\n  };\n\n  return (\n    <Popup\n      isOpen={policyModal}\n      handleCancel={hidePolicyModal}\n      closeModal={hidePolicyModal}\n      handleSubmit={handleSubmit(onSubmit)}\n      title=\"Create middleware\"\n      isCancel\n      cancel=\"Cancel\"\n      isSubmit\n      submit=\"Create middleware\"\n      bodyClass=\"xxl:max-h-110 overflow-auto xl:max-h-96\"\n      submitLoading={isSubmitting}\n      isAutoFocusOnSave\n    >\n      <div>\n        <div className=\"grid grid-cols-1 gap-5\">\n          <Controller\n            control={control}\n            name=\"fileName\"\n            rules={{ required: true }}\n            render={(controlProps) => (\n              <Input\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...controlProps}\n                autoFocus\n                maxLength={MAX_INPUT_FIELD_LIMIT.title}\n                placeholder=\"Enter middleware name\"\n                label=\"Middleware name*\"\n                desc=\"Give a name to your middleware. The file name in the generated code will be the same as the middleware name.\"\n                error={getError(errors, 'fileName', (errors?.fileName?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.title : 'Middleware name')}\n                customRegex={nodeKeyRegex}\n              />\n            )}\n          />\n\n        </div>\n      </div>\n    </Popup>\n  );\n});\nAddPolicy.displayName = 'AddPolicy';\n"
  },
  {
    "path": "packages/client/src/container/Policy/DeletePolicy.js",
    "content": "import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { Button, ConfirmationAlert } from '../../components';\nimport { deletePolicy } from '../../api/applicationPolicy';\nimport { deleteCurrentPolicy } from '../../redux/reducers/policy';\nimport { useBoolean, useToastNotifications } from '../hooks';\n\nfunction DeletePolicy({ selectedPolicy, isDisable }) {\n  const dispatch = useDispatch();\n\n  const [isDelete, setDelete, removeSetDelete] = useBoolean(false);\n  const [isLoading, setLoading, removeLoading] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const handelDelete = React.useCallback(() => {\n    setLoading();\n    deletePolicy({ id: selectedPolicy, isHardDelete: true }).then((response) => {\n      addSuccessToast(response.message);\n      dispatch(deleteCurrentPolicy());\n    }).catch((err) => {\n      addErrorToast(err);\n    }).finally(() => {\n      removeLoading();\n      removeSetDelete();\n    });\n  }, [selectedPolicy]);\n\n  return (\n    <>\n      {isDelete && (\n        <ConfirmationAlert\n          description=\"Middleware file will be deleted permanently and cannot be restored in the future.Are you sure do you want to delete this middleware file?\"\n          handleSubmit={handelDelete}\n          isOpen={isDelete}\n          handleClose={removeSetDelete}\n          isLoading={isLoading}\n        // description=\"Do you want to delete this constant ?\"\n        />\n      )}\n\n      {!isDisable && (\n\n        <Button\n          variant=\"outline\"\n          className=\"ml-2\"\n          size=\"medium\"\n          shape=\"rounded\"\n          onClick={setDelete}\n        >\n          Delete\n        </Button>\n\n      )}\n\n    </>\n  );\n}\n\nexport default DeletePolicy;\n"
  },
  {
    "path": "packages/client/src/container/Policy/LeftPolicyList.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { SidebarList } from '../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../components';\nimport { setCurrentPolicy } from '../../redux/reducers/policy';\n\nexport const LeftPolicyList = React.memo(({\n  addPolicy,\n}) => {\n  const dispatch = useDispatch();\n  const policyList = useSelector((state) => state.policy.policyList);\n  const currentPolicy = useSelector((state) => state.policy.currentId);\n\n  return (\n    <SidebarList isAddButton title=\"Middleware\" addClick={addPolicy} tooltip=\"Add middleware\">\n      <Menu iconShape=\"square\" className=\"p-2\">\n        <SidebarMenuList\n          mainMenuList={policyList}\n          titleKey=\"fileName\"\n          onClick={(data) => dispatch(setCurrentPolicy(data))}\n          initialSelectedId={currentPolicy || policyList?.[0]?._id}\n        />\n      </Menu>\n    </SidebarList>\n  );\n});\nLeftPolicyList.displayName = 'LeftPolicyList';\n"
  },
  {
    "path": "packages/client/src/container/Policy/PolicyView/Policy.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = ({ rows }) => (\n  <>\n    {Array(rows || 1)\n      .fill('')\n      .map((d) => (\n        <ContentLoader\n          key={d}\n          speed={2}\n          className=\"mt-5\"\n          width=\"100%\"\n          height=\"300px\"\n          // viewBox=\"0 0 100% 300px\"\n          backgroundColor=\"var(--color-gray-200)\"\n          foregroundColor=\"var(--color-gray-100)\"\n        >\n          <rect x=\"10\" y=\"8\" rx=\"3\" ry=\"3\" width=\"100%\" height=\"300px\" />\n          {/* <rect x=\"10\" y=\"26\" rx=\"3\" ry=\"3\" width=\"50%\" height=\"6\" />\n\n          <rect x=\"85%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          <rect x=\"90%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" />\n          <rect x=\"95%\" y=\"8\" rx=\"3\" ry=\"3\" width=\"50\" height=\"6\" /> */}\n          {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n        </ContentLoader>\n      ))}\n  </>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/Policy/PolicyView/PolicyHead.js",
    "content": "import React from 'react';\nimport { isBoolean, isEmpty, replace } from 'lodash';\nimport { useSelector, useDispatch } from 'react-redux';\nimport { updatePolicy } from '../../../api/applicationPolicy';\nimport { updateCurrentPolicy } from '../../../redux/reducers/policy';\nimport { InlineHeader } from '../../../components/InlineHeader';\nimport { useBoolean, useToastNotifications } from '../../hooks';\n\nexport const PolicyHead = React.memo(({\n  updateRef, isDisable, setLoading, hideLoading,\n}) => {\n  const [edit, setShowEdit, setHideEdit] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const selectedPolicy = useSelector((state) => state.policy.currentId);\n  const policyList = useSelector((state) => state.policy.policyList);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const dispatch = useDispatch();\n\n  const currentPolicyData = policyList.find((d) => d._id === selectedPolicy);\n\n  const [state, _setState] = React.useState(() => ({\n    fileName: '',\n    description: '',\n    isActive: false,\n  }));\n\n  const setState = React.useCallback(\n    (data) => {\n      _setState((prevState) => ({ ...prevState, ...data }));\n    },\n    [_setState],\n  );\n\n  let fileName = '';\n  if (/\\s/.test(currentPolicyData?.fileName)) {\n    fileName = replace(currentPolicyData.fileName, / /g, '_');\n  } else {\n    fileName = currentPolicyData?.fileName;\n  }\n\n  React.useEffect(() => {\n    setState({\n      fileName,\n      description: currentPolicyData?.description,\n      isActive: currentPolicyData?.isActive,\n    });\n    setHideEdit();\n  }, [selectedPolicy]);\n\n  const handelPolicyProperty = (key, value) => {\n    const data = {\n      [key]: isBoolean(value) ? value : value ?? currentPolicyData?.[key],\n    };\n    setState({ ...data });\n    const request = {\n      ...state,\n      customJson: currentPolicyData?.customJson || {},\n      // TODO:Remove if customJson come in List\n      ...data,\n      applicationId,\n      type: currentPolicyData?.type,\n    };\n\n    if (isEmpty(request?.customJson)) {\n      addErrorToast('Enter Middleware Code');\n      return;\n    }\n    if (value || isBoolean(value)) {\n      setLoading();\n      updatePolicy(selectedPolicy, request)\n        .then((response) => {\n          addSuccessToast(response.message);\n          dispatch(updateCurrentPolicy(response.data));\n        })\n        .catch((error) => {\n          addErrorToast(error);\n          setState({\n            fileName: currentPolicyData?.fileName,\n            description: currentPolicyData?.description,\n            isActive: currentPolicyData?.isActive,\n          });\n        }).finally(hideLoading);\n    }\n  };\n\n  React.useImperativeHandle(updateRef, () => ({ handelPolicyProperty, setHideEdit }));\n\n  return (\n    <InlineHeader\n      defaultValue={state}\n      currentId={selectedPolicy}\n      onBlurEvent={handelPolicyProperty}\n      isDisable={isDisable}\n      isActiveButton\n      edit={edit}\n      setShowEdit={setShowEdit}\n      setHideEdit={setHideEdit}\n      titlePlaceHolder=\"Middleware\"\n    />\n  );\n});\nPolicyHead.displayName = 'PolicyHead';\n"
  },
  {
    "path": "packages/client/src/container/Policy/PolicyView/index.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport Editor from '@monaco-editor/react';\nimport { isEmpty } from 'lodash';\nimport { Icons } from '@dhiwise/icons';\nimport { PolicyHead } from './PolicyHead';\nimport {\n  POLICY_GENERATE_TYPE,\n} from '../../../constant/policy';\nimport DeletePolicy from '../DeletePolicy';\nimport { Button, Error } from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\n\nexport const PolicyView = React.memo(() => {\n  const selectedPolicy = useSelector((state) => state.policy.currentId);\n  const policyList = useSelector((state) => state.policy.policyList);\n  const currentPolicyData = policyList.find((d) => d._id === selectedPolicy);\n  const isDisable = currentPolicyData?.type === POLICY_GENERATE_TYPE.AUTO;\n  const [code, setCode] = React.useState(JSON.stringify({}));\n  const [isError, setShowError, setHideError] = useBoolean(false);\n  const [codeEditorError, setCodeEditorError] = React.useState([]);\n  const updateRef = React.useRef();\n  const [loading, setLoading, hideLoading] = useBoolean(false);\n\n  React.useEffect(() => {\n    setCode(currentPolicyData?.customJson);\n  }, [selectedPolicy, currentPolicyData]);\n\n  const onSubmit = () => {\n    updateRef.current?.handelPolicyProperty('customJson', code);\n    updateRef.current?.setHideEdit();\n  };\n  const handleShowError = () => {\n    setShowError();\n  };\n  return (\n    <div className=\"flex flex-col w-full\">\n      <div className=\"px-5 py-3 flex justify-between headTop items-center\">\n        <PolicyHead updateRef={updateRef} isDisable={isDisable} setLoading={setLoading} hideLoading={hideLoading} />\n        <div className=\"flex items-center\">\n          {!isDisable && (\n            <Button\n              onClick={handleShowError}\n              className=\"ml-2\"\n              variant=\"secondary\"\n              shape=\"rounded\"\n              size=\"medium\"\n              isIcon\n              label={`${!isEmpty(codeEditorError) ? 1 : 0} error`}\n              icon={!isEmpty(codeEditorError) ? <Icons.Alert color=\"#E24C4B\" /> : <Icons.Alert />}\n            />\n          )}\n          <DeletePolicy selectedPolicy={selectedPolicy} isDisable={isDisable} />\n          {!isDisable && (\n            <Button\n              size=\"medium\"\n              variant=\"primary\"\n              shape=\"rounded\"\n              className=\"ml-2\"\n              onClick={() => { if (!isError) onSubmit(); }}\n              loading={loading}\n            >\n              Save\n            </Button>\n          )}\n        </div>\n      </div>\n      <div\n        className={`flex-grow ${isDisable ? 'readonlyEditor' : ''}`}\n        onKeyDown={(e) => {\n          // stop copy past\n          if (isDisable) {\n            e.preventDefault();\n          }\n        }}\n      >\n        <Editor\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          height=\"100%\"\n          defaultValue={code}\n          value={code}\n          theme=\"vs-dark\"\n          className=\"rounded\"\n          options={{ readOnly: isDisable, contextmenu: !isDisable }}\n          // readOnly={isDisable}\n          onChange={(tempCode) => {\n            setCode(tempCode);\n          }}\n          onValidate={(error) => {\n            setCodeEditorError(error);\n          }}\n        />\n\n        {isError ? (\n          <Error\n            isOpen={isError}\n            error={\n              !isEmpty(codeEditorError) && {\n                message: `On line no ${codeEditorError[0]?.endLineNumber} ${codeEditorError[0]?.message}`,\n              }\n            }\n            handleCancel={setHideError}\n          />\n        ) : null}\n      </div>\n    </div>\n  );\n});\nPolicyView.displayName = 'PolicyView';\n"
  },
  {
    "path": "packages/client/src/container/Policy/index.js",
    "content": "import React from 'react';\nimport { isEmpty } from 'lodash';\nimport { useSelector, shallowEqual, useDispatch } from 'react-redux';\nimport { PolicyView } from './PolicyView';\nimport Layout from '../Shared/Layout';\nimport { BoxLayout, NoData, Loader } from '../../components';\nimport { AddPolicy } from './AddPolicy';\nimport { LeftPolicyList } from './LeftPolicyList';\nimport { listPolicy } from '../../redux/thunks/policy';\nimport { listModels } from '../../redux/thunks/models';\n\nexport default function Policy() {\n  const addModalRef = React.useRef();\n  const {\n    policyList, loading, applicationId,\n  } = useSelector(({ policy, projects }) => ({\n    policyList: policy.policyList,\n    loading: policy.listPolicyFetching,\n    applicationId: projects.currentApplicationId,\n    currentApplicationCode: projects.currentApplicationCode,\n  }), shallowEqual);\n\n  const dispatch = useDispatch();\n\n  const fetchAllPolicy = () => {\n    dispatch(listPolicy({\n      applicationId,\n      isActiveDeactivateDisplay: true,\n    }));\n  };\n\n  React.useEffect(() => {\n    fetchAllPolicy();\n    dispatch(listModels({ applicationId }));\n  }, []);\n\n  return (\n    <Layout isSidebar>\n\n      <div className=\"w-sidebarRight\">\n        {/* {loading && <LazyLoader />} */}\n        {loading && <Loader className=\"min-h-body\" />}\n        {!loading && (\n          <>\n            {!isEmpty(policyList) ? (\n              <div className=\"flex h-full\">\n                <LeftPolicyList\n                  addPolicy={() => {\n                    addModalRef.current?.showPolicyModal();\n                  }}\n                />\n                <BoxLayout variant=\"subRight\" className=\"overflow-hidden\">\n                  <PolicyView />\n                </BoxLayout>\n              </div>\n            )\n              : (\n                <NoData\n                  onClick={() => {\n                    addModalRef.current?.showPolicyModal();\n                  }}\n                  btnText=\"Add middleware\"\n                  title=\"No middleware found\"\n                />\n              )}\n            <AddPolicy\n              addModalRef={addModalRef}\n            />\n          </>\n        )}\n      </div>\n\n    </Layout>\n\n  );\n}\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/AddRole/index.js",
    "content": "import React from 'react';\nimport { Controller, useForm } from 'react-hook-form';\nimport { useSelector } from 'react-redux';\nimport { upsertProjectRoleAccess } from '../../../api/projectRoleAccess';\nimport { Popup, Input } from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\nimport { MAX_INPUT_FIELD_LIMIT } from '../../../constant/common';\nimport { useToastNotifications } from '../../hooks';\nimport { nodeKeyRegex } from '../../../utils/regex';\nimport { getError } from '../../../utils/validationMsgs';\nimport { ROLE_ACCESS_ACTION_TYPES, useRoleAccess } from '../RoleAccessProvider';\n\nconst defaultValues = {\n  name: undefined,\n  description: undefined,\n};\n\nexport const AddRole = React.forwardRef(({ addModalRef }) => {\n  const [addRoleModal, showAddRoleModal, hideAddRoleModal] = useBoolean(false);\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const {\n    isLoading, setLoading, removeLoading, dispatch,\n  } = useRoleAccess();\n\n  const {\n    handleSubmit, errors, control,\n  } = useForm({ defaultValues, mode: 'onChange' });\n\n  React.useImperativeHandle(addModalRef, () => ({ showAddRoleModal }));\n\n  const onSubmit = (roleData) => {\n    setLoading();\n    const apiData = {\n      ...roleData,\n      applicationId,\n      customJson: [],\n    };\n    upsertProjectRoleAccess(apiData).then((roleRes) => {\n      dispatch({ type: ROLE_ACCESS_ACTION_TYPES.ADD_ROLE, payload: roleRes.data });\n      addSuccessToast(roleRes?.message);\n      hideAddRoleModal();\n    }).catch((err) => {\n      addErrorToast(err);\n    }).finally(removeLoading);\n  };\n\n  return (\n    <Popup\n      isOpen={addRoleModal}\n      handleCancel={hideAddRoleModal}\n      handleSubmit={handleSubmit(onSubmit)}\n      closeModal={hideAddRoleModal}\n      title=\"Create role\"\n      isCancel\n      cancel=\"Cancel\"\n      isSubmit\n      submit=\"Create role\"\n      submitLoading={isLoading}\n      isAutoFocusOnSave\n    >\n      <div>\n        <div className=\"grid grid-cols-1 gap-5\">\n          <Controller\n            control={control}\n            name=\"name\"\n            rules={{ required: true }}\n            render={(controlProps) => (\n              <Input\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...controlProps}\n                autoFocus\n                label=\"Add new role*\"\n                desc=\"Add a new role for your application.\"\n                placeholder=\"Enter role\"\n                maxLength={MAX_INPUT_FIELD_LIMIT.title}\n                error={getError(errors, 'name', (errors?.name?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.title : 'Role')}\n                customRegex={nodeKeyRegex}\n              />\n            )}\n          />\n          {/* <Controller\n            control={control}\n            name=\"description\"\n            rules={{ required: true }}\n            render={(controlProps) => (\n              <TextArea\n                // eslint-disable-next-line react/jsx-props-no-spreading\n                {...controlProps}\n                maxLength={MAX_INPUT_FIELD_LIMIT.description}\n                label=\"Description*\"\n                desc=\"You're a star developer. You know comments go a long way! Write brief about the role.\"\n                placeholder=\"Enter description\"\n                error={getError(errors, 'description', (errors?.description?.type === 'maxLength') ? MAX_INPUT_FIELD_LIMIT.description : 'Description')}\n              />\n            )}\n          /> */}\n        </div>\n      </div>\n    </Popup>\n  );\n});\nAddRole.displayName = 'AddRole';\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleAccessHead/index.js",
    "content": "import React from 'react';\nimport { isBoolean } from 'lodash';\nimport { useSelector } from 'react-redux';\nimport { upsertProjectRoleAccess } from '../../../api/projectRoleAccess';\nimport { InlineHeader } from '../../../components/InlineHeader';\nimport { useBoolean } from '../../../components/hooks';\nimport { useToastNotifications } from '../../hooks';\nimport { ROLE_ACCESS_ACTION_TYPES, useRoleAccess } from '../RoleAccessProvider';\n\nexport const RoleAccessHead = React.memo(({\n  updateRef, setLoading, hideLoading,\n}) => {\n  const [edit, setShowEdit, setHideEdit] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const {\n    selectedRoleData, selectedRole, dispatch,\n  } = useRoleAccess();\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const [state, _setState] = React.useState(() => ({\n    name: '',\n    description: '',\n  }));\n\n  const setState = React.useCallback(\n    (data) => {\n      _setState((prevState) => ({ ...prevState, ...data }));\n    },\n    [_setState],\n  );\n\n  React.useEffect(() => {\n    setState({\n      name: selectedRoleData?.name,\n      description: selectedRoleData?.description,\n    });\n    setHideEdit();\n  }, [selectedRole]);\n\n  const handelRoleAccess = (key, value) => {\n    const data = {\n      [key]: isBoolean(value) ? value : value || selectedRoleData?.[key],\n    };\n    setState({ ...data });\n    const apiData = {\n      ...state,\n      customJson: selectedRoleData?.customJson || [],\n      id: selectedRole,\n      ...data,\n      applicationId,\n    };\n    if (value || isBoolean(value)) {\n      setLoading();\n      upsertProjectRoleAccess(apiData)\n        .then((response) => {\n          addSuccessToast(response?.message);\n          dispatch({ type: ROLE_ACCESS_ACTION_TYPES.EDIT_SELECTED_ROLE_DATA, payload: response?.data });\n        })\n        .catch((error) => {\n          addErrorToast(error);\n          setState({\n            name: selectedRoleData?.name,\n            description: selectedRoleData?.description,\n          });\n        }).finally(hideLoading);\n    }\n  };\n\n  React.useImperativeHandle(updateRef, () => ({ handelRoleAccess, setHideEdit }));\n\n  return (\n    <InlineHeader\n      defaultValue={state}\n      currentId={selectedRole}\n      onBlurEvent={handelRoleAccess}\n      edit={edit}\n      setShowEdit={setShowEdit}\n      setHideEdit={setHideEdit}\n      titlePlaceHolder=\"Role\"\n    />\n  );\n});\nRoleAccessHead.displayName = 'RoleAccessHead';\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleAccessList/DeleteRole.js",
    "content": "import React from 'react';\nimport { deleteProjectRoleAccess } from '../../../api/projectRoleAccess';\nimport { Button, ConfirmationAlert } from '../../../components';\nimport { useBoolean, useToastNotifications } from '../../hooks';\nimport { ROLE_ACCESS_ACTION_TYPES, useRoleAccess } from '../RoleAccessProvider';\n\nfunction DeleteRole() {\n  const [isDelete, setDelete, removeSetDelete] = useBoolean(false);\n  const [isLoading, setLoading, removeLoading] = useBoolean(false);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n\n  const { selectedRole, dispatch } = useRoleAccess();\n\n  const handelDelete = React.useCallback(() => {\n    setLoading();\n    deleteProjectRoleAccess({ id: selectedRole }).then((response) => {\n      addSuccessToast(response.message);\n      dispatch({ type: ROLE_ACCESS_ACTION_TYPES.DELETE_ROLE });\n    }).catch((err) => {\n      addErrorToast(err);\n    }).finally(() => {\n      removeLoading();\n      removeSetDelete();\n    });\n  }, [selectedRole]);\n\n  return (\n    <>\n      {isDelete && (\n        <ConfirmationAlert\n          description=\"Created role will be deleted permanently and cannot be restored in the future.\"\n          handleSubmit={handelDelete}\n          isOpen={isDelete}\n          handleClose={removeSetDelete}\n          isLoading={isLoading}\n        />\n      )}\n      <Button\n        variant=\"outline\"\n        className=\"ml-2\"\n        size=\"medium\"\n        shape=\"rounded\"\n        onClick={setDelete}\n      >\n        Delete\n      </Button>\n    </>\n  );\n}\n\nexport default DeleteRole;\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleAccessList/index.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { cloneDeep, find, isEmpty } from 'lodash';\nimport {\n  Checkbox, ListTitle, NoData, Button,\n} from '../../../components';\nimport { RoleAccessHead } from '../RoleAccessHead';\nimport DeleteRole from './DeleteRole';\nimport { roleAccessListCss } from './roleAccessListCss';\nimport { useBoolean } from '../../../components/hooks';\nimport { CRUD } from '../../../constant/permission';\nimport { useRoleAccess } from '../RoleAccessProvider';\n\nexport const RoleListItem = ({ modelName, customJson, handleChange }) => {\n  const ActionCheckBox = (propsVal) => {\n    const { children, operationType, modelId } = propsVal;\n    return (\n      <Checkbox\n        checked={(operationType !== CRUD.ALL_MODEL) ? !!customJson?.actions?.[operationType] : !!Object.keys(customJson?.actions)?.every((val) => customJson?.actions?.[val])}\n        onChange={(val) => {\n          handleChange(val, operationType, modelId);\n        }}\n      >\n        {children}\n      </Checkbox>\n    );\n  };\n\n  return (\n    <div className={roleAccessListCss.roleListWrap}>\n      <div className=\"\">\n        <ListTitle title={modelName} />\n      </div>\n      <div className=\"flex justify-between w-96\">\n        <div className=\"mr-2\">\n          <ActionCheckBox operationType={CRUD.ALL_MODEL} modelId={customJson?.modelId}>\n            All\n          </ActionCheckBox>\n        </div>\n        <div className=\"mr-2\">\n          <ActionCheckBox operationType={CRUD.C} modelId={customJson?.modelId}>\n            Create\n          </ActionCheckBox>\n        </div>\n        <div className=\"mr-2 text-center\">\n          <ActionCheckBox operationType={CRUD.R} modelId={customJson?.modelId}>\n            View\n          </ActionCheckBox>\n        </div>\n        <div className=\"mr-2\">\n          <ActionCheckBox operationType={CRUD.U} modelId={customJson?.modelId}>\n            Update\n          </ActionCheckBox>\n        </div>\n        <div className=\"mr-2\">\n          <ActionCheckBox operationType={CRUD.D} modelId={customJson?.modelId}>\n            Delete\n          </ActionCheckBox>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport const RoleAccessList = React.memo(() => {\n  const updateRef = React.useRef();\n  const [customJson, setCustomJson] = React.useState([]);\n  const [loading, setLoading, hideLoading] = useBoolean(false);\n\n  const modelList = useSelector((state) => state.models.modelList);\n\n  const { selectedRole, selectedRoleData } = useRoleAccess();\n\n  const prepareRoleAccessData = () => {\n    const roleAccessCustomJson = [];\n    modelList?.forEach((model) => {\n      if (find(selectedRoleData?.customJson, ['modelId', model?._id])) {\n        roleAccessCustomJson.push(find(selectedRoleData?.customJson, ['modelId', model?._id]));\n      } else {\n        const customJsonObject = {};\n        customJsonObject.modelId = model?._id;\n        customJsonObject.actions = {\n          C: false,\n          R: false,\n          U: false,\n          D: false,\n        };\n        roleAccessCustomJson.push(customJsonObject);\n      }\n    });\n    setCustomJson(roleAccessCustomJson);\n  };\n\n  React.useEffect(() => {\n    prepareRoleAccessData();\n  }, [selectedRole]);\n\n  const handleChange = (val, operationType, modelId) => {\n    const newCustomJson = cloneDeep(customJson);\n    const index = customJson?.findIndex((model) => model?.modelId === modelId);\n\n    if (operationType === CRUD.ALL_MODEL) {\n      Object.keys(newCustomJson[index].actions)?.forEach((operation) => {\n        newCustomJson[index].actions[operation] = val;\n      });\n    }\n    if (operationType === CRUD.ALL) {\n      newCustomJson?.forEach((modelJson) => {\n        const modelIndex = customJson?.findIndex((model) => model?.modelId === modelJson?.modelId);\n        Object.keys(modelJson?.actions)?.forEach((operation) => {\n          newCustomJson[modelIndex].actions[operation] = val;\n        });\n      });\n    }\n    if (operationType !== CRUD.ALL_MODEL && operationType !== CRUD.ALL) {\n      newCustomJson[index].actions[operationType] = val;\n    }\n    setCustomJson(newCustomJson);\n  };\n\n  const AllModelCheckBox = (propsVal) => {\n    const { children } = propsVal;\n    return (\n      <Checkbox\n        checked={!!customJson?.every((modelJson) => Object.keys(modelJson?.actions)?.every((val) => modelJson?.actions[val]))}\n        onChange={(val) => handleChange(val, CRUD.ALL)}\n      >\n        {children}\n      </Checkbox>\n    );\n  };\n\n  const onSubmit = () => {\n    updateRef.current?.handelRoleAccess('customJson', customJson);\n    updateRef.current?.setHideEdit();\n  };\n\n  return (\n    <>\n      <div className=\"px-5 py-3 flex justify-between items-center headTop\">\n        <RoleAccessHead updateRef={updateRef} setLoading={setLoading} hideLoading={hideLoading} />\n        <div className=\"w-4/12 xxl:w-6/12 flex justify-end\">\n          {/* <Button\n            variant=\"outline\"\n            shape=\"rounded\"\n            size=\"medium\"\n            className=\"ml-2\"\n            onClick={() => {\n              prepareRoleAccessData();\n            }}\n          >\n            Cancel\n          </Button> */}\n          <DeleteRole />\n          <Button\n            variant=\"primary\"\n            shape=\"rounded\"\n            size=\"medium\"\n            onClick={onSubmit}\n            className=\"ml-2\"\n            loading={loading}\n          >\n            Update\n          </Button>\n        </div>\n      </div>\n      {(!isEmpty(modelList) && !isEmpty(customJson))\n        ? (\n          <div\n            className=\"overflow-auto flex-grow\"\n          >\n            <div className={roleAccessListCss.roleListHead}>\n              <div className={roleAccessListCss.roleListHeadTitle}>Model list</div>\n              <div className={roleAccessListCss.roleListHeadBox}>\n                <span>Action</span>\n                <span>\n                  <AllModelCheckBox>\n                    All\n                  </AllModelCheckBox>\n                </span>\n              </div>\n            </div>\n            {\n              modelList.map((model) => (\n                <RoleListItem\n                  key={model?._id}\n                  modelName={model?.name}\n                  customJson={find(customJson, ['modelId', model?._id])}\n                  handleChange={handleChange}\n                />\n              ))\n            }\n          </div>\n        )\n        : (\n          <NoData\n            title=\"No model found\"\n          />\n        )}\n    </>\n  );\n});\nRoleAccessList.displayName = 'RoleAccessList';\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleAccessList/roleAccessListCss.js",
    "content": "export const roleAccessListCss = {\n  roleListHead: 'bg-gray-200 px-5 py-1.5 flex justify-between items-center w-full sticky top-0 z-1',\n  roleListHeadBox: 'flex justify-between text-primary-text text-sm w-96',\n  roleListHeadTitle: 'text-primary-text text-sm',\n  roleListWrap: 'bg-gray-black p-3 cursor-pointer flex justify-between border-t border-gray-200',\n};\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleAccessProvider.js",
    "content": "import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { getProjectRoleAccess } from '../../api/projectRoleAccess';\nimport { useBoolean } from '../../components/hooks';\nimport { useToastNotifications } from '../hooks';\n\nexport const RoleAccessContext = React.createContext();\n\nexport const ROLE_ACCESS_ACTION_TYPES = {\n  FETCH_LIST: 'fetchRoleAccessList',\n  ADD_ROLE: 'addRoleAccess',\n  DELETE_ROLE: 'deleteRoleAccess',\n  SELECT_ROLE: 'selectRole',\n  SELECTED_ROLE_DATA: 'selectedRoleData',\n  EDIT_SELECTED_ROLE_DATA: 'editSelectedRoleData',\n};\n\nfunction roleAccessReducer(state, { type, payload = {} }) {\n  switch (type) {\n    case ROLE_ACCESS_ACTION_TYPES.FETCH_LIST: {\n      return {\n        ...state, roleAccessList: payload || [], selectedRole: payload?.[0]?._id || null, selectedRoleData: payload?.find((role) => role?._id === payload?.[0]?._id) || {},\n      };\n    }\n    case ROLE_ACCESS_ACTION_TYPES.ADD_ROLE: {\n      const { roleAccessList } = state;\n      roleAccessList.unshift({ ...payload });\n      return {\n        ...state, roleAccessList, selectedRole: payload?._id, selectedRoleData: payload,\n      };\n    }\n    case ROLE_ACCESS_ACTION_TYPES.DELETE_ROLE: {\n      const roleAccessList = state.roleAccessList?.filter((role) => role?._id !== state.selectedRole) || [];\n      const selectedRole = roleAccessList?.[0]?._id || null;\n      const selectedRoleData = roleAccessList?.find((role) => role?._id === selectedRole) || {};\n      return {\n        ...state, roleAccessList, selectedRole, selectedRoleData,\n      };\n    }\n    case ROLE_ACCESS_ACTION_TYPES.SELECT_ROLE: {\n      return { ...state, selectedRole: payload };\n    }\n    case ROLE_ACCESS_ACTION_TYPES.SELECTED_ROLE_DATA: {\n      return { ...state, selectedRoleData: state.roleAccessList?.find((role) => role?._id === payload) || {}, selectedRole: payload || null };\n    }\n    case ROLE_ACCESS_ACTION_TYPES.EDIT_SELECTED_ROLE_DATA: {\n      const updatedRoleAccessList = state.roleAccessList?.map((role) => {\n        if (role?._id === state.selectedRole) {\n          return payload;\n        }\n        return role;\n      });\n      return { ...state, roleAccessList: updatedRoleAccessList, selectedRoleData: payload };\n    }\n    default: {\n      throw new Error(`Unhandled action type: ${type}`);\n    }\n  }\n}\n\nconst RoleAccessProvider = ({ children }) => {\n  const [stateData, dispatch] = React.useReducer(roleAccessReducer, { roleAccessList: [], selectedRoleData: {}, selectedRole: null });\n\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const { addErrorToast } = useToastNotifications();\n  const [isLoading, setLoading, removeLoading] = useBoolean(false);\n\n  React.useEffect(() => {\n    setLoading();\n    getProjectRoleAccess({ applicationId }).then((roleRes) => {\n      if (roleRes?.data?.list) {\n        dispatch({ type: ROLE_ACCESS_ACTION_TYPES.FETCH_LIST, payload: roleRes?.data?.list || [] });\n      }\n    }).catch(addErrorToast).finally(removeLoading);\n  }, [applicationId]);\n\n  const value = {\n    isLoading,\n    setLoading,\n    removeLoading,\n    roleAccessList: stateData.roleAccessList,\n    selectedRoleData: stateData.selectedRoleData,\n    selectedRole: stateData.selectedRole,\n    dispatch,\n  };\n  return <RoleAccessContext.Provider value={value}>{children}</RoleAccessContext.Provider>;\n};\n\nfunction useRoleAccess() {\n  const context = React.useContext(RoleAccessContext);\n  if (context === undefined) {\n    throw new Error('useRoleAccess must be used within a RoleAccessProvider');\n  }\n  return context;\n}\n\nexport { RoleAccessProvider, useRoleAccess };\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/RoleList/index.js",
    "content": "import React from 'react';\nimport { Menu } from 'react-pro-sidebar';\nimport { SidebarList } from '../../Shared/Layout/Sidebar/SubSidebar';\nimport { SidebarMenuList } from '../../../components';\nimport { ROLE_ACCESS_ACTION_TYPES, useRoleAccess } from '../RoleAccessProvider';\n\nexport const RoleList = React.memo(({ handleShow }) => {\n  const { roleAccessList, selectedRole, dispatch } = useRoleAccess();\n\n  return (\n    <SidebarList isAddButton title=\"Role access\" addClick={handleShow} tooltip=\"Add Role\">\n      <Menu iconShape=\"square\" className=\"p-2\">\n        <SidebarMenuList\n          mainMenuList={roleAccessList}\n          titleKey=\"name\"\n          onClick={(data) => dispatch({ type: ROLE_ACCESS_ACTION_TYPES.SELECTED_ROLE_DATA, payload: data })}\n          initialSelectedId={selectedRole || roleAccessList?.[0]?._id}\n        />\n      </Menu>\n    </SidebarList>\n  );\n});\nRoleList.displayName = 'RoleList';\n"
  },
  {
    "path": "packages/client/src/container/RoleAccess/index.js",
    "content": "import React from 'react';\nimport { isEmpty } from 'lodash';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { unwrapResult } from '@reduxjs/toolkit';\nimport Layout from '../Shared/Layout';\nimport { RoleAccessList } from './RoleAccessList';\nimport { RoleList } from './RoleList';\nimport { BoxLayout, Loader, NoData } from '../../components';\nimport { AddRole } from './AddRole';\nimport { RoleAccessProvider, useRoleAccess } from './RoleAccessProvider';\nimport { listModels } from '../../redux/thunks/models';\nimport { useBoolean } from '../../components/hooks';\nimport { useToastNotifications } from '../hooks';\n\nconst RoleAccess = () => {\n  const dispatch = useDispatch();\n  const addModalRef = React.useRef();\n  const { addErrorToast } = useToastNotifications();\n  const [modelLoader, setModelLoader, hideModelLoader] = useBoolean(false);\n\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n\n  const { isLoading, roleAccessList } = useRoleAccess();\n\n  React.useEffect(() => {\n    setModelLoader();\n    dispatch(listModels({ applicationId }))\n      .then(unwrapResult)\n      .catch(addErrorToast)\n      .finally(hideModelLoader);\n  }, [applicationId]);\n\n  return (\n    <Layout isSidebar>\n      {(isLoading || modelLoader)\n      && (\n        <div className=\"w-full\">\n          <Loader />\n        </div>\n      )}\n      {(!isLoading && !modelLoader)\n        && (\n          !isEmpty(roleAccessList)\n            ? (\n              <BoxLayout variant=\"mainRight\" className=\"flex\">\n                <RoleList handleShow={() => {\n                  addModalRef.current?.showAddRoleModal();\n                }}\n                />\n                <BoxLayout variant=\"subRight\" className=\"flex flex-col\">\n                  <RoleAccessList />\n                </BoxLayout>\n              </BoxLayout>\n            )\n            : (\n              <div className=\"flex items-center w-full\">\n                <NoData\n                  onClick={() => {\n                    addModalRef.current?.showAddRoleModal();\n                  }}\n                  btnText=\"Add Role\"\n                  title=\"No roles found\"\n                />\n              </div>\n            )\n        )}\n      <AddRole addModalRef={addModalRef} />\n    </Layout>\n  );\n};\n\nconst RoleAccessMain = () => (\n  <RoleAccessProvider>\n    <RoleAccess />\n  </RoleAccessProvider>\n);\n\nexport default RoleAccessMain;\n"
  },
  {
    "path": "packages/client/src/container/Shared/BuildApp/BuildAppDropdown/animation.json",
    "content": "{\n  \"v\": \"4.6.0\",\n  \"fr\": 29.9700012207031,\n  \"ip\": 0,\n  \"op\": 49.0000019958109,\n  \"w\": 200,\n  \"h\": 200,\n  \"nm\": \"loading_ring_medium\",\n  \"ddd\": 0,\n  \"assets\": [],\n  \"layers\": [\n    {\n      \"ddd\": 0,\n      \"ind\": 1,\n      \"ty\": 4,\n      \"nm\": \"green ring 1\",\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100\n        },\n        \"r\": {\n          \"a\": 1,\n          \"k\": [\n            {\n              \"i\": {\n                \"x\": [\n                  0.833\n                ],\n                \"y\": [\n                  0.833\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  0.167\n                ],\n                \"y\": [\n                  0.167\n                ]\n              },\n              \"n\": [\n                \"0p833_0p833_0p167_0p167\"\n              ],\n              \"t\": 0,\n              \"s\": [\n                0\n              ],\n              \"e\": [\n                360\n              ]\n            },\n            {\n              \"t\": 49.0000019958109\n            }\n          ]\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            0\n          ]\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            200,\n            200,\n            100\n          ]\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  54,\n                  54\n                ]\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ]\n              },\n              \"nm\": \"Ellipse Path 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\"\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  1,\n                  1,\n                  1,\n                  1\n                ]\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 6\n              },\n              \"lc\": 2,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\"\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Ellipse 1\",\n          \"np\": 3,\n          \"mn\": \"ADBE Vector Group\"\n        },\n        {\n          \"ty\": \"tm\",\n          \"s\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.667\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.644\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p667_1_0p644_0\"\n                ],\n                \"t\": 10,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  100\n                ]\n              },\n              {\n                \"t\": 50.0000020365418\n              }\n            ],\n            \"ix\": 1\n          },\n          \"e\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.667\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.333\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p667_1_0p333_0\"\n                ],\n                \"t\": -1,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  100\n                ]\n              },\n              {\n                \"t\": 37.0000015070409\n              }\n            ],\n            \"ix\": 2\n          },\n          \"o\": {\n            \"a\": 0,\n            \"k\": 0,\n            \"ix\": 3\n          },\n          \"m\": 1,\n          \"ix\": 2,\n          \"nm\": \"Trim Paths 1\",\n          \"mn\": \"ADBE Vector Filter - Trim\"\n        }\n      ],\n      \"ip\": 0,\n      \"op\": 50.0000020365418,\n      \"st\": -1.00000004073083,\n      \"bm\": 0,\n      \"sr\": 1\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 2,\n      \"ty\": 4,\n      \"nm\": \"flamingo ring 3\",\n      \"parent\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100\n        },\n        \"r\": {\n          \"a\": 1,\n          \"k\": [\n            {\n              \"i\": {\n                \"x\": [\n                  0.785\n                ],\n                \"y\": [\n                  1\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  1\n                ],\n                \"y\": [\n                  0\n                ]\n              },\n              \"n\": [\n                \"0p785_1_1_0\"\n              ],\n              \"t\": 17,\n              \"s\": [\n                14.2\n              ],\n              \"e\": [\n                360\n              ]\n            },\n            {\n              \"t\": 50.0000020365418\n            }\n          ]\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ]\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  54,\n                  54\n                ]\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ]\n              },\n              \"nm\": \"Ellipse Path 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\"\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  1,\n                  1,\n                  1,\n                  1\n                ]\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 6\n              },\n              \"lc\": 2,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\"\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Ellipse 1\",\n          \"np\": 3,\n          \"mn\": \"ADBE Vector Group\"\n        },\n        {\n          \"ty\": \"tm\",\n          \"s\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.833\n                  ],\n                  \"y\": [\n                    0.833\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.167\n                  ],\n                  \"y\": [\n                    0.167\n                  ]\n                },\n                \"n\": [\n                  \"0p833_0p833_0p167_0p167\"\n                ],\n                \"t\": 42,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  1\n                ]\n              },\n              {\n                \"t\": 44.0000017921567\n              }\n            ],\n            \"ix\": 1\n          },\n          \"e\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.833\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.333\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p833_1_0p333_0\"\n                ],\n                \"t\": 20,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  1\n                ]\n              },\n              {\n                \"t\": 44.0000017921567\n              }\n            ],\n            \"ix\": 2\n          },\n          \"o\": {\n            \"a\": 0,\n            \"k\": 0,\n            \"ix\": 3\n          },\n          \"m\": 1,\n          \"ix\": 2,\n          \"nm\": \"Trim Paths 1\",\n          \"mn\": \"ADBE Vector Filter - Trim\"\n        }\n      ],\n      \"ip\": 17.0000006924242,\n      \"op\": 44.0000017921567,\n      \"st\": -1.00000004073083,\n      \"bm\": 0,\n      \"sr\": 1\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 3,\n      \"ty\": 4,\n      \"nm\": \"flamingo ring 2\",\n      \"parent\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100\n        },\n        \"r\": {\n          \"a\": 1,\n          \"k\": [\n            {\n              \"i\": {\n                \"x\": [\n                  0.612\n                ],\n                \"y\": [\n                  1\n                ]\n              },\n              \"o\": {\n                \"x\": [\n                  1\n                ],\n                \"y\": [\n                  0\n                ]\n              },\n              \"n\": [\n                \"0p612_1_1_0\"\n              ],\n              \"t\": 17,\n              \"s\": [\n                14.2\n              ],\n              \"e\": [\n                360\n              ]\n            },\n            {\n              \"t\": 50.0000020365418\n            }\n          ]\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ]\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  54,\n                  54\n                ]\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ]\n              },\n              \"nm\": \"Ellipse Path 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\"\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  1,\n                  1,\n                  1,\n                  1\n                ]\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 6\n              },\n              \"lc\": 2,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\"\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Ellipse 1\",\n          \"np\": 3,\n          \"mn\": \"ADBE Vector Group\"\n        },\n        {\n          \"ty\": \"tm\",\n          \"s\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.833\n                  ],\n                  \"y\": [\n                    0.833\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.167\n                  ],\n                  \"y\": [\n                    0.167\n                  ]\n                },\n                \"n\": [\n                  \"0p833_0p833_0p167_0p167\"\n                ],\n                \"t\": 42,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  13.7\n                ]\n              },\n              {\n                \"t\": 44.0000017921567\n              }\n            ],\n            \"ix\": 1\n          },\n          \"e\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.833\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    0.333\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p833_1_0p333_0\"\n                ],\n                \"t\": 20,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  13.7\n                ]\n              },\n              {\n                \"t\": 44.0000017921567\n              }\n            ],\n            \"ix\": 2\n          },\n          \"o\": {\n            \"a\": 0,\n            \"k\": 0,\n            \"ix\": 3\n          },\n          \"m\": 1,\n          \"ix\": 2,\n          \"nm\": \"Trim Paths 1\",\n          \"mn\": \"ADBE Vector Filter - Trim\"\n        }\n      ],\n      \"ip\": 17.0000006924242,\n      \"op\": 44.0000017921567,\n      \"st\": -1.00000004073083,\n      \"bm\": 0,\n      \"sr\": 1\n    },\n    {\n      \"ddd\": 0,\n      \"ind\": 4,\n      \"ty\": 4,\n      \"nm\": \"flaming ring 1\",\n      \"parent\": 1,\n      \"ks\": {\n        \"o\": {\n          \"a\": 0,\n          \"k\": 100\n        },\n        \"r\": {\n          \"a\": 0,\n          \"k\": 0\n        },\n        \"p\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"a\": {\n          \"a\": 0,\n          \"k\": [\n            0,\n            0,\n            0\n          ]\n        },\n        \"s\": {\n          \"a\": 0,\n          \"k\": [\n            100,\n            100,\n            100\n          ]\n        }\n      },\n      \"ao\": 0,\n      \"shapes\": [\n        {\n          \"ty\": \"gr\",\n          \"it\": [\n            {\n              \"d\": 1,\n              \"ty\": \"el\",\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  54,\n                  54\n                ]\n              },\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ]\n              },\n              \"nm\": \"Ellipse Path 1\",\n              \"mn\": \"ADBE Vector Shape - Ellipse\"\n            },\n            {\n              \"ty\": \"st\",\n              \"c\": {\n                \"a\": 0,\n                \"k\": [\n                  1,\n                  1,\n                  1,\n                  1\n                ]\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100\n              },\n              \"w\": {\n                \"a\": 0,\n                \"k\": 6\n              },\n              \"lc\": 2,\n              \"lj\": 1,\n              \"ml\": 4,\n              \"nm\": \"Stroke 1\",\n              \"mn\": \"ADBE Vector Graphic - Stroke\"\n            },\n            {\n              \"ty\": \"tr\",\n              \"p\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 2\n              },\n              \"a\": {\n                \"a\": 0,\n                \"k\": [\n                  0,\n                  0\n                ],\n                \"ix\": 1\n              },\n              \"s\": {\n                \"a\": 0,\n                \"k\": [\n                  100,\n                  100\n                ],\n                \"ix\": 3\n              },\n              \"r\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 6\n              },\n              \"o\": {\n                \"a\": 0,\n                \"k\": 100,\n                \"ix\": 7\n              },\n              \"sk\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 4\n              },\n              \"sa\": {\n                \"a\": 0,\n                \"k\": 0,\n                \"ix\": 5\n              },\n              \"nm\": \"Transform\"\n            }\n          ],\n          \"nm\": \"Ellipse 1\",\n          \"np\": 3,\n          \"mn\": \"ADBE Vector Group\"\n        },\n        {\n          \"ty\": \"tm\",\n          \"s\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.667\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    1\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p667_1_1_0\"\n                ],\n                \"t\": 8,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  100\n                ]\n              },\n              {\n                \"t\": 48.0000019550801\n              }\n            ],\n            \"ix\": 1\n          },\n          \"e\": {\n            \"a\": 1,\n            \"k\": [\n              {\n                \"i\": {\n                  \"x\": [\n                    0.667\n                  ],\n                  \"y\": [\n                    1\n                  ]\n                },\n                \"o\": {\n                  \"x\": [\n                    1\n                  ],\n                  \"y\": [\n                    0\n                  ]\n                },\n                \"n\": [\n                  \"0p667_1_1_0\"\n                ],\n                \"t\": -1,\n                \"s\": [\n                  0\n                ],\n                \"e\": [\n                  100\n                ]\n              },\n              {\n                \"t\": 37.0000015070409\n              }\n            ],\n            \"ix\": 2\n          },\n          \"o\": {\n            \"a\": 0,\n            \"k\": 0,\n            \"ix\": 3\n          },\n          \"m\": 1,\n          \"ix\": 2,\n          \"nm\": \"Trim Paths 1\",\n          \"mn\": \"ADBE Vector Filter - Trim\"\n        }\n      ],\n      \"ip\": 15.0000006109625,\n      \"op\": 44.0000017921567,\n      \"st\": -1.00000004073083,\n      \"bm\": 0,\n      \"sr\": 1\n    }\n  ]\n}"
  },
  {
    "path": "packages/client/src/container/Shared/BuildApp/BuildAppDropdown/index.js",
    "content": "import React from 'react';\nimport { shallowEqual, useDispatch, useSelector } from 'react-redux';\nimport { Icons } from '@dhiwise/icons';\nimport Lottie from 'react-lottie';\nimport {\n  Button, DropdownMenu, Select, MenuBox, ConfirmationAlert,\n} from '../../../../components';\nimport { BUILD_ARCHITECTURE_CODE } from '../../../../constant/buildProcessConstant';\nimport { setBuildCodeState } from '../../../../redux/reducers/buildCode';\nimport { codeGenerator } from '../../../../redux/thunks/buildCode';\nimport { useBoolean } from '../../../../components/hooks';\nimport { apiClient, API_URLS } from '../../../../api';\nimport animationData from './animation.json';\nimport { useToastNotifications } from '../../../hooks';\n\nconst defaultOptions = {\n  loop: true,\n  autoplay: true,\n  animationData,\n  rendererSettings: {\n    preserveAspectRatio: 'xMidYMid slice',\n  },\n};\nexport const BuildVSCodePopup = () => {\n  // To Ask openWithVs code or not\n  const {\n    buildError, isOpenVsCode, generatedId, applicationName, codeGeneratedPath,\n  } = useSelector((\n    { buildCode, projects },\n  ) => ({\n    buildError: buildCode.buildError,\n    isOpenVsCode: buildCode.vsCodePopup,\n    generatedId: buildCode.generatedId,\n    applicationName: projects.currentProjectDetail.applicationList.find((app) => app._id === projects.currentApplicationId)?.name,\n    codeGeneratedPath: buildCode.codeGeneratedPath,\n  }), shallowEqual);\n\n  const { addErrorToast } = useToastNotifications();\n  const dispatch = useDispatch();\n  const [vsCodeLoader, setVsCodeLoader, hideVsCodeLoader] = useBoolean(false);\n  const openInVsCode = () => {\n    setVsCodeLoader();\n    apiClient(API_URLS.application.openVsCode, { generatedId, name: applicationName }).then(() => {\n      hideVsCodeLoader();\n      dispatch(setBuildCodeState({ vsCodePopup: !isOpenVsCode }));\n    }).catch((e) => {\n      addErrorToast(e);\n      hideVsCodeLoader();\n      dispatch(setBuildCodeState({ vsCodePopup: !isOpenVsCode }));\n    });\n  };\n  return (\n    <ConfirmationAlert\n      okText={false}\n      isOpen={isOpenVsCode}\n      closeModal={() => {\n        dispatch(setBuildCodeState({ vsCodePopup: !isOpenVsCode }));\n      }}\n      titleVariant=\"h4\"\n      size=\"w-6/12 xxl:w-4/12\"\n      // eslint-disable-next-line react/jsx-props-no-spreading\n      {... (codeGeneratedPath && {\n        shortDesc:\n  <div>\n    <span>\n      Access the generated code from the following path:\n      <br />\n      <b>\n        packages/server\n        {codeGeneratedPath}\n      </b>\n    </span>\n    <span> if you do not have VS code installed.</span>\n  </div>,\n      })}\n      title={buildError ? 'Error found while building your application' : 'Your application is successfully build'}\n    >\n      {buildError\n\n        ? <div className=\"text-error mt-3\">{buildError}</div>\n        : (\n          <Button\n            autoFocus\n            onClick={openInVsCode}\n            className=\"w-48 mt-5\"\n            variant=\"primary\"\n            shape=\"rounded\"\n            loading={vsCodeLoader}\n          >\n            Open with VS code\n          </Button>\n        )}\n    </ConfirmationAlert>\n  );\n};\nconst options = [\n  {\n    name: 'MVC',\n    id: BUILD_ARCHITECTURE_CODE.MVC,\n  },\n  {\n    name: 'Clean Code',\n    id: BUILD_ARCHITECTURE_CODE.CC,\n  },\n];\n\nexport const BuildAppDropdown = () => {\n  const { isBuildLoading, buildArchitecture, generatedId } = useSelector(({ buildCode }) => ({\n    isBuildLoading: buildCode.isBuildLoading,\n    buildArchitecture: buildCode.buildArchitecture,\n    generatedId: buildCode.generatedId,\n\n  }), shallowEqual);\n  const [architectureValue, setArchitectureValue] = React.useState(buildArchitecture);\n  const dispatch = useDispatch();\n\n  const onChange = (val) => {\n    setArchitectureValue(val);\n    dispatch(setBuildCodeState({ buildArchitecture: val }));\n  };\n  const applicationId = useSelector((state) => state.projects.currentApplicationId);\n  const [isBuild, setBuild, hideBuild] = useBoolean(false);\n\n  return (\n    <>\n\n      <DropdownMenu\n        dropdownMenu=\"w-auto\"\n        position=\"right\"\n        placeholder={() => (\n          <div className=\"flex items-center h-full bg-primary-dark hover:bg-primary-dark\">\n            <MenuBox\n              title=\"Build app\"\n              menuClass=\"bg-primary-dark hover:bg-primary-dark h-full border-l border-gray-200\"\n              isDropdown={false}\n              isIcon\n              textCss=\"text-defaultWhite\"\n              icon={<Icons.Project color=\"#ffffff\" />}\n            />\n            {isBuildLoading && (\n              <>\n                <Lottie\n                  options={defaultOptions}\n                  height={20}\n                  width={30}\n                />\n              </>\n            )}\n          </div>\n        )}\n        isChildren\n        triggerType=\"component\"\n        trigger=\"buildApp\"\n        wrapClass=\"buildDropdown\"\n      >\n        <div className=\"mb-3\">\n          <Select\n            disabled={!!generatedId || isBuildLoading}\n            label=\"Code architecture\"\n            options={options}\n            value={architectureValue}\n            onChange={onChange}\n            defaultValue=\"MVC\"\n            isClearable={false}\n          />\n        </div>\n        <Button\n          loading={isBuildLoading}\n          onClick={() => {\n            if (generatedId) {\n              setBuild();\n              return;\n            }\n            dispatch(codeGenerator({ applicationId, projectType: architectureValue }));\n          }}\n          className=\"w-full\"\n          variant=\"primary\"\n          shape=\"rounded\"\n        >\n          Build app\n        </Button>\n\n      </DropdownMenu>\n      <BuildVSCodePopup />\n      <ConfirmationAlert\n        isOpen={isBuild}\n        description=\"Building a new application will permanently delete your old build application.\"\n        okText=\"Build app\"\n        variant=\"primary\"\n        handleSubmit={() => {\n          hideBuild();\n          dispatch(codeGenerator({ applicationId, projectType: architectureValue }));\n        }}\n        handleClose={hideBuild}\n      />\n\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/LanguageHeader/index.js",
    "content": "import React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { Icons } from '@dhiwise/icons';\nimport { useHistory } from 'react-router';\nimport { languageHeaderCss } from './languageHeaderCss';\nimport {\n  Heading, MenuBox, LinkTag, ConfirmationAlert,\n} from '../../../../components';\nimport { APPLICATION_DASHBOARD } from '../../../../constant/Project/applicationStep';\nimport { BuildAppDropdown } from '../../BuildApp/BuildAppDropdown';\nimport { useBoolean } from '../../../../components/hooks';\nimport { destroyApplication } from '../../../../api/project';\nimport { resetBuildState } from '../../../../redux/reducers/buildCode';\n\nexport const LanguageHeader = () => {\n  const currentApplicationId = useSelector((state) => state.projects.currentApplicationId);\n  const currentProjectDetail = useSelector((state) => state.projects.currentProjectDetail);\n  const applicationCode = useSelector((state) => state.projects.currentApplicationCode);\n  const history = useHistory();\n  const dispatch = useDispatch();\n  const currentApplicationName = currentProjectDetail?.applicationList?.find((application) => application?._id === currentApplicationId)?.name;\n  const [isAlert, setAlert, hideAlert] = useBoolean(false);\n  const destroyApp = () => {\n    destroyApplication({ id: currentApplicationId, isHardDelete: true }).then(() => {\n      dispatch(resetBuildState());\n      history.push('/', { isNewApp: true });\n      hideAlert();\n    });\n  };\n\n  return (\n    <>\n      <div className={`header ${languageHeaderCss.headWrap}`}>\n        <div className=\"w-4/12 flex\">\n          <MenuBox\n            title=\"Create new app\"\n            isDropdown={false}\n            isIcon\n            onClick={setAlert}\n            icon={<Icons.App />}\n          />\n          <hr className=\"bg-gray-100 h-auto my-2 m-auto mx-2 w-0.5\" />\n          <div className=\"flex items-center ml-2 w-8/12\">\n            <Heading variant=\"h6\" className=\"truncate\">\n              <LinkTag whiteText className=\"hover:no-underline\" link={APPLICATION_DASHBOARD[applicationCode]}>\n                {currentApplicationName || ''}\n                {' '}\n              </LinkTag>\n            </Heading>\n          </div>\n        </div>\n        <div className=\"w-8/12 h-12 flex justify-end\">\n\n          <BuildAppDropdown />\n        </div>\n        <ConfirmationAlert\n          description=\"To create a new application, your current application data will be deleted.\"\n          handleSubmit={destroyApp}\n          isOpen={isAlert}\n          handleClose={hideAlert}\n        />\n      </div>\n\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/LanguageHeader/languageHeaderCss.js",
    "content": "export const languageHeaderCss = {\n  headWrap: 'bg-gray-200 flex sticky top-0 z-1000000 justify-between',\n  menuSelect: 'bg-gray-300 hover:bg-gray-300 border-b-2 border-primary-dark',\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/Sidebar/MainSidebar/index.js",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n  MenuItem,\n} from 'react-pro-sidebar';\nimport ReactTooltip from 'react-tooltip';\nimport { SidebarCss } from '../sidebarCss';\n\nexport const DefaultSidebar = ({\n  link, tooltipID, tooltip, icon, iconActive, linkSet, iconClass, onPopupOpen, onClick,\n}) => {\n  const Path = window.location.pathname;\n  return (\n    <Link data-tip data-for={tooltipID} to={link} onClick={onPopupOpen && onClick}>\n      <ReactTooltip id={tooltipID} type=\"dark\">{tooltip}</ReactTooltip>\n      <MenuItem\n        className={`${SidebarCss.menulist} ${Path.split('/')[2] === linkSet && 'bg-primary-dark hover:bg-primary-dark'}`}\n      >\n        <div className={`w-5 h-5 m-auto ${iconClass}`}>\n          {Path.split('/')[2] === linkSet ? <>{iconActive}</> : <>{icon}</>}\n        </div>\n        {/* <div className={`text-xs mt-2 text-center text-primary-text ${Path.split('/')[2]\n         === linkSet && 'text-defaultWhite'}`}>{tooltip}</div> */}\n      </MenuItem>\n    </Link>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/Sidebar/SubSidebar/SidebarlistCss.js",
    "content": "export const SidebarListCss = {\n  sidebar: '',\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/Sidebar/SubSidebar/index.js",
    "content": "import React from 'react';\nimport ScrollArea from 'react-scrollbar';\nimport {\n  ProSidebar,\n} from 'react-pro-sidebar';\n// import ReactTooltip from 'react-tooltip';\nimport { Icons } from '@dhiwise/icons';\nimport { SidebarListCss } from './SidebarlistCss';\nimport { BoxLayout, IconBox } from '../../../../../components';\n\nexport const SidebarList = React.memo(({\n  Scroll = false, children, style, isAddButton, tooltip, addClick, sidebarWrap, title, Pin, toggle, IconFill, sidebarClass, PinActive, icon, IconClick, Icontooltip, IconVariant = 'primary',\n  isAddButtonDisabled = false,\n}) => (\n  <BoxLayout variant=\"subSidebar\" style={style} className={sidebarClass}>\n    <ProSidebar className={`${SidebarListCss.sidebar} ${sidebarWrap} sidebar-list`}>\n      {!!title && (\n      <div className=\"sideTop flex justify-between p-3 items-center border-b-1 border-gray-100 relative\">\n        <div className=\"text-primary-text text-base font-semibold\">{title}</div>\n        <div className=\"flex\">\n          {Pin && (\n          <IconBox\n            variant=\"outline\"\n            size=\"small\"\n            tooltip={PinActive ? 'Pin the navigator' : 'Pin the navigator'}\n            className=\"mr-3\"\n            onClick={toggle}\n            icon={PinActive ? <><Icons.PinFill /></>\n              : <><Icons.PinOutline /></>}\n          />\n          )}\n          {icon\n          && <IconBox size=\"small\" variant={IconVariant} className={isAddButton && 'mr-1'} tooltip={Icontooltip} icon={icon} onClick={IconClick} />}\n          {isAddButton\n          && (\n            <IconBox disabled={isAddButtonDisabled} size=\"small\" variant=\"primary\" tooltip={tooltip} icon={IconFill || <Icons.Plus color=\"#fff\" />} onClick={addClick} />\n          )}\n        </div>\n      </div>\n      )}\n      {Scroll ? <>{ children }</> : (\n        <ScrollArea\n          speed={0.8}\n          className=\"area h-full justify-between\"\n          contentClassName=\"w-full\"\n          smoothScrolling\n        >\n          {children}\n        </ScrollArea>\n      )}\n    </ProSidebar>\n  </BoxLayout>\n));\nSidebarList.displayName = 'SidebarList';\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/Sidebar/index.js",
    "content": "import React from 'react';\nimport {\n  ProSidebar, Menu,\n} from 'react-pro-sidebar';\nimport 'react-pro-sidebar/dist/css/styles.css';\nimport '../../../../assets/css/sidebar.css';\nimport ScrollArea from 'react-scrollbar';\nimport { sidebar } from '../../../../constant/sidebar';\nimport { SidebarCss } from './sidebarCss';\nimport { DefaultSidebar } from './MainSidebar';\nimport { APPLICATION_CODE } from '../../../../constant/Project/applicationStep';\n\nconst Sidebar = () => {\n  const menus = sidebar[APPLICATION_CODE.nodeExpress];\n  return (\n    <>\n      <div className=\"theme-sidenav\">\n        <ProSidebar className={SidebarCss.wrap}>\n          {/* <div className={SidebarCss.projectSiebar}> */}\n          {/* <ChangeLanguage /> */}\n          {/* </div> */}\n          <ScrollArea\n            speed={0.8}\n            className=\"area h-full\"\n            contentClassName=\"content\"\n            smoothScrolling\n          >\n            <Menu iconShape=\"square\">\n              {menus.map((d) => (\n                <DefaultSidebar\n                  linkSet={d.linkSet}\n                    // after build different url redirect\n                  link={d.link}\n                  tooltipID={d.tooltipID}\n                  iconActive={d.iconActive}\n                  icon={d.icon}\n                  tooltip={d.tooltip}\n                  key={d.tooltipID}\n                  onPopupOpen={d.onPopupOpen}\n                />\n              ))}\n            </Menu>\n          </ScrollArea>\n\n        </ProSidebar>\n      </div>\n    </>\n  );\n};\nexport default Sidebar;\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/Sidebar/sidebarCss.js",
    "content": "export const SidebarCss = {\n  wrap: 'border-gray-100 h-full w-sidebar',\n  menulist: 'text-gray-900 hover:bg-gary-200 hover:text-gray-900',\n  projectSiebar: 'py-2 flex justify-center my-dw5',\n  bottomButton: 'border-t boredr-1 border-gray-80',\n  bottomButtonwrap: 'w-full text-md my-4 flex justify-center items-center font-bold text-sm cursor-pointer',\n  folderMenu: 'border-b-1 border-gray-100',\n  menuActive: 'bg-primary-dark',\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/StepHeader/index.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\nimport { BackButton, Heading } from '../../../../components';\n\nexport const StepHeader = ({\n  backTitle, headTitle, link, onClick, nameEditable, updateScreenName, setScreenName, editTitle, // editTitle,\n  setNameEditable, screenName,\n}) => {\n  const screenNameRef = React.useRef(null);\n\n  return (\n    <div className=\"flex px-3 py-2 bg-gray-200 justify-center relative header flex-shrink-0\">\n      <div className=\"absolute left-4 top-2.5 z-1\">\n        <BackButton onClick={onClick} link={link} title={backTitle} />\n      </div>\n      <div className=\"ml-10 text-center\">\n        <Heading variant=\"h5\" className=\"flex items-center\">\n          {!nameEditable && headTitle }\n          {editTitle\n          && (\n          <>\n            {\n          nameEditable ? (\n            <input\n              ref={screenNameRef}\n              placeholder=\"Screen Name\"\n              className=\"focus:outline-none text-xl text-primary-text bg-transparent font-semibold font-title w-full\"\n              value={screenName}\n              defaultValue={screenName}\n              onChange={(e) => {\n                if (e.target.value?.length <= 250) {\n                  setScreenName(e.target.value);\n                }\n              }}\n              onBlur={updateScreenName}\n              onKeyDown={(e) => { if (e.key === 'Enter') updateScreenName(); }}\n            />\n          ) : (\n            <div\n              onClick={() => {\n                setTimeout(() => {\n                  screenNameRef.current?.focus();\n                }, 100);\n                setNameEditable(true);\n              }}\n              className=\"w-4 h-4 ml-2 cursor-pointer\"\n            >\n\n              <Icons.Edit />\n            </div>\n          )\n        }\n          </>\n          )}\n          {/* {editTitle\n          && (\n          <div className=\"w-4 h-4 ml-2\">\n            <Icons.Edit/>\n          </div>\n          )} */}\n        </Heading>\n      </div>\n    </div>\n\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/Layout/index.js",
    "content": "import React from 'react';\nimport { Helmet } from 'react-helmet';\nimport Sidebar from './Sidebar';\nimport { LanguageHeader } from './LanguageHeader';\n\nconst Layout = ({\n  isSidebar, children, hideHeader, bodyClass, wrapClass, ...props\n}) => (\n  <div className={`flex flex-col h-screen ${wrapClass}`}>\n    <Helmet>\n      <title>DhiWise</title>\n      <meta name=\"description\" content=\"Our mission is to build the most intelligent programming platform in the world\" />\n    </Helmet>\n    <>\n\n      {!hideHeader && <LanguageHeader />}\n    </>\n\n    <div className={`flex bg-body flex-grow overflow-auto ${bodyClass}`}>\n      {isSidebar\n          // eslint-disable-next-line react/jsx-props-no-spreading\n          && <Sidebar {...props} />}\n      {children}\n    </div>\n  </div>\n);\nexport default Layout;\n"
  },
  {
    "path": "packages/client/src/container/Shared/LayoutStepUrl/SidebarLayout.js",
    "content": "import React from 'react';\nimport { Link } from 'react-router-dom';\nimport {\n  MenuItem,\n} from 'react-pro-sidebar';\nimport 'react-pro-sidebar/dist/css/styles.css';\nimport '../../../assets/css/sidebar.css';\nimport ReactTooltip from 'react-tooltip';\n// import { SidebarCss } from '../Layout/Sidebar/sidebarCss';\nimport { SidebarMenuListCss } from '../../../components/SidebarMenuList/sidebarMenuListCss';\n// linkSet = pass compare more than 2nd index ex.node/crud/model\n\n// when toggle layout is small show icon\nexport const SmallToggleLayout = ({\n  link,\n  linkSet, // link path which to compare with url\n  tooltipID,\n  tooltip,\n  icon,\n  iconActive,\n  iconClass,\n}) => {\n  const Path = window.location.pathname;\n  return (\n    <Link data-tip data-for={tooltipID} to={link}>\n      <ReactTooltip id={tooltipID} effect=\"solid\">{tooltip}</ReactTooltip>\n      <MenuItem\n        className={`px-1 py-3.5 list-none ${Path.slice(Path.indexOf(linkSet)) === linkSet && 'bg-primary-dark hover:bg-primary-dark'}`}\n      >\n        <div className={`w-5 h-5 m-auto ${iconClass}`}>\n          {Path.slice(Path.indexOf(linkSet)) === linkSet ? <>{iconActive}</> : <>{icon}</>}\n        </div>\n      </MenuItem>\n    </Link>\n  );\n};\n\n// sidebar with title and description\nexport const BigToggleLayout = ({\n  link, // redirect link\n  linkSet, // link path which to compare with url\n  title = '',\n  description = '',\n}) => {\n  const Path = window.location.pathname;\n  return (\n    <Link data-tip to={link}>\n      <MenuItem\n        className={`${SidebarMenuListCss.menuList}  ${Path.slice(Path.indexOf(linkSet)) === linkSet && SidebarMenuListCss.menuActive}`}\n      >\n        <div className=\"flex items-center justify-between w-full\">\n          <span className={`${Path.slice(Path.indexOf(linkSet)) === linkSet && 'text-defaultWhite'} text-sm leading-5 truncate text-primary-text`}>\n            {title}\n          </span>\n        </div>\n        <div className={`${Path.slice(Path.indexOf(linkSet)) === linkSet && 'text-defaultWhite'} text-xxs mt-1 leading-4 text-primary-text`}>\n          {description}\n        </div>\n      </MenuItem>\n    </Link>\n\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/LayoutStepUrl/index.js",
    "content": "import React from 'react';\nimport {\n  ProSidebar, Menu,\n} from 'react-pro-sidebar';\nimport 'react-pro-sidebar/dist/css/styles.css';\nimport '../../../assets/css/sidebar.css';\nimport ScrollArea from 'react-scrollbar';\nimport { ToggleBox } from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\nimport { encryptStorage } from '../../../utils/localStorage';\nimport { SidebarCss } from '../Layout/Sidebar/sidebarCss';\nimport { BigToggleLayout, SmallToggleLayout } from './SidebarLayout';\nimport { stepSidebarData } from './stepSidebarData';\n\nconst LayoutStepUrl = ({\n  children, moduleName = '', toggle = true,\n  isOpenBigLayout = true,\n}) => {\n  const [tabToggle, , , handelTabToggle] = useBoolean(encryptStorage.get('sidebarToggle') ?? isOpenBigLayout);\n  React.useEffect(() => {\n    // to maintain global all tab toggle when false set\n    ((isOpenBigLayout && !tabToggle) || (!isOpenBigLayout && tabToggle)) ? encryptStorage.set('sidebarToggle', tabToggle) : encryptStorage.remove('sidebarToggle');\n  }, [tabToggle]);\n  return (\n    <>\n      <div className=\"flex flex-grow h-0\">\n        <div className={`border-r border-gray-200 layoutStep relative z-10000 ${!tabToggle ? 'bg-gray-200 w-12' : 'bg-gray-300 xxl:w-1.5/12 w-2/12 '}`}>\n          <ProSidebar className={`${SidebarCss.wrap} sm:w-full`}>\n            <ScrollArea\n              speed={0.8}\n              className=\"area h-full\"\n              contentClassName=\"content\"\n              smoothScrolling\n            >\n              {tabToggle ? (\n                <Menu iconShape=\"square\">\n                  {stepSidebarData[moduleName].map((d) => (\n\n                    <BigToggleLayout\n                      key={d.title}\n                      linkSet={d.linkSet}\n                      link={d.link}\n                      title={d.title}\n                      description={d.description}\n                    />\n\n                  ))}\n                </Menu>\n              ) : stepSidebarData[moduleName].map((d) => (\n\n                <SmallToggleLayout\n                  linkSet={d.linkSet}\n                  link={d.link}\n                  tooltipID={d.tooltipID}\n                  iconActive={d.iconActive}\n                  icon={d.icon}\n                  tooltip={d.tooltip}\n                  key={d.tooltipID}\n                />\n              ))}\n            </ScrollArea>\n          </ProSidebar>\n        </div>\n        <div\n          className={`relative ${!tabToggle ? 'smallToggle' : 'xxl:w-10.5/12 w-10/12 '} flex flex-col`}\n        >\n          {toggle && <ToggleBox onClick={handelTabToggle} isSidebar={!tabToggle} />}\n          {children}\n        </div>\n      </div>\n\n    </>\n  );\n};\nexport default LayoutStepUrl;\n"
  },
  {
    "path": "packages/client/src/container/Shared/LayoutStepUrl/stepSidebarData.js",
    "content": "import React from 'react';\nimport { Icons } from '@dhiwise/icons';\n\nexport const stepSidebarData = {\n  NodeCRUD: [\n    {\n      linkSet: 'crud/platform',\n      link: '/node/crud/platform',\n      tooltipID: 'Platform Configuration',\n      iconActive: <Icons.Configuration color=\"#ffffff\" />,\n      icon: <Icons.Configuration />,\n      tooltip: 'Platform Configuration',\n      title: 'Platform Configuration',\n      description: 'Enter information regarding platforms, type of users, and details of login access.',\n    },\n    {\n      linkSet: 'crud/model',\n      link: '/node/crud/model',\n      tooltipID: 'Models',\n      iconActive: <Icons.Model color=\"#ffffff\" />,\n      icon: <Icons.Model />,\n      tooltip: 'Models',\n      title: 'Models',\n      description: 'Define models, the datatype of its attributes, and validations.',\n    },\n    // {\n    //   linkSet: 'crud/authentication',\n    //   link: '/node/crud/authentication',\n    //   tooltipID: 'Authentication Setup',\n    //   iconActive: <Icons.Auth color=\"#ffffff\" />,\n    //   icon: <Icons.Auth />,\n    //   tooltip: 'Authentication Setup',\n    //   title: 'Authentication Setup',\n    //   description: 'Setup of authentication for your application.',\n    //   isHideAfterBuild: true,\n    // },\n    {\n      linkSet: 'crud/permission',\n      link: '/node/crud/permission',\n      tooltipID: 'Model Permission',\n      iconActive: <Icons.Permission color=\"#ffffff\" />,\n      icon: <Icons.Permission />,\n      tooltip: 'Model Permission',\n      title: 'Model Permission',\n      description: 'Setup permission for CRUD operations for each model.',\n    },\n    {\n      linkSet: 'crud/routes',\n      link: '/node/crud/routes',\n      tooltipID: 'routes',\n      iconActive: <Icons.Routes color=\"#ffffff\" />,\n      icon: <Icons.Routes />,\n      tooltip: 'Routes',\n      title: 'Routes',\n      description: 'Setup of model-wise routes.',\n    },\n  ],\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/TechnologySetStep/Application.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = () => (\n  <ContentLoader\n    speed={2}\n    className=\"mt-5\"\n    width=\"100%\"\n    height=\"365\"\n    // viewBox=\"0 0 100% 100%\"\n    backgroundColor=\"var(--color-gray-200)\"\n    foregroundColor=\"var(--color-gray-100)\"\n    // {...props}\n  >\n    {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n    <rect x=\"0\" y=\"18\" rx=\"3\" ry=\"3\" width=\"60px\" height=\"6\" />\n    {/* <rect x=\"20\" y=\"50\" rx=\"3\" ry=\"3\" width=\"1px\" height=\"250px\" /> */}\n    <rect x=\"0\" y=\"70\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"80\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"40px\" />\n    <rect x=\"0\" y=\"140\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"150\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"40px\" />\n    <rect x=\"0\" y=\"210\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"220\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"80px\" />\n    <rect x=\"0\" y=\"320\" rx=\"3\" ry=\"3\" width=\"250\" height=\"42px\" />\n\n    {/* <circle cx=\"20\" cy=\"340\" r=\"20\" />\n    <rect x=\"50\" y=\"340\" rx=\"3\" ry=\"3\" width=\"45px\" height=\"6\" /> */}\n\n    {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n  </ContentLoader>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/Shared/TechnologySetStep/SideBlock.loader.js",
    "content": "import React from 'react';\nimport ContentLoader from 'react-content-loader';\n\nconst MyLoader = () => (\n  <ContentLoader\n    speed={2}\n    className=\"mt-5\"\n    width=\"100%\"\n    height=\"365\"\n    // viewBox=\"0 0 100% 100%\"\n    backgroundColor=\"var(--color-gray-200)\"\n    foregroundColor=\"var(--color-gray-100)\"\n    // {...props}\n  >\n    {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n    <rect x=\"0\" y=\"18\" rx=\"3\" ry=\"3\" width=\"100%\" height=\"365\" />\n    {/* <rect x=\"20\" y=\"50\" rx=\"3\" ry=\"3\" width=\"1px\" height=\"250px\" /> */}\n    {/* <rect x=\"0\" y=\"70\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"80\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"40px\" />\n    <rect x=\"0\" y=\"140\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"150\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"40px\" />\n    <rect x=\"0\" y=\"210\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"4px\" />\n    <rect x=\"0\" y=\"220\" rx=\"3\" ry=\"3\" width=\"90%\" height=\"80px\" />\n    <rect x=\"0\" y=\"320\" rx=\"3\" ry=\"3\" width=\"250\" height=\"42px\" /> */}\n\n    {/* <circle cx=\"20\" cy=\"340\" r=\"20\" />\n    <rect x=\"50\" y=\"340\" rx=\"3\" ry=\"3\" width=\"45px\" height=\"6\" /> */}\n\n    {/* <circle cx=\"20\" cy=\"20\" r=\"20\" /> */}\n  </ContentLoader>\n);\n\nexport default MyLoader;\n"
  },
  {
    "path": "packages/client/src/container/Shared/TechnologySetStep/addNewTag.js",
    "content": "import { isEmpty, uniq } from 'lodash';\nimport React from 'react';\nimport { Select } from '../../../components';\nimport { useComponentWillUnmount } from '../../hooks';\n\nfunction TagNameSelect({\n  onChange, defaultTagName = [], options, tagNameCustom = [], setCustomTag = () => {}, ...props\n}) {\n  const [tagList, setTagList] = React.useState(options);\n  const [tag, setTag] = React.useState(defaultTagName);\n  const [inputVal, setInputVal] = React.useState('');\n  const isFirstSet = React.useRef(false);\n\n  const handleSelectTag = (value) => {\n    setTag(value);\n    onChange(value);\n  };\n  React.useEffect(() => {\n    // custom platform created\n    if (!isEmpty(tagNameCustom) && !isFirstSet.current) {\n      setTagList(uniq([...tagNameCustom, ...tagList]));\n      isFirstSet.current = true;\n    }\n  }, [tagNameCustom]);\n\n  useComponentWillUnmount(() => { isFirstSet.current = false; setTagList([]); });\n\n  const handleCreateTag = (e) => {\n    const value = inputVal;\n    const nameTagList = tagList.map((d) => d.id.toLowerCase());\n    if (['Enter'].includes(e.code) && !isEmpty(value) && !nameTagList.includes(value.toLowerCase()) && /^[-_A-Za-z]+$/.test(value) && !/^[-_]+$/.test(value[0])) {\n      e.stopPropagation();\n      e.preventDefault();\n      const updateTagList = [...tagList];\n      const newOption = { id: value.trim().toLowerCase(), name: value.trim() };\n      updateTagList.unshift(newOption);\n      setTagList([...updateTagList]);\n      setCustomTag([...updateTagList]);\n      // const selectedTag = tag;\n      // selectedTag.unshift(value.trim());\n      // setTag(selectedTag);\n    }\n  };\n  React.useEffect(() => () => {\n    setTag([]);\n  }, []);\n\n  return (\n    <Select\n      value={tag}\n      options={!isEmpty(tagList) ? tagList : []}\n      onChange={handleSelectTag}\n      onInputChange={(value) => {\n        if (/^[-_A-Za-z]+$/.test(value) && !/^[-_]+$/.test(value[0])) {\n          setInputVal(value);\n        }\n        if (!value) {\n          setInputVal(value);\n        }\n        // tagCreateValue.current = value;\n      }}\n      inputValue={inputVal}\n      onKeyDown={(e) => { handleCreateTag(e); }}\n      // eslint-disable-next-line react/jsx-props-no-spreading\n      {...props}\n    />\n  );\n}\n\nexport default TagNameSelect;\n"
  },
  {
    "path": "packages/client/src/container/Shared/TechnologySetStep/applicationForm.js",
    "content": "/* eslint-disable no-unused-vars */\nimport React from 'react';\nimport { Controller } from 'react-hook-form';\nimport get from 'lodash/get';\nimport { Helmet } from 'react-helmet';\nimport {\n  Button, StringInput, TextArea, NumberInput, Select, Checkbox, Input, SelectTree, MessageNotify,\n\n} from '../../../components';\nimport {\n  // APPLICATION_PAGE_HEADING,\n  ORM_TYPE,\n  DATABASE_TYPE,\n  APPLICATION_CODE,\n} from '../../../constant/Project/applicationStep';\nimport TagNameSelect from './addNewTag';\n\nexport const ApplicationStep = ({\n  applicationStep,\n  handleClick,\n  loading,\n  control,\n  errors,\n  handleSubmit,\n  watch,\n  register,\n  setValue,\n}) => {\n  const [isShow, setShow] = React.useState(true);\n  const handleClose = () => {\n    setShow(false);\n  };\n  const KeysToComponentMap = {\n    stringInput: StringInput,\n    textArea: TextArea,\n    numberInput: NumberInput,\n    dropdown: Select,\n    checkbox: Checkbox,\n    input: Input,\n    selectTree: SelectTree,\n    tagNameSelect: TagNameSelect,\n  };\n\n  return (\n    <>\n      <Helmet>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1,user-scalable=0\" />\n      </Helmet>\n\n      <div className=\"pb-5\">\n\n        <div className=\"grid gap-5  grid-cols-1\">\n          {applicationStep?.map((field) => {\n            let isVisible = true;\n            if (field.dependentOn) {\n              isVisible = watch(field.dependentOn);\n            }\n            if (field.includes) {\n              isVisible = get(watch(), field.dependentOn)?.includes(field.includes);\n            }\n            if (field.equals) {\n              isVisible = get(watch(), field.dependentOn) === field.equals;\n            }\n            let { options } = field;\n            if (field.optionDependent) {\n              const filter = [];\n              // get(watch(), field.optionDependent)\n              //         && get(watch(), field.optionDependent)?.map((data) => filter?.push({ id: data, name: field?.optionFilter?.find((option) => option?.id === data)?.name || data }));\n              options = filter;\n            }\n            if (field.stateKey) {\n              options = [];\n            }\n            return true && (\n            // <>\n\n            <>\n              {field.messageInfo && isShow && (\n              <MessageNotify size=\"small\" messageCloseClass=\"top-2 bottom-auto sm:right-2\" isClose isInfo messageType=\"info\" closeClick={handleClose}>\n                {/* eslint-disable-next-line react/no-danger */}\n                <div dangerouslySetInnerHTML={{ __html: field.messageInfo }} />\n              </MessageNotify>\n              )}\n              <Controller\n                key={field.name + APPLICATION_CODE.nodeExpress}\n                control={control}\n                name={field.name}\n                rules={field.rules}\n                defaultValue={field.defaultValue}\n                render={(controlProps) => (field.ishidden\n                  ? (\n                    <input\n                      type=\"hidden\"\n                      ref={register}\n                    />\n                  )\n                  : React.createElement(KeysToComponentMap[field.component], {\n                    ref: register,\n                    placeholder: field.placeholder,\n                    label: field.label,\n                    desc: field.description,\n                    error: get(errors ?? '', field.dbKey) ? field.validationMsg[get(errors ?? '', field.dbKey)?.type] : '',\n                    options,\n                    checked: !!watch(field.dbKey),\n                    // fileinputref: field.component === 'folderUpload' ? register(field.rules) : 'false',\n                    ...controlProps,\n                    ...field.extraProps,\n                    onChange: (...args) => {\n                      controlProps?.onChange(...args);\n                      if (field.dbKey === 'stepInput.databaseType') {\n                        args.includes(DATABASE_TYPE.MONGODB) && setValue('stepInput[ormType]', ORM_TYPE.MONGOOSE);\n                        Object.values(DATABASE_TYPE).filter((d) => d !== DATABASE_TYPE.MONGODB).some((r) => args.includes(r)) && setValue('stepInput[ormType]', ORM_TYPE.SEQUELIZE);\n                      }\n                    },\n                  }))}\n              />\n            </>\n            );\n          })}\n        </div>\n        <div className=\"mt-6\">\n          <Button loading={loading} variant=\"primary\" type=\"submit\" shape=\"rounded\" onClick={handleSubmit(handleClick)}>\n            Create application\n          </Button>\n        </div>\n\n      </div>\n    </>\n  );\n};\n"
  },
  {
    "path": "packages/client/src/container/Shared/TechnologySetStep/index.js",
    "content": "/* eslint-disable no-nested-ternary */\n/* eslint-disable no-param-reassign */\nimport React from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useHistory, useLocation } from 'react-router-dom';\nimport { Controller, useForm } from 'react-hook-form';\nimport {\n  createNewApplication, redirectApplication,\n} from '../../../api/project';\nimport {\n  ContainerBox, Heading,\n} from '../../../components';\nimport { useBoolean } from '../../../components/hooks';\nimport {\n  APPLICATION_STEP, APPLICATION_CODE, APP_NAME_PATTERN, APP_NAME_VALIDATION_MESSAGE, APPLICATION_DASHBOARD,\n} from '../../../constant/Project/applicationStep';\nimport { useQueryParams, useToastNotifications } from '../../hooks';\n\nimport { selectCurrentApplication } from '../../../redux/reducers/projects';\nimport Layout from '../Layout';\nimport { ApplicationStep } from './applicationForm';\nimport { Input } from '../../../components/Input';\nimport { resetBuildState, setBuildCodeState } from '../../../redux/reducers/buildCode';\n\nconst TechnologySetStep = () => {\n  const history = useHistory();\n  const dispatch = useDispatch();\n  const { projectId, appId } = useQueryParams(['projectId', 'appId']);\n  const { addErrorToast, addSuccessToast } = useToastNotifications();\n  const [loading, setLoading, hideLoading] = useBoolean(false);\n  const location = useLocation();\n  const applicationId = useSelector(({ projects }) => (projects.currentApplicationId));\n\n  const {\n    control, errors, handleSubmit, watch, register, setValue, setError,\n  } = useForm({ mode: 'onChange' });\n  React.useEffect(() => {\n    dispatch(resetBuildState());\n    if (!location.state?.isNewApp && applicationId) {\n      redirectApplication(applicationId).then((response) => {\n        dispatch(setBuildCodeState({\n          buildArchitecture: response.data.projectType,\n          generatedId: response.data.generatedId,\n        }));\n        history.push('/node/dashboard');\n      });\n    }\n  }, []);\n\n  const createApp = (data) => {\n    const values = data;\n    // eslint-disable-next-line no-nested-ternary\n    setLoading();\n    const apiFun = createNewApplication;\n\n    const apiReq = {\n      ...values, projectId, definitionId: appId, projectDefinitionCode: APPLICATION_CODE.nodeExpress,\n    };\n\n    apiFun(apiReq).then((res) => {\n      addSuccessToast('Application added successfully.');\n      try {\n        dispatch(\n          selectCurrentApplication({\n            projectId,\n            applicationId: res?.data?._id,\n            applicationCode: APPLICATION_CODE.nodeExpress,\n            currentProject: { applications: [res.data] },\n            generatedProjectData: res?.data?.generatedIdData || {},\n            prevGeneratedProjectData: res?.data?.tempGeneratedIdData || {},\n            statics: res?.data?.statics || {},\n            generatedProjectArchitecture: res?.data?.projectType || '',\n            processStep: res?.data?.processStep || '',\n            generatedId: res?.data?.generatedId || '',\n          }),\n        );\n      } catch (e) {\n        console.warn('Error:', e);\n      }\n      history.push(APPLICATION_DASHBOARD.NODE_EXPRESS);\n    }).catch((err) => {\n      const errMessage = typeof err === 'string' ? err : err?.message;\n      addErrorToast(errMessage);\n      if (errMessage === 'Application name already exists.') {\n        const nextfield = document.querySelector('input[name=\"name\"]');\n        nextfield?.focus();\n        setError('name', {\n          type: 'duplicate',\n          message: '',\n        });\n      }\n    })\n      .finally(() => { hideLoading(); });\n  };\n\n  const handleClick = async (data) => {\n    if (errors?.length > 0) {\n      return;\n    }\n    createApp(data);\n  };\n\n  return (\n    <Layout hideHeader bodyClass=\"flex-col h-full\">\n      <>\n        <div className=\"flex px-3 py-2 bg-gray-200 justify-center relative header flex-shrink-0\">\n          {/* <div className=\"w-full\"> */}\n          <img\n            className=\"absolute left-4 top-2.5 z-1 w-20\"\n            src=\"https://dxuoui1db8w1y.cloudfront.net/DhiWise-white.svg\"\n            alt=\"logo\"\n          />\n          {/* </div> */}\n          <ContainerBox className=\"py-0 text-center\">\n            <div className=\"full\">\n              <Heading className=\"hidden md:block\" variant=\"h5\">\n                Create Node.js application\n              </Heading>\n            </div>\n          </ContainerBox>\n        </div>\n        <div className=\"overflow-auto flex-grow relative\">\n          <ContainerBox className=\"pb-0 pt-0 h-full\">\n            <div className=\"w-full md:w-6/12 xxl:w-full m-auto flex flex-col min-h-full\">\n              <div className=\"applicationNameBox pt-5 pb-4 md:py-5 \">\n                <Controller\n                  key=\"name\"\n                  control={control}\n                  name=\"name\"\n                  rules={{\n                    required: true,\n                    minLength: 1,\n                    maxLength: 40,\n                    validate: (value) => APP_NAME_PATTERN[APPLICATION_CODE.nodeExpress]?.test(value) && /^[a-zA-Z0-9]+/.test(value[0]),\n                  }}\n                  render={(controlProps) => (\n                    <Input\n                        // eslint-disable-next-line react/jsx-props-no-spreading\n                      {...controlProps}\n                      label=\"Application name*\"\n                      placeholder=\"Enter application name\"\n                      desc=\"Enter name of your application.\"\n                      error={\n                          errors?.name ? APP_NAME_VALIDATION_MESSAGE[APPLICATION_CODE.nodeExpress]?.name[errors?.name?.type] : ''\n                        }\n                    />\n                  )}\n                />\n              </div>\n              <div className=\"flex flex-wrap md:flex-nowwrap flex-grow w-full\">\n\n                <form onSubmit={handleSubmit(handleClick)} className=\"w-full\">\n                  <ApplicationStep\n                    applicationStep={[...APPLICATION_STEP]}\n                    handleClick={handleClick}\n                    loading={loading}\n                    projectData={APPLICATION_CODE.nodeExpress}\n                    control={control}\n                    errors={errors}\n                    handleSubmit={handleSubmit}\n                    watch={watch}\n                    register={register}\n                    setValue={setValue}\n                    projectId={projectId}\n                  />\n\n                </form>\n\n              </div>\n            </div>\n          </ContainerBox>\n        </div>\n      </>\n    </Layout>\n  );\n};\nexport default TechnologySetStep;\n"
  },
  {
    "path": "packages/client/src/container/common.js",
    "content": "import React from 'react';\n\nfunction Common() {\n  return (\n    <div>\n      Hello.....Welcome To DhiWise\n    </div>\n  );\n}\n\nexport default Common;\n"
  },
  {
    "path": "packages/client/src/container/hooks/index.js",
    "content": "import useClickOutside from 'use-onclickoutside';\nimport useBoolean from './useBoolean';\nimport useComponentDidMount from './useComponentDidMount';\nimport useComponentWillUnmount from './useComponentWillUnmount';\nimport useDrop from './useDrop';\nimport useToastNotifications from './useToastNotifications';\nimport useWindowSize from './useWindowSize';\nimport useQueryParams from './useQueryParams';\n\nexport {\n  useBoolean,\n  useComponentDidMount,\n  useComponentWillUnmount,\n  useDrop,\n  useClickOutside,\n  useToastNotifications,\n  useWindowSize,\n  useQueryParams,\n};\n"
  },
  {
    "path": "packages/client/src/container/hooks/useBoolean.js",
    "content": "import { useState } from 'react';\n\nconst useBoolean = (status) => {\n  const [boolean, setBoolean] = useState(status);\n  const setTrue = () => setBoolean(true);\n  const setFalse = () => setBoolean(false);\n  return [boolean, setTrue, setFalse];\n};\nexport default useBoolean;\n"
  },
  {
    "path": "packages/client/src/container/hooks/useComponentDidMount.js",
    "content": "import React from 'react';\n// usage: useComponentDidMount(() => console.log('Component did mount'));\nconst useComponentDidMount = (onMountHandler) => {\n  React.useEffect(() => {\n    onMountHandler();\n  }, []);\n};\nexport default useComponentDidMount;\n"
  },
  {
    "path": "packages/client/src/container/hooks/useComponentWillUnmount.js",
    "content": "import React from 'react';\n\n// usage : useComponentWillUnmount(() => console.log('Component will unmount'));\n\nconst useComponentWillUnmount = (onUnmountHandler) => {\n  React.useEffect(\n    () => () => {\n      onUnmountHandler();\n    },\n    [],\n  );\n};\nexport default useComponentWillUnmount;\n"
  },
  {
    "path": "packages/client/src/container/hooks/useDrop.js",
    "content": "import { useMemo, useState } from 'react';\n\nconst noop = () => { };\n\nconst createEventHandler = (options) => (dataTransfer, event) => {\n  if (dataTransfer.files && dataTransfer.files.length) {\n    (options.onFiles || noop)(Array.from(dataTransfer.files), event);\n  }\n};\n\nconst registerDropEvents = (eventHandler, setIsHovering) => ({\n  onDragOver: (event) => {\n    event.preventDefault();\n    setIsHovering(true);\n  },\n  onDragEnter: (event) => {\n    event.preventDefault();\n    setIsHovering(true);\n  },\n  onDragLeave: () => {\n    setIsHovering(false);\n  },\n  onDrop: (event) => {\n    event.preventDefault();\n    event.persist();\n    setIsHovering(false);\n    eventHandler(event.dataTransfer, event);\n  },\n  onPaste: (event) => {\n    event.persist();\n    eventHandler(event.clipboardData, event);\n  },\n});\n\nconst useDrop = (options) => {\n  const { onFiles } = options;\n  const [isHovering, setIsHovering] = useState(false);\n  const eventHandler = useMemo(() => createEventHandler(options), [onFiles]);\n  const eventProps = useMemo(\n    () => registerDropEvents(eventHandler, setIsHovering), [eventHandler, setIsHovering],\n  );\n\n  return [eventProps, { isHovering }];\n};\n\nexport default useDrop;\n"
  },
  {
    "path": "packages/client/src/container/hooks/useQueryParams.js",
    "content": "const getQuery = () => {\n  if (typeof window !== 'undefined') {\n    return new URLSearchParams(window.location.search);\n  }\n  return new URLSearchParams();\n};\n\nconst useQueryParams = (keys = []) => {\n  const query = getQuery();\n  let params;\n  if (typeof keys === 'string') {\n    params = query.get(keys);\n  }\n  if (Array.isArray(keys)) {\n    const tempKeys = {};\n    keys.forEach((key) => {\n      tempKeys[key] = query.get(key);\n    });\n    params = tempKeys;\n  }\n  return params;\n};\nexport default useQueryParams;\n"
  },
  {
    "path": "packages/client/src/container/hooks/useToastNotifications.js",
    "content": "import * as React from 'react';\nimport { useToasts } from 'react-toast-notifications';\n\nexport default function useToastNotifications() {\n  const { addToast, removeAllToasts } = useToasts();\n\n  const addSuccessToast = React.useCallback((message) => {\n    if (typeof message === 'string') {\n      removeAllToasts();\n      addToast(message, { appearance: 'success', autoDismiss: true });\n    }\n  }, []);\n\n  const addErrorToast = React.useCallback((message) => {\n    if (typeof message === 'string' && message !== 'Invalid token.') {\n      removeAllToasts();\n      addToast(message, { appearance: 'error', autoDismiss: true });\n    }\n  }, []);\n\n  return { addSuccessToast, addErrorToast };\n}\n"
  },
  {
    "path": "packages/client/src/container/hooks/useWindowSize.js",
    "content": "import React from 'react';\nimport { useBoolean } from '../../components/hooks';\n\nconst validations = { width: 1200 };\nexport default function useWindowSize(options = validations) {\n  const [isValidSize, setValidSize, setNotValidSize] = useBoolean(true);\n\n  React.useEffect(() => {\n    // Handler to call on window resize\n    function handleResize() {\n      // Pass Options to set initial width\n      // console.log(window.innerWidth, options.width, window.innerWidth < options.width.window);\n      if (window.screen.width < options.width) {\n        setNotValidSize();\n      } else setValidSize();\n    }\n\n    // Add event listener\n    window.addEventListener('resize', handleResize);\n\n    // Call handler right away so state gets updated with initial window size\n    handleResize();\n\n    // Remove event listener on cleanup\n    return () => window.removeEventListener('resize', handleResize);\n  }, []); // Empty array ensures that effect is only run on mount\n\n  return isValidSize;\n}\n"
  },
  {
    "path": "packages/client/src/index.css",
    "content": "body {\n  margin: 0;\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n    sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n    monospace;\n}\n"
  },
  {
    "path": "packages/client/src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\nimport './assets/css/main.css';\nimport './assets/css/components/style.css';\nimport './assets/css/drawer.css';\nimport './assets/css/sidebar.css';\n\nReactDOM.render(\n  <React.StrictMode>\n    <App />\n  </React.StrictMode>,\n  document.getElementById('root'),\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"
  },
  {
    "path": "packages/client/src/redux/reducers/buildCode.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { createSlice } from '@reduxjs/toolkit';\nimport { BUILD_ARCHITECTURE_CODE } from '../../constant/buildProcessConstant';\nimport { codeGenerator } from '../thunks/buildCode';\n\nconst initialState = {\n  generatedId: '',\n  isBuildLoading: false,\n  buildArchitecture: BUILD_ARCHITECTURE_CODE.MVC,\n  vsCodePopup: false,\n  buildError: '',\n  codeGeneratedPath: '',\n};\nconst buildCode = createSlice({\n  name: 'buildCode',\n  initialState,\n  reducers: {\n    setBuildCodeState: (state, { payload }) => {\n      state.buildArchitecture = payload.buildArchitecture ?? state.buildArchitecture;\n      state.vsCodePopup = payload.vsCodePopup ?? state.vsCodePopup;\n      state.generatedId = payload.generatedId ?? state.generatedId;\n    },\n    resetBuildState: (state) => {\n      Object.assign(state, initialState);\n    },\n  },\n  extraReducers: (builder) => {\n    builder\n      .addCase(codeGenerator.fulfilled, (state, { payload }) => {\n        // If on create app page and than not set\n        if (window.location.pathname.includes('node')) {\n          state.isBuildLoading = false;\n          state.vsCodePopup = true;\n          state.generatedId = payload.data.generatedId;\n          state.codeGeneratedPath = payload.data.path;\n        }\n      })\n      .addCase(codeGenerator.pending, (state) => {\n        state.isBuildLoading = true;\n      })\n      .addCase(codeGenerator.rejected, (state, { error }) => {\n        state.isBuildLoading = false;\n        state.buildError = error?.message;\n        state.vsCodePopup = true;\n        state.codeGeneratedPath = '';\n      });\n  },\n});\n\nconst { reducer, actions } = buildCode;\nexport const {\n  setBuildCodeState, resetBuildState,\n} = actions;\nexport default reducer;\n"
  },
  {
    "path": "packages/client/src/redux/reducers/constants.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { createSlice } from '@reduxjs/toolkit';\nimport { cloneDeep, sortBy } from 'lodash';\nimport { listConstants } from '../thunks/constants';\n\nconst sortConstantList = (constantList) => sortBy(constantList, ['fileName']);\n\nconst initialState = { constantList: [], currentId: null, listConstantFetching: false };\nconst constants = createSlice({\n  name: 'constants',\n  initialState,\n  reducers: {\n    addConstant: {\n      reducer: (state, { payload }) => {\n        const tempConstants = cloneDeep(state.constantList);\n        tempConstants.unshift(payload);\n        state.constantList = sortConstantList(tempConstants);\n        state.currentId = payload._id;\n      },\n    },\n    setCurrentConstant: (state, { payload }) => {\n      state.currentId = payload;\n    },\n\n    deleteCurrentConstant: (state) => {\n      state.constantList = state.constantList.filter((constant) => constant._id !== state.currentId);\n      state.currentId = state.constantList?.[0]?._id || null;\n    },\n    updateCurrentConstant: function updateConstant(state, { payload }) {\n      const tempConstants = state.constantList.map((constant) => {\n        if (payload._id === constant._id) {\n          return payload;\n        }\n        return constant;\n      });\n      state.constantList = sortConstantList(tempConstants);\n    },\n  },\n  extraReducers: (builder) => {\n    builder\n      .addCase(listConstants.fulfilled, (state, { payload }) => {\n        state.listConstantFetching = false;\n        state.constantList = payload?.data?.list ? sortConstantList(payload.data.list) : [];\n        state.currentId = state.constantList[0]?._id;\n      })\n      .addCase(listConstants.pending, (state) => {\n        state.listConstantFetching = true;\n      });\n  },\n});\n\nconst { reducer, actions } = constants;\nexport const {\n  addConstant, setCurrentConstant, deleteCurrentConstant, updateCurrentConstant,\n} = actions;\nexport default reducer;\n"
  },
  {
    "path": "packages/client/src/redux/reducers/index.js",
    "content": "import { combineReducers } from '@reduxjs/toolkit';\nimport models from './models';\nimport projects from './projects';\nimport constants from './constants';\nimport policy from './policy';\nimport buildCode from './buildCode';\n\nexport default combineReducers({\n  models,\n  projects,\n  constants,\n  policy,\n  buildCode,\n});\n"
  },
  {
    "path": "packages/client/src/redux/reducers/models.js",
    "content": "/* eslint-disable no-prototype-builtins */\n/* eslint-disable no-param-reassign */\nimport { createSlice } from '@reduxjs/toolkit';\nimport { sortBy, uniqBy } from 'lodash';\nimport { listModels, getModelDetail } from '../thunks/models';\n\nconst sortModelList = (models) => sortBy(models, 'name');\n\nconst initialState = {\n  modelList: [], currentId: null, listFetching: false, editorLoader: false, detailFetching: false,\n};\nconst models = createSlice({\n  name: 'models',\n  initialState,\n  reducers: {\n    addModel: {\n      reducer: (state, { payload }) => {\n        const tempModels = [...state.modelList];\n        tempModels.push(payload);\n        state.modelList = sortModelList(tempModels);\n        state.currentId = payload._id;\n      },\n    },\n    addMultipleModel: (state, { payload }) => {\n      let tempModels = [...payload, ...state.modelList];\n      tempModels = uniqBy(tempModels, '_id');\n      state.modelList = sortModelList(tempModels);\n      state.currentId = sortModelList(payload)?.[0]?._id || state.modelList[0]?._id;\n    },\n    setCurrentModel: (state, { payload }) => {\n      state.currentId = payload.currentId;\n      // state.editorLoader = true;\n    },\n    hideEditorLoader: (state) => {\n      state.editorLoader = false;\n    },\n    setCurrentModelProperty: (state, { payload }) => {\n      state.modelList = state.modelList.map((model) => {\n        if (model._id === payload.modelId) {\n          return {\n            ...model,\n            [payload.key]: payload.value,\n          };\n        }\n        return model;\n      });\n    },\n    deleteCurrentModel: (state, { payload }) => {\n      state.modelList = state.modelList.filter((model) => model._id !== (payload?.delId || state.currentId));\n      if ((payload?.delId && payload.delId === state.currentId) || !payload?.delId) { state.currentId = state.modelList?.[0]?._id || null; }\n    },\n    updateModel: function updateModel(state, { payload }) {\n      const tempModels = state.modelList.map((model) => {\n        if (payload._id === model._id) {\n          return payload;\n        }\n        return model;\n      });\n      state.modelList = sortModelList(tempModels);\n    },\n    updateModelDependency: function updateModelDependency(state, { payload }) {\n      // update model while change dependency\n      const { request, response, currentModel } = payload;\n      const tempModels = state.modelList.map((model) => {\n        if (response._id === model._id) {\n          if (request.hasOwnProperty('name')) {\n            Object.keys(model.schemaJson).forEach((x) => {\n              // update  schema\n              if (model.schemaJson[x].ref === currentModel?.name) {\n                model.schemaJson[x].ref = request.name;\n              }\n            });\n            model.name = response.name;\n            return model;\n          } if (request.hasOwnProperty('description')) {\n            model.description = response.description;\n            return model;\n          } return response;\n        }\n        return model;\n      });\n      state.modelList = sortModelList(tempModels);\n    },\n  },\n  extraReducers: (builder) => {\n    builder\n      .addCase(listModels.fulfilled, (state, { payload }) => {\n        state.modelList = payload?.data?.list ? sortModelList(payload.data.list) : [];\n        state.currentId = state.modelList[0]?._id;\n        state.listFetching = false;\n      })\n      .addCase(listModels.pending, (state) => {\n        state.listFetching = true;\n      })\n      .addCase(getModelDetail.fulfilled, (state, { payload }) => {\n        const index = state.modelList.findIndex((model) => model._id === payload?.data?._id);\n        if (index > -1) { state.modelList[index] = payload.data; }\n        state.detailFetching = false;\n      })\n      .addCase(getModelDetail.pending, (state) => {\n        state.detailFetching = true;\n      })\n      .addCase(getModelDetail.rejected, (state) => {\n        state.detailFetching = false;\n      });\n  },\n});\n\nconst { reducer, actions } = models;\nexport const {\n  hideEditorLoader, addModel, setCurrentModel, setCurrentModelProperty, deleteCurrentModel, updateModel, addMultipleModel, updateModelDependency,\n} = actions;\nexport default reducer;\n"
  },
  {
    "path": "packages/client/src/redux/reducers/policy.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { createSlice } from '@reduxjs/toolkit';\nimport { cloneDeep, sortBy } from 'lodash';\nimport { listPolicy } from '../thunks/policy';\n\nconst sortPolicyList = (policyList) => sortBy(policyList, ['fileName']);\n\nconst initialState = { policyList: [], currentId: null, listPolicyFetching: false };\nconst policy = createSlice({\n  name: 'policy',\n  initialState,\n  reducers: {\n    addPolicy: {\n      reducer: (state, { payload }) => {\n        const tempPolicies = cloneDeep(state.policyList);\n        tempPolicies.unshift(payload);\n        state.policyList = sortPolicyList(tempPolicies);\n        state.currentId = payload._id;\n      },\n    },\n    setCurrentPolicy: (state, { payload }) => {\n      state.currentId = payload;\n    },\n\n    deleteCurrentPolicy: (state) => {\n      state.policyList = state.policyList.filter((pol) => pol._id !== state.currentId);\n      state.currentId = state.policyList?.[0]?._id || null;\n    },\n    updateCurrentPolicy: function updatePolicy(state, { payload }) {\n      const tempPolicies = state.policyList.map((pol) => {\n        if (payload._id === pol._id) {\n          return payload;\n        }\n        return pol;\n      });\n      state.policyList = sortPolicyList(tempPolicies);\n    },\n  },\n  extraReducers: (builder) => {\n    builder\n      .addCase(listPolicy.fulfilled, (state, { payload }) => {\n        state.listPolicyFetching = false;\n        state.policyList = payload?.data?.list ? sortPolicyList(payload.data.list) : [];\n        state.currentId = state.policyList[0]?._id;\n      })\n      .addCase(listPolicy.pending, (state) => {\n        state.listPolicyFetching = true;\n      });\n  },\n});\n\nconst { reducer, actions } = policy;\nexport const {\n  addPolicy, setCurrentPolicy, deleteCurrentPolicy, updateCurrentPolicy,\n} = actions;\nexport default reducer;\n"
  },
  {
    "path": "packages/client/src/redux/reducers/projects.js",
    "content": "/* eslint-disable no-param-reassign */\nimport { createSlice } from '@reduxjs/toolkit';\nimport { isEmpty } from 'lodash';\nimport { ORM_TYPE, DATABASE_TYPE } from '../../constant/Project/applicationStep';\n\nconst initialState = {\n  currentApplicationId: null,\n  currentApplicationCode: '',\n  currentProjectDetail: { projectName: '', applicationList: [] },\n  applicationAddedBy: '',\n  isClone: false,\n  projectDatabase: {},\n  applicationDatabase: { ormType: ORM_TYPE.MONGOOSE, databaseType: DATABASE_TYPE.MONGODB }, // default MONGO\n};\nconst projects = createSlice({\n  name: 'projects',\n  initialState,\n  reducers: {\n    selectCurrentApplication: (state, { payload }) => {\n      state.currentApplicationId = payload.applicationId ?? state.currentApplicationId;\n\n      state.currentApplicationCode = payload.applicationCode ?? state.currentApplicationCode;\n\n      // Current Select application => project information and application List\n      state.currentProjectDetail = {\n        projectName: payload.currentProject?.name ?? state.currentProjectDetail.projectName,\n        applicationList: payload.currentProject?.applications ?? state.currentProjectDetail.applicationList,\n      };\n\n      const currentApplication = state.currentProjectDetail.applicationList.find((x) => x._id === state.currentApplicationId);\n      state.applicationDatabase = !isEmpty(currentApplication?.stepInput) ? currentApplication?.stepInput : initialState.applicationDatabase;\n    },\n  },\n});\n\nconst { reducer, actions } = projects;\nexport const {\n  selectCurrentApplication,\n} = actions;\nexport default reducer;\n"
  },
  {
    "path": "packages/client/src/redux/store.js",
    "content": "import storage from 'redux-persist/lib/storage';\nimport { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';\nimport {\n  persistReducer,\n  FLUSH,\n  REHYDRATE,\n  PAUSE,\n  PERSIST,\n  PURGE,\n  REGISTER,\n} from 'redux-persist';\nimport rootReducer from './reducers';\n\nconst persistConfig = {\n  key: 'dhiWise',\n  version: 1,\n  storage,\n};\n\nconst persistedReducer = persistReducer({ ...persistConfig }, rootReducer);\n\nexport default configureStore({\n  reducer: persistedReducer,\n  middleware: getDefaultMiddleware({\n    serializableCheck: {\n      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],\n    },\n  }),\n\n});\n"
  },
  {
    "path": "packages/client/src/redux/thunks/buildCode.js",
    "content": "import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { apiClient, API_URLS } from '../../api';\n\nexport const codeGenerator = createAsyncThunk(\n  'build/codeGeneration',\n  // eslint-disable-next-line no-return-await\n  async (data) => await apiClient(API_URLS.application.generate, data),\n);\n"
  },
  {
    "path": "packages/client/src/redux/thunks/constants.js",
    "content": "import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { fetchConstant } from '../../api/applicationConstant';\n\nexport const listConstants = createAsyncThunk(\n  'constant/pagination',\n  // eslint-disable-next-line no-return-await\n  async (data) => await fetchConstant(data),\n);\n"
  },
  {
    "path": "packages/client/src/redux/thunks/models.js",
    "content": "import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { API_URLS, apiClient } from '../../api';\nimport { getModel } from '../../api/models';\n\nexport const listModels = createAsyncThunk(\n  'model/paginate',\n  // eslint-disable-next-line no-return-await\n  async (data) => await apiClient(API_URLS.schema.paginate, data),\n);\n\nexport const getModelDetail = createAsyncThunk(\n  '',\n  // eslint-disable-next-line no-return-await\n  async (data) => await getModel(data),\n);\n"
  },
  {
    "path": "packages/client/src/redux/thunks/policy.js",
    "content": "import { createAsyncThunk } from '@reduxjs/toolkit';\nimport { fetchPolicy } from '../../api/applicationPolicy';\n\nexport const listPolicy = createAsyncThunk(\n  'policy/pagination',\n  // eslint-disable-next-line no-return-await\n  async (data) => await fetchPolicy(data),\n);\n"
  },
  {
    "path": "packages/client/src/reportWebVitals.js",
    "content": "const reportWebVitals = (onPerfEntry) => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({\n      getCLS, getFID, getFCP, getLCP, getTTFB,\n    }) => {\n      getCLS(onPerfEntry);\n      getFID(onPerfEntry);\n      getFCP(onPerfEntry);\n      getLCP(onPerfEntry);\n      getTTFB(onPerfEntry);\n    });\n  }\n};\n\nexport default reportWebVitals;\n"
  },
  {
    "path": "packages/client/src/setupTests.js",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom';\n"
  },
  {
    "path": "packages/client/src/utils/applicationPlatform.js",
    "content": "import { isEmpty, toLower } from 'lodash';\nimport { DEVICE_TYPE_NAME } from '../constant/permission';\n\nexport const getApplicationPlatforms = (loginAccess) => {\n  const allPlatforms = [];\n  loginAccess?.forEach((platform) => {\n    allPlatforms.push({ id: platform, name: (!isEmpty(toLower(DEVICE_TYPE_NAME[platform?.toUpperCase()])) ? toLower(DEVICE_TYPE_NAME[platform?.toUpperCase()]) : platform) });\n  });\n  return allPlatforms;\n};\n"
  },
  {
    "path": "packages/client/src/utils/dataTypes.js",
    "content": "/* eslint-disable no-param-reassign */\nexport function filterObjectTruthyValues(obj) {\n  return Object.keys(obj)\n    .reduce((o, key) => {\n      !!obj[key] && (o[key] = obj[key]);\n      return o;\n    }, {});\n}\n\nexport function filterObjectUndefinedValues(obj) {\n  return Object.keys(obj)\n    .reduce((o, key) => {\n      obj[key] !== undefined && (o[key] = obj[key]);\n      return o;\n    }, {});\n}\n"
  },
  {
    "path": "packages/client/src/utils/dateTimeFormatter.js",
    "content": "import dayjs from 'dayjs';\n\nconst relativeTime = require('dayjs/plugin/relativeTime');\n\nexport const dateFormat = 'MM-DD-YYYY';\nexport const dateTimeFormat = 'MM-DD-YYYY hh:mm:ss A';\n\ndayjs.extend(relativeTime);\n\nexport function dateTimeFormatter(date = dayjs(), format = 'DD MMM YYYY') {\n  return dayjs(date).format(format);\n}\n\nexport function getRemainingSecond(date) {\n  return dayjs(date).diff(dayjs(), 'second');\n}\n\nexport function addMinutes(minute) {\n  return dayjs().add(minute, 'minute');\n}\n\nexport function checkIsAfter(date) { // formate YYYY-MM-DD\n  return dayjs().format('YYYY-MM-DD') > date;\n}\n\nexport function getDayDiff(date) { // formate YYYY-MM-DD\n  return dayjs(date).diff(dayjs().format('YYYY-MM-DD'), 'day');\n}\n\nexport function getUnixTimestamp(date) {\n  return dayjs(date).unix(); // 1548381600\n}\n\nexport function getDateByTimestamp(unixTime, time) {\n  if (time) return dayjs(unixTime * 1000).format(dateTimeFormat);\n  return dayjs(unixTime * 1000).format(dateFormat);\n}\n\nexport const setDateToISO = (date) => dayjs(date).toISOString();\n"
  },
  {
    "path": "packages/client/src/utils/domMethods.js",
    "content": "export const onSingleKeyDown = (e, focusField, FiledPosition, idPrefix, opt) => {\n  // manage keyboard shortcuts for less inputs (event, field, object of fields)\n  const focusIndex = FiledPosition[focusField];\n  switch (e.keyCode) {\n    case 38:\n    { // up\n      let field;\n      if (opt?.inputWithId) {\n        field = document.querySelector(`#${idPrefix}${focusIndex - 1}  [tabindex=\"0\"]`);\n      } else { field = document.querySelector(`#${idPrefix}${focusIndex - 1}`); }\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n      break; }\n    case 40:\n    {\n      // down\n      let field;\n      if (opt?.inputWithId) {\n        field = document.querySelector(`#${idPrefix}${focusIndex + 1}  [tabindex=\"0\"]`);\n      } else { field = document.querySelector(`#${idPrefix}${focusIndex + 1}`); }\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n      break; }\n    case 37:\n    { // left\n      if (e.ctrlKey) {\n        let field;\n        if (opt?.inputWithId) {\n          field = document.querySelector(`#${idPrefix}${focusIndex - 1}  [tabindex=\"0\"]`);\n        } else { field = document.querySelector(`#${idPrefix}${focusIndex - 1}`); }\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n        }\n      }\n      break; }\n    case 39:\n    {\n      // right\n      if (e.ctrlKey) {\n        let field;\n        if (opt?.inputWithId) {\n          field = document.querySelector(`#${idPrefix}${focusIndex + 1}  [tabindex=\"0\"]`);\n        } else { field = document.querySelector(`#${idPrefix}${focusIndex + 1}`); }\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field.tabindex = 0;\n          field?.focus();\n        }\n      }\n      break; }\n    case 13:\n    {\n      // enter\n      let field;\n      if (opt?.inputWithId) {\n        field = document.querySelector(`#${idPrefix}${focusIndex + 1}  [tabindex=\"0\"]`);\n      } else { field = document.querySelector(`#${idPrefix}${focusIndex + 1}`); }\n      if (field && !field?.hasAttribute?.('disabled')) {\n        field?.focus();\n      }\n      break; }\n    default:\n      break;\n  }\n};\n\n/**\n * handle view table format keyboard shortcut handel\n * @param  {e} keyEvent keyboard event\n * @param  {} focusIndex current focusIndex\n * @param  {} totalColumns totalColumn in Table\n * @param  {} totalRows totalRow in Table\n * @param  {} id='r' if you want set custom id\n *\n */\nexport const keyBoardShortcut = ({\n  keyEvent: e, focusIndex, totalColumns, totalRows, id = 'r',\n}) => {\n  switch (e.keyCode) {\n    case 38:\n    { // up\n      for (let nextIndex = totalColumns; nextIndex < totalRows * totalColumns; nextIndex += totalColumns) {\n        const field = document.querySelector(`#${id}${focusIndex - nextIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n      break; }\n    case 40:\n    { // down\n      for (let nextIndex = totalColumns; nextIndex < totalRows * totalColumns; nextIndex += totalColumns) {\n        const field = document.querySelector(`#${id}${focusIndex + nextIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n      break; }\n    case 37:\n    { // left\n      if (e.ctrlKey) {\n        for (let nextIndex = 1; nextIndex !== totalRows * totalColumns; nextIndex += 1) {\n          const field = document.querySelector(`#${id}${focusIndex - nextIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            break;\n          }\n        }\n      }\n      break; }\n    case 39:\n    {\n      // right\n      if (e.ctrlKey) {\n        for (let nextIndex = 1; nextIndex !== totalRows * totalColumns; nextIndex += 1) {\n          const field = document.querySelector(`#${id}${focusIndex + nextIndex}`);\n          if (field && !field?.hasAttribute?.('disabled')) {\n            field?.focus();\n            break;\n          }\n        }\n      }\n      break; }\n    case 13:\n    {\n      // enter\n      for (let nextIndex = 1; nextIndex !== totalRows * totalColumns; nextIndex += 1) {\n        const field = document.querySelector(`#${id}${focusIndex + nextIndex}`);\n        if (field && !field?.hasAttribute?.('disabled')) {\n          field?.focus();\n          break;\n        }\n      }\n      break; }\n\n    default:\n      break;\n  }\n};\n"
  },
  {
    "path": "packages/client/src/utils/localStorage.js",
    "content": "export const encryptStorage = {\n  set: (key, value) => {\n    const setKey = JSON.stringify(key);\n    const setValue = JSON.stringify(value);\n    localStorage.setItem(setKey, setValue);\n  },\n  get: (key) => {\n    const setKey = JSON.stringify(key);\n    const data = localStorage.getItem(setKey);\n    return data ? JSON.parse(data) : null;\n  },\n  remove: (key) => {\n    const setKey = JSON.stringify(key);\n    localStorage.removeItem(setKey);\n  },\n};\n"
  },
  {
    "path": "packages/client/src/utils/mergeRefs.js",
    "content": "export default function mergeRefs(refs) {\n  return (value) => {\n    refs.forEach((ref) => {\n      if (typeof ref === 'function') {\n        ref(value);\n      } else if (ref != null) {\n        // eslint-disable-next-line no-param-reassign\n        ref.current = value;\n      }\n    });\n  };\n}\n"
  },
  {
    "path": "packages/client/src/utils/regex.js",
    "content": "export const removeLeadingSpace = /^ +/gm; // to remove all leading spaces\n\nexport const modelAttrRegex = /^[a-zA-Z_][a-zA-Z_0-9]*$/;\n\nexport const nodeKeyRegex = /^[a-zA-Z]+[\\w0-9_]*$/; // fileName,key(attribute),functionName\n\nexport const URLRegex = /^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?$/;\n\nexport const emailRegex = /^\\w+([.-]?\\w+)*@\\w+([.-]?\\w+)*(\\.\\w{2,3})+$/;\n\nexport const isRegExp = (string) => {\n  try {\n    // eslint-disable-next-line no-new-func\n    return new Function(`\n            \"use strict\";\n            try {\n                new RegExp(${string});\n                return true;\n            } catch (e) {\n                return false;\n            }\n        `)();\n  } catch (e) {\n    // console.log('false', e);\n    return false;\n  }\n};\n"
  },
  {
    "path": "packages/client/src/utils/validationMsgs.js",
    "content": "export const validationMsg = {\n  required: (alias) => `${alias} is required.`,\n  select: (alias) => `Please select ${alias}.`,\n  minLength: (alias) => `Minimum limit is ${alias} characters`,\n  maxLength: (alias) => `Maximum limit is ${alias} characters`,\n  min: (alias) => `Minimum limit is ${alias}`,\n  max: (alias) => `Maximum limit is ${alias}`,\n  pattern: (alias) => `${alias}`,\n  validate: (alias) => `${alias}`,\n};\n\nexport const getError = (errors = {}, keyName, alias) => (errors[keyName] ? validationMsg[errors[keyName].type](alias) : '');\n"
  },
  {
    "path": "packages/client/src/utils.js",
    "content": "import { isBoolean, isNumber, isArray } from 'lodash';\n\nexport const compact = (array) => array.filter(Boolean);\nexport const isString = (value) => typeof value === 'string';\nexport const isFunction = (value) => typeof value === 'function';\nexport const get = (obj, path) => path.split(/[,[\\].]+?/).reduce((o, key) => (o && o[key] ? o[key] : null), obj);\nexport const isNullOrUndefined = (value) => (value == null || value === undefined);\nexport const stringContainsCaseInsensitive = (search, subject) => subject.toLowerCase().indexOf(search.toLowerCase()) !== -1;\n\nexport const isUndefined = (value) => value === undefined;\n\nexport const isObjectType = (value) => typeof value === 'object';\n\nexport const isObject = (value) => !isNullOrUndefined(value)\n    && !Array.isArray(value)\n    && isObjectType(value)\n    && !(value instanceof Date);\n\nexport function capitalizeStr(value) {\n  if (value?.length > 0) {\n    return value.replace(/\\w\\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());\n  } return value;\n}\n\nexport const findMaxLengthObjectOfArray = (array) => {\n  let maxNum = 0;\n  let maxObject = {};\n  array.find((val) => {\n    if (isObject(val)) {\n      if (maxNum < Object.keys(val).length) {\n        maxNum = Object.keys(val).length;\n        maxObject = val;\n      }\n    }\n    return val;\n  });\n  return maxObject;\n};\n\nexport const getAllKeysRecursion = (data, finalData = []) => {\n  Object.keys(data).forEach((key) => {\n    if (isString(data[key]) || isBoolean(data[key]) || isNumber(data[key])) {\n      finalData.push(key);\n    } else if (isObject(data[key]) && !isArray(data[key])) {\n      getAllKeysRecursion(data[key], finalData);\n    } else if (Array.isArray(data[key]) && (isObject(data[key][0]) && !isArray(data[key][0]))) {\n      finalData.push(key);\n      const maxObj = findMaxLengthObjectOfArray(data[key]);\n      getAllKeysRecursion(maxObj, finalData);\n    }\n  });\n  return finalData;\n};\n\nexport const arrayMove = (arr, oldIndex, newIndex) => {\n  if (newIndex >= arr.length) {\n    let k = newIndex - arr.length + 1;\n    // eslint-disable-next-line no-plusplus\n    while (k--) {\n      arr.push(undefined);\n    }\n  }\n  arr.splice(newIndex, 0, arr.splice(oldIndex, 1)[0]);\n  return arr;\n};\n"
  },
  {
    "path": "packages/client/tailwind.config.js",
    "content": "module.exports = {\n  purge: [\n    './src/**/*.js',\n    './**/*.js',\n  ],\n  theme: {\n    extend: {\n      screens: {\n        sm: { min: '200px' },\n        md: { min: '541px' },\n        lg: { min: '768px' },\n        xl: { min: '1080px' },\n        xxl: { min: '1380px' },\n      },\n      colors: {\n        red: {\n          500: '#FA4D56',\n        },\n        headerSearch: 'var(--color-bg-headerSearch)',\n        primary: {\n          DEFAULT: '#0061ff',\n          10: 'var(--color-blue-10)',\n          100: 'var(--color-blue-100)',\n          text: 'var(--color-text-primary)',\n          dark: 'var(--color-bg-primary)',\n          light: 'var(--color-bg-primary-light)',\n          inverse: 'var(--color-bg-inverse)',\n          softlight: 'var(--color-bg-softlight)',\n          themecard: 'var(--color-bg-default-light)',\n          themecardborder: 'var(--color-border-default-light)',\n          bodytext: '#232323',\n          hoverdark: '#0352d1',\n          message: '#232323',\n          disable: '#9ec2fc',\n          buttonOutline: 'var(--color-button-outline-border)',\n        },\n        other: {\n          lightblue: 'var(--color-bg-lightblue)',\n          lightgreen: 'var(--color-bg-lightGreen)',\n          lightorange: 'var(--color-bg-lightorange)',\n        },\n        error: 'var(--color-bg-deactive)',\n        body: {\n          text: 'var(--color-text-body)',\n        },\n        secondary: {\n          DEFAULT: '#FF800D',\n          dark: '#FF800D',\n          light: '#ffeddd',\n          softlight: '#fff2e6',\n          yellow: 'var(--color-bg-yellow)',\n          yellowlight: '#fff8e1',\n          red: '#da202a',\n          redlight: '#fff1f1',\n          reddarkLight: 'var(--color-bg-redstatus)',\n          blue: '#0747cf',\n          bluelight: '#f0f7ff',\n          green: '#009E25',\n          greenLight: 'var(--color-bg-greenLight)',\n        },\n        lightdefault: {\n          light: 'var(--color-bg-light)',\n        },\n        gray: {\n          black: 'var(--color-gray-black)',\n          300: 'var(--color-gray-300)',\n          350: 'var(--color-gray-350)',\n          200: 'var(--color-gray-200)',\n          100: 'var(--color-gray-100)',\n          90: 'var(--color-gray-90)',\n          80: 'var(--color-gray-80)',\n          70: 'var(--color-gray-70)',\n          60: 'var(--color-gray-60)',\n          50: 'var(--color-gray-50)',\n          40: 'var(--color-gray-40)',\n          30: 'var(--color-gray-30)',\n          20: 'var(--color-gray-20)',\n          10: 'var(--color-gray-10)',\n          0: 'var(--color-gray-0)',\n          white: 'var(--color-gray-white)',\n          input: 'var(--color-gray-input)',\n          inputSub: 'var(--color-gray-inputSub)',\n          error: 'var(--color-text-error)',\n          selectDropdown: 'var(--color-select-dropdown)',\n          activebg: 'var(--color-bg-active)',\n          deactivebg: 'var(--color-bg-deactive)',\n          codeButton: 'var(--color-code-button)',\n        },\n      },\n      textColor: {\n        white: 'var(--color-text-white)',\n        buttontext: 'var(--color-button-text)',\n        outlinebuttontext: 'var(--color-outline-button-text)',\n        dashedbuttontext: 'var(--color-dashedbutton-text)',\n        activetext: 'var(--color-active-text)',\n        deactivetext: 'var(--color-deactive-text)',\n        defaultWhite: '#fff',\n        error: 'var(--color-text-error)',\n      },\n      placeholderColor: {\n        primary: 'var(--color-placeholder-primary)',\n      },\n      backgroundColor: {\n        white: 'var(--color-bg-white)',\n        black: 'var(--color-bg-black)',\n        popover: 'var(--color-bg-popover)',\n        body: 'var(--color-bg-body)',\n        overlay: 'rgba(0,0,0,0.73)',\n        activebg: 'var(--color-bg-active)',\n        deactivebg: 'var(--color-bg-deactive)',\n      },\n      backgroundOpacity: {\n        10: '0.1',\n        20: '0.2',\n        95: '0.95',\n      },\n      width: {\n        sidebar: 'var(--sidebar-width)',\n        sidebarRight: 'calc(100% - 55px)',\n        profileSidebar: 'var(--profile-sidebar-width)',\n        profileRight: 'calc(100% - var(--profile-sidebar-width))',\n        28: '7rem',\n        100: '28rem',\n        102: '36rem',\n        4.5: '1.125rem',\n        '1.5/12': '14%',\n        '10.5/12': '86%',\n        '2.5/12': '20%',\n        '9.5/12': '80%',\n        '3.5/12': '20%',\n      },\n      height: {\n        4.5: '1.125rem',\n        110: '30rem',\n        body: 'var(--sidebar-height)',\n      },\n      borderRadius: {\n        3: '3px',\n      },\n      maxHeight: {\n        110: '35rem',\n      },\n      minHeight: {\n        body: 'var(--sidebar-height)',\n        9: '2rem',\n        11: '2.5rem;',\n      },\n      spacing: {\n        dw1: '0.25rem',\n        dw5: '0.313rem',\n      },\n      boxShadow: {\n        dw: 'rgba(0, 0 ,0 , 0.06) 0px 8px 16px 0px',\n        dw1: 'rgba(0 ,0 ,0 , 0.08) 4px -3px 13px 0px',\n        primary: 'var(--box-shadow-primary)',\n      },\n      cursor: {\n        grab: 'grab',\n      },\n      fontSize: {\n        xxs: '.625rem',\n        xs: '.75rem',\n        sm: '.875rem',\n        tiny: '.875rem',\n        base: '1rem',\n        lg: '1.125rem',\n        xl: '1.25rem',\n        '2xl': '1.5rem',\n        '2.5xl': '1.75rem',\n        '3xl': '2rem',\n        '4xl': '2.25rem',\n        '5xl': '3rem',\n        '6xl': '4rem',\n        '7xl': '5rem',\n      },\n      fontWeight: {\n        theme: 'var(--font-theme-DW1)',\n      },\n      lineHeight: {\n        '1xl': '1.75rem',\n        normal: '1.375rem',\n      },\n      inset: {\n        '-0.3': '-3px',\n      },\n      borderWidth: {\n        DEFAULT: '1px',\n        1: '1px',\n        3: '3px',\n      },\n      zIndex: {\n        0: 0,\n        1: 1,\n        10000: 10000,\n        1000000: 1000000,\n      },\n      outline: {\n        none: '0',\n      },\n      fontFamily: {\n        body: ['var(--font-famliy)'],\n        title: ['var(--font-title-famliy)'],\n      },\n      divideColor: ['groupbox-hover'],\n      hidden: ['group-hover'],\n      block: ['group-hover'],\n    },\n  },\n  variants: {},\n  plugins: [],\n};\n"
  },
  {
    "path": "packages/client/tailwind.js",
    "content": "const colors = require('tailwindcss/colors');\n\nmodule.exports = {\n  purge: [],\n  presets: [],\n  darkMode: false, // or 'media' or 'class'\n  theme: {\n    screens: {\n      sm: '640px',\n      md: '768px',\n      lg: '1024px',\n      xl: '1280px',\n      '2xl': '1536px',\n    },\n    colors: {\n      transparent: 'transparent',\n      current: 'currentColor',\n\n      black: colors.black,\n      white: colors.white,\n      gray: colors.coolGray,\n      red: colors.red,\n      yellow: colors.amber,\n      green: colors.emerald,\n      blue: colors.blue,\n      indigo: colors.indigo,\n      purple: colors.violet,\n      pink: colors.pink,\n    },\n    spacing: {\n      px: '1px',\n      0: '0px',\n      0.5: '0.125rem',\n      1: '0.25rem',\n      1.5: '0.375rem',\n      2: '0.5rem',\n      2.5: '0.625rem',\n      3: '0.75rem',\n      3.5: '0.875rem',\n      4: '1rem',\n      5: '1.25rem',\n      6: '1.5rem',\n      7: '1.75rem',\n      8: '2rem',\n      9: '2.25rem',\n      10: '2.5rem',\n      11: '2.75rem',\n      12: '3rem',\n      14: '3.5rem',\n      16: '4rem',\n      20: '5rem',\n      24: '6rem',\n      28: '7rem',\n      32: '8rem',\n      36: '9rem',\n      40: '10rem',\n      44: '11rem',\n      48: '12rem',\n      52: '13rem',\n      56: '14rem',\n      60: '15rem',\n      64: '16rem',\n      72: '18rem',\n      80: '20rem',\n      96: '24rem',\n    },\n    animation: {\n      none: 'none',\n      spin: 'spin 1s linear infinite',\n      ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',\n      pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',\n      bounce: 'bounce 1s infinite',\n    },\n    backgroundColor: (theme) => theme('colors'),\n    backgroundImage: {\n      none: 'none',\n      'gradient-to-t': 'linear-gradient(to top, var(--tw-gradient-stops))',\n      'gradient-to-tr': 'linear-gradient(to top right, var(--tw-gradient-stops))',\n      'gradient-to-r': 'linear-gradient(to right, var(--tw-gradient-stops))',\n      'gradient-to-br': 'linear-gradient(to bottom right, var(--tw-gradient-stops))',\n      'gradient-to-b': 'linear-gradient(to bottom, var(--tw-gradient-stops))',\n      'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))',\n      'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))',\n      'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))',\n    },\n    backgroundOpacity: (theme) => theme('opacity'),\n    backgroundPosition: {\n      bottom: 'bottom',\n      center: 'center',\n      left: 'left',\n      'left-bottom': 'left bottom',\n      'left-top': 'left top',\n      right: 'right',\n      'right-bottom': 'right bottom',\n      'right-top': 'right top',\n      top: 'top',\n    },\n    backgroundSize: {\n      auto: 'auto',\n      cover: 'cover',\n      contain: 'contain',\n    },\n    borderColor: (theme) => ({\n      ...theme('colors'),\n      DEFAULT: theme('colors.gray.200', 'currentColor'),\n    }),\n    borderOpacity: (theme) => theme('opacity'),\n    borderRadius: {\n      none: '0px',\n      sm: '0.125rem',\n      DEFAULT: '0.25rem',\n      md: '0.375rem',\n      lg: '0.5rem',\n      xl: '0.75rem',\n      '2xl': '1rem',\n      '3xl': '1.5rem',\n      full: '9999px',\n    },\n    borderWidth: {\n      DEFAULT: '1px',\n      0: '0px',\n      2: '2px',\n      4: '4px',\n      8: '8px',\n    },\n    boxShadow: {\n      sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n      DEFAULT: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',\n      md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',\n      lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',\n      xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',\n      '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',\n      inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',\n      none: 'none',\n    },\n    container: {},\n    cursor: {\n      auto: 'auto',\n      default: 'default',\n      pointer: 'pointer',\n      wait: 'wait',\n      text: 'text',\n      move: 'move',\n      'not-allowed': 'not-allowed',\n    },\n    divideColor: (theme) => theme('borderColor'),\n    divideOpacity: (theme) => theme('borderOpacity'),\n    divideWidth: (theme) => theme('borderWidth'),\n    fill: { current: 'currentColor' },\n    flex: {\n      1: '1 1 0%',\n      auto: '1 1 auto',\n      initial: '0 1 auto',\n      none: 'none',\n    },\n    flexGrow: {\n      0: '0',\n      DEFAULT: '1',\n    },\n    flexShrink: {\n      0: '0',\n      DEFAULT: '1',\n    },\n    fontFamily: {\n      sans: [\n        'ui-sans-serif',\n        'system-ui',\n        '-apple-system',\n        'BlinkMacSystemFont',\n        '\"Segoe UI\"',\n        'Roboto',\n        '\"Helvetica Neue\"',\n        'Arial',\n        '\"Noto Sans\"',\n        'sans-serif',\n        '\"Apple Color Emoji\"',\n        '\"Segoe UI Emoji\"',\n        '\"Segoe UI Symbol\"',\n        '\"Noto Color Emoji\"',\n      ],\n      serif: ['ui-serif', 'Georgia', 'Cambria', '\"Times New Roman\"', 'Times', 'serif'],\n      mono: [\n        'ui-monospace',\n        'SFMono-Regular',\n        'Menlo',\n        'Monaco',\n        'Consolas',\n        '\"Liberation Mono\"',\n        '\"Courier New\"',\n        'monospace',\n      ],\n    },\n    fontSize: {\n      xs: ['0.75rem', { lineHeight: '1rem' }],\n      sm: ['0.875rem', { lineHeight: '1.25rem' }],\n      base: ['1rem', { lineHeight: '1.5rem' }],\n      lg: ['1.125rem', { lineHeight: '1.75rem' }],\n      xl: ['1.25rem', { lineHeight: '1.75rem' }],\n      '2xl': ['1.5rem', { lineHeight: '2rem' }],\n      '3xl': ['1.875rem', { lineHeight: '2.25rem' }],\n      '4xl': ['2.25rem', { lineHeight: '2.5rem' }],\n      '5xl': ['3rem', { lineHeight: '1' }],\n      '6xl': ['3.75rem', { lineHeight: '1' }],\n      '7xl': ['4.5rem', { lineHeight: '1' }],\n      '8xl': ['6rem', { lineHeight: '1' }],\n      '9xl': ['8rem', { lineHeight: '1' }],\n    },\n    fontWeight: {\n      thin: '100',\n      extralight: '200',\n      light: '300',\n      normal: '400',\n      medium: '500',\n      semibold: '600',\n      bold: '700',\n      extrabold: '800',\n      black: '900',\n    },\n    gap: (theme) => theme('spacing'),\n    gradientColorStops: (theme) => theme('colors'),\n    gridAutoColumns: {\n      auto: 'auto',\n      min: 'min-content',\n      max: 'max-content',\n      fr: 'minmax(0, 1fr)',\n    },\n    gridAutoRows: {\n      auto: 'auto',\n      min: 'min-content',\n      max: 'max-content',\n      fr: 'minmax(0, 1fr)',\n    },\n    gridColumn: {\n      auto: 'auto',\n      'span-1': 'span 1 / span 1',\n      'span-2': 'span 2 / span 2',\n      'span-3': 'span 3 / span 3',\n      'span-4': 'span 4 / span 4',\n      'span-5': 'span 5 / span 5',\n      'span-6': 'span 6 / span 6',\n      'span-7': 'span 7 / span 7',\n      'span-8': 'span 8 / span 8',\n      'span-9': 'span 9 / span 9',\n      'span-10': 'span 10 / span 10',\n      'span-11': 'span 11 / span 11',\n      'span-12': 'span 12 / span 12',\n      'span-full': '1 / -1',\n    },\n    gridColumnEnd: {\n      auto: 'auto',\n      1: '1',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5',\n      6: '6',\n      7: '7',\n      8: '8',\n      9: '9',\n      10: '10',\n      11: '11',\n      12: '12',\n      13: '13',\n    },\n    gridColumnStart: {\n      auto: 'auto',\n      1: '1',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5',\n      6: '6',\n      7: '7',\n      8: '8',\n      9: '9',\n      10: '10',\n      11: '11',\n      12: '12',\n      13: '13',\n    },\n    gridRow: {\n      auto: 'auto',\n      'span-1': 'span 1 / span 1',\n      'span-2': 'span 2 / span 2',\n      'span-3': 'span 3 / span 3',\n      'span-4': 'span 4 / span 4',\n      'span-5': 'span 5 / span 5',\n      'span-6': 'span 6 / span 6',\n      'span-full': '1 / -1',\n    },\n    gridRowStart: {\n      auto: 'auto',\n      1: '1',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5',\n      6: '6',\n      7: '7',\n    },\n    gridRowEnd: {\n      auto: 'auto',\n      1: '1',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5',\n      6: '6',\n      7: '7',\n    },\n    transformOrigin: {\n      center: 'center',\n      top: 'top',\n      'top-right': 'top right',\n      right: 'right',\n      'bottom-right': 'bottom right',\n      bottom: 'bottom',\n      'bottom-left': 'bottom left',\n      left: 'left',\n      'top-left': 'top left',\n    },\n    gridTemplateColumns: {\n      none: 'none',\n      1: 'repeat(1, minmax(0, 1fr))',\n      2: 'repeat(2, minmax(0, 1fr))',\n      3: 'repeat(3, minmax(0, 1fr))',\n      4: 'repeat(4, minmax(0, 1fr))',\n      5: 'repeat(5, minmax(0, 1fr))',\n      6: 'repeat(6, minmax(0, 1fr))',\n      7: 'repeat(7, minmax(0, 1fr))',\n      8: 'repeat(8, minmax(0, 1fr))',\n      9: 'repeat(9, minmax(0, 1fr))',\n      10: 'repeat(10, minmax(0, 1fr))',\n      11: 'repeat(11, minmax(0, 1fr))',\n      12: 'repeat(12, minmax(0, 1fr))',\n    },\n    gridTemplateRows: {\n      none: 'none',\n      1: 'repeat(1, minmax(0, 1fr))',\n      2: 'repeat(2, minmax(0, 1fr))',\n      3: 'repeat(3, minmax(0, 1fr))',\n      4: 'repeat(4, minmax(0, 1fr))',\n      5: 'repeat(5, minmax(0, 1fr))',\n      6: 'repeat(6, minmax(0, 1fr))',\n    },\n    height: (theme) => ({\n      auto: 'auto',\n      ...theme('spacing'),\n      '1/2': '50%',\n      '1/3': '33.333333%',\n      '2/3': '66.666667%',\n      '1/4': '25%',\n      '2/4': '50%',\n      '3/4': '75%',\n      '1/5': '20%',\n      '2/5': '40%',\n      '3/5': '60%',\n      '4/5': '80%',\n      '1/6': '16.666667%',\n      '2/6': '33.333333%',\n      '3/6': '50%',\n      '4/6': '66.666667%',\n      '5/6': '83.333333%',\n      full: '100%',\n      screen: '100vh',\n    }),\n    inset: (theme, { negative }) => ({\n      auto: 'auto',\n      ...theme('spacing'),\n      ...negative(theme('spacing')),\n      '1/2': '50%',\n      '1/3': '33.333333%',\n      '2/3': '66.666667%',\n      '1/4': '25%',\n      '2/4': '50%',\n      '3/4': '75%',\n      full: '100%',\n      '-1/2': '-50%',\n      '-1/3': '-33.333333%',\n      '-2/3': '-66.666667%',\n      '-1/4': '-25%',\n      '-2/4': '-50%',\n      '-3/4': '-75%',\n      '-full': '-100%',\n    }),\n    keyframes: {\n      spin: {\n        to: {\n          transform: 'rotate(360deg)',\n        },\n      },\n      ping: {\n        '75%, 100%': {\n          transform: 'scale(2)',\n          opacity: '0',\n        },\n      },\n      pulse: {\n        '50%': {\n          opacity: '.5',\n        },\n      },\n      bounce: {\n        '0%, 100%': {\n          transform: 'translateY(-25%)',\n          animationTimingFunction: 'cubic-bezier(0.8,0,1,1)',\n        },\n        '50%': {\n          transform: 'none',\n          animationTimingFunction: 'cubic-bezier(0,0,0.2,1)',\n        },\n      },\n    },\n    letterSpacing: {\n      tighter: '-0.05em',\n      tight: '-0.025em',\n      normal: '0em',\n      wide: '0.025em',\n      wider: '0.05em',\n      widest: '0.1em',\n    },\n    lineHeight: {\n      none: '1',\n      tight: '1.25',\n      snug: '1.375',\n      normal: '1.5',\n      relaxed: '1.625',\n      loose: '2',\n      3: '.75rem',\n      4: '1rem',\n      5: '1.25rem',\n      6: '1.5rem',\n      7: '1.75rem',\n      8: '2rem',\n      9: '2.25rem',\n      10: '2.5rem',\n    },\n    listStyleType: {\n      none: 'none',\n      disc: 'disc',\n      decimal: 'decimal',\n    },\n    margin: (theme, { negative }) => ({\n      auto: 'auto',\n      ...theme('spacing'),\n      ...negative(theme('spacing')),\n    }),\n    maxHeight: (theme) => ({\n      ...theme('spacing'),\n      full: '100%',\n      screen: '100vh',\n    }),\n    maxWidth: (theme, { breakpoints }) => ({\n      none: 'none',\n      0: '0rem',\n      xs: '20rem',\n      sm: '24rem',\n      md: '28rem',\n      lg: '32rem',\n      xl: '36rem',\n      '2xl': '42rem',\n      '3xl': '48rem',\n      '4xl': '56rem',\n      '5xl': '64rem',\n      '6xl': '72rem',\n      '7xl': '80rem',\n      full: '100%',\n      min: 'min-content',\n      max: 'max-content',\n      prose: '65ch',\n      ...breakpoints(theme('screens')),\n    }),\n    minHeight: {\n      0: '0px',\n      full: '100%',\n      screen: '100vh',\n    },\n    minWidth: {\n      0: '0px',\n      full: '100%',\n      min: 'min-content',\n      max: 'max-content',\n    },\n    objectPosition: {\n      bottom: 'bottom',\n      center: 'center',\n      left: 'left',\n      'left-bottom': 'left bottom',\n      'left-top': 'left top',\n      right: 'right',\n      'right-bottom': 'right bottom',\n      'right-top': 'right top',\n      top: 'top',\n    },\n    opacity: {\n      0: '0',\n      5: '0.05',\n      10: '0.1',\n      20: '0.2',\n      25: '0.25',\n      30: '0.3',\n      40: '0.4',\n      50: '0.5',\n      60: '0.6',\n      70: '0.7',\n      75: '0.75',\n      80: '0.8',\n      90: '0.9',\n      95: '0.95',\n      100: '1',\n    },\n    order: {\n      first: '-9999',\n      last: '9999',\n      none: '0',\n      1: '1',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5',\n      6: '6',\n      7: '7',\n      8: '8',\n      9: '9',\n      10: '10',\n      11: '11',\n      12: '12',\n    },\n    outline: {\n      none: ['2px solid transparent', '2px'],\n      white: ['2px dotted white', '2px'],\n      black: ['2px dotted black', '2px'],\n    },\n    padding: (theme) => theme('spacing'),\n    placeholderColor: (theme) => theme('colors'),\n    placeholderOpacity: (theme) => theme('opacity'),\n    ringColor: (theme) => ({\n      DEFAULT: theme('colors.blue.500', '#3b82f6'),\n      ...theme('colors'),\n    }),\n    ringOffsetColor: (theme) => theme('colors'),\n    ringOffsetWidth: {\n      0: '0px',\n      1: '1px',\n      2: '2px',\n      4: '4px',\n      8: '8px',\n    },\n    ringOpacity: (theme) => ({\n      DEFAULT: '0.5',\n      ...theme('opacity'),\n    }),\n    ringWidth: {\n      DEFAULT: '3px',\n      0: '0px',\n      1: '1px',\n      2: '2px',\n      4: '4px',\n      8: '8px',\n    },\n    rotate: {\n      '-180': '-180deg',\n      '-90': '-90deg',\n      '-45': '-45deg',\n      '-12': '-12deg',\n      '-6': '-6deg',\n      '-3': '-3deg',\n      '-2': '-2deg',\n      '-1': '-1deg',\n      0: '0deg',\n      1: '1deg',\n      2: '2deg',\n      3: '3deg',\n      6: '6deg',\n      12: '12deg',\n      45: '45deg',\n      90: '90deg',\n      180: '180deg',\n    },\n    scale: {\n      0: '0',\n      50: '.5',\n      75: '.75',\n      90: '.9',\n      95: '.95',\n      100: '1',\n      105: '1.05',\n      110: '1.1',\n      125: '1.25',\n      150: '1.5',\n    },\n    skew: {\n      '-12': '-12deg',\n      '-6': '-6deg',\n      '-3': '-3deg',\n      '-2': '-2deg',\n      '-1': '-1deg',\n      0: '0deg',\n      1: '1deg',\n      2: '2deg',\n      3: '3deg',\n      6: '6deg',\n      12: '12deg',\n    },\n    space: (theme, { negative }) => ({\n      ...theme('spacing'),\n      ...negative(theme('spacing')),\n    }),\n    stroke: {\n      current: 'currentColor',\n    },\n    strokeWidth: {\n      0: '0',\n      1: '1',\n      2: '2',\n    },\n    textColor: (theme) => theme('colors'),\n    textOpacity: (theme) => theme('opacity'),\n    transitionDuration: {\n      DEFAULT: '150ms',\n      75: '75ms',\n      100: '100ms',\n      150: '150ms',\n      200: '200ms',\n      300: '300ms',\n      500: '500ms',\n      700: '700ms',\n      1000: '1000ms',\n    },\n    transitionDelay: {\n      75: '75ms',\n      100: '100ms',\n      150: '150ms',\n      200: '200ms',\n      300: '300ms',\n      500: '500ms',\n      700: '700ms',\n      1000: '1000ms',\n    },\n    transitionProperty: {\n      none: 'none',\n      all: 'all',\n      DEFAULT: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',\n      colors: 'background-color, border-color, color, fill, stroke',\n      opacity: 'opacity',\n      shadow: 'box-shadow',\n      transform: 'transform',\n    },\n    transitionTimingFunction: {\n      DEFAULT: 'cubic-bezier(0.4, 0, 0.2, 1)',\n      linear: 'linear',\n      in: 'cubic-bezier(0.4, 0, 1, 1)',\n      out: 'cubic-bezier(0, 0, 0.2, 1)',\n      'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',\n    },\n    translate: (theme, { negative }) => ({\n      ...theme('spacing'),\n      ...negative(theme('spacing')),\n      '1/2': '50%',\n      '1/3': '33.333333%',\n      '2/3': '66.666667%',\n      '1/4': '25%',\n      '2/4': '50%',\n      '3/4': '75%',\n      full: '100%',\n      '-1/2': '-50%',\n      '-1/3': '-33.333333%',\n      '-2/3': '-66.666667%',\n      '-1/4': '-25%',\n      '-2/4': '-50%',\n      '-3/4': '-75%',\n      '-full': '-100%',\n    }),\n    width: (theme) => ({\n      auto: 'auto',\n      ...theme('spacing'),\n      '1/2': '50%',\n      '1/3': '33.333333%',\n      '2/3': '66.666667%',\n      '1/4': '25%',\n      '2/4': '50%',\n      '3/4': '75%',\n      '1/5': '20%',\n      '2/5': '40%',\n      '3/5': '60%',\n      '4/5': '80%',\n      '1/6': '16.666667%',\n      '2/6': '33.333333%',\n      '3/6': '50%',\n      '4/6': '66.666667%',\n      '5/6': '83.333333%',\n      '1/12': '8.333333%',\n      '2/12': '16.666667%',\n      '3/12': '25%',\n      '4/12': '33.333333%',\n      '5/12': '41.666667%',\n      '6/12': '50%',\n      '7/12': '58.333333%',\n      '8/12': '66.666667%',\n      '9/12': '75%',\n      '10/12': '83.333333%',\n      '11/12': '91.666667%',\n      full: '100%',\n      screen: '100vw',\n      min: 'min-content',\n      max: 'max-content',\n    }),\n    zIndex: {\n      auto: 'auto',\n      0: '0',\n      10: '10',\n      20: '20',\n      30: '30',\n      40: '40',\n      50: '50',\n    },\n  },\n  variantOrder: [\n    'first',\n    'last',\n    'odd',\n    'even',\n    'visited',\n    'checked',\n    'group-hover',\n    'group-focus',\n    'focus-within',\n    'hover',\n    'focus',\n    'focus-visible',\n    'active',\n    'disabled',\n  ],\n  variants: {\n    accessibility: ['responsive', 'focus-within', 'focus'],\n    alignContent: ['responsive'],\n    alignItems: ['responsive'],\n    alignSelf: ['responsive'],\n    animation: ['responsive'],\n    appearance: ['responsive'],\n    backgroundAttachment: ['responsive'],\n    backgroundClip: ['responsive'],\n    backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],\n    backgroundImage: ['responsive'],\n    backgroundOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    backgroundPosition: ['responsive'],\n    backgroundRepeat: ['responsive'],\n    backgroundSize: ['responsive'],\n    borderCollapse: ['responsive'],\n    borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],\n    borderOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    borderRadius: ['responsive'],\n    borderStyle: ['responsive'],\n    borderWidth: ['responsive'],\n    boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    boxSizing: ['responsive'],\n    clear: ['responsive'],\n    container: ['responsive'],\n    cursor: ['responsive'],\n    display: ['responsive'],\n    divideColor: ['responsive', 'dark'],\n    divideOpacity: ['responsive'],\n    divideStyle: ['responsive'],\n    divideWidth: ['responsive'],\n    fill: ['responsive'],\n    flex: ['responsive'],\n    flexDirection: ['responsive'],\n    flexGrow: ['responsive'],\n    flexShrink: ['responsive'],\n    flexWrap: ['responsive'],\n    float: ['responsive'],\n    fontFamily: ['responsive'],\n    fontSize: ['responsive'],\n    fontSmoothing: ['responsive'],\n    fontStyle: ['responsive'],\n    fontVariantNumeric: ['responsive'],\n    fontWeight: ['responsive'],\n    gap: ['responsive'],\n    gradientColorStops: ['responsive', 'dark', 'hover', 'focus'],\n    gridAutoColumns: ['responsive'],\n    gridAutoFlow: ['responsive'],\n    gridAutoRows: ['responsive'],\n    gridColumn: ['responsive'],\n    gridColumnEnd: ['responsive'],\n    gridColumnStart: ['responsive'],\n    gridRow: ['responsive'],\n    gridRowEnd: ['responsive'],\n    gridRowStart: ['responsive'],\n    gridTemplateColumns: ['responsive'],\n    gridTemplateRows: ['responsive'],\n    height: ['responsive'],\n    inset: ['responsive'],\n    justifyContent: ['responsive'],\n    justifyItems: ['responsive'],\n    justifySelf: ['responsive'],\n    letterSpacing: ['responsive'],\n    lineHeight: ['responsive'],\n    listStylePosition: ['responsive'],\n    listStyleType: ['responsive'],\n    margin: ['responsive'],\n    maxHeight: ['responsive'],\n    maxWidth: ['responsive'],\n    minHeight: ['responsive'],\n    minWidth: ['responsive'],\n    objectFit: ['responsive'],\n    objectPosition: ['responsive'],\n    opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    order: ['responsive'],\n    outline: ['responsive', 'focus-within', 'focus'],\n    overflow: ['responsive'],\n    overscrollBehavior: ['responsive'],\n    padding: ['responsive'],\n    placeContent: ['responsive'],\n    placeItems: ['responsive'],\n    placeSelf: ['responsive'],\n    placeholderColor: ['responsive', 'dark', 'focus'],\n    placeholderOpacity: ['responsive', 'focus'],\n    pointerEvents: ['responsive'],\n    position: ['responsive'],\n    resize: ['responsive'],\n    ringColor: ['responsive', 'dark', 'focus-within', 'focus'],\n    ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'],\n    ringOffsetWidth: ['responsive', 'focus-within', 'focus'],\n    ringOpacity: ['responsive', 'focus-within', 'focus'],\n    ringWidth: ['responsive', 'focus-within', 'focus'],\n    rotate: ['responsive', 'hover', 'focus'],\n    scale: ['responsive', 'hover', 'focus'],\n    skew: ['responsive', 'hover', 'focus'],\n    space: ['responsive'],\n    stroke: ['responsive'],\n    strokeWidth: ['responsive'],\n    tableLayout: ['responsive'],\n    textAlign: ['responsive'],\n    textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'],\n    textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    textOpacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'],\n    textOverflow: ['responsive'],\n    textTransform: ['responsive'],\n    transform: ['responsive'],\n    transformOrigin: ['responsive'],\n    transitionDelay: ['responsive'],\n    transitionDuration: ['responsive'],\n    transitionProperty: ['responsive'],\n    transitionTimingFunction: ['responsive'],\n    translate: ['responsive', 'hover', 'focus'],\n    userSelect: ['responsive'],\n    verticalAlign: ['responsive'],\n    visibility: ['responsive'],\n    whitespace: ['responsive'],\n    width: ['responsive'],\n    wordBreak: ['responsive'],\n    zIndex: ['responsive', 'focus-within', 'focus'],\n  },\n  plugins: [],\n};\n"
  },
  {
    "path": "packages/server/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  extends: [\n    'airbnb-base',\n  ],\n  parserOptions: {\n    ecmaVersion: 12,\n    sourceType: 'module',\n  },\n  rules: {\n    semi: ['error', 'always'],\n    indent: ['error', 2],\n    'no-multi-spaces': ['error'],\n    'no-irregular-whitespace': ['error', {\n      skipStrings: true,\n      skipComments: true,\n      skipRegExps: true,\n      skipTemplates: true,\n    }],\n    'multiline-comment-style': ['error', 'starred-block'],\n    'object-property-newline': ['error', {\n      allowAllPropertiesOnSameLine: false,\n      allowMultiplePropertiesPerLine: false,\n    }],\n    'object-curly-newline': ['error', {\n      minProperties: 2,\n      multiline: true,\n    }],\n    'no-multiple-empty-lines': ['error', {\n      max: 1,\n      maxEOF: 0,\n    }],\n    'no-param-reassign': 'off',\n    'no-underscore-dangle': 'off',\n    'class-methods-use-this': 'off',\n    'max-len': [2, {\n      code: 1000,\n      ignorePattern: '^import .*',\n    }],\n    'space-infix-ops': ['error', { int32Hint: false }],\n    'space-before-function-paren': ['error', {\n      anonymous: 'always',\n      named: 'always',\n      asyncArrow: 'always',\n    }],\n    'keyword-spacing': ['error', {\n      before: true,\n      after: true,\n    }],\n    'object-curly-spacing': ['error', 'always'],\n    quotes: ['error', 'single'],\n  },\n};\n"
  },
  {
    "path": "packages/server/.gitignore",
    "content": "config/database\ninput \noutput"
  },
  {
    "path": "packages/server/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.3.1](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.3.0...v1.3.1) (2022-09-28)\n\n\n### Bug Fixes\n\n* **server:** missing constant ([eeccc59](https://github.com/DhiWise/dhiwise-nodejs/commit/eeccc59c8890d3f43ff6e36d243659c27158f7f8))\n\n\n\n\n\n# [1.3.0](https://github.com/DhiWise/dhiwise-nodejs/compare/v1.2.0...v1.3.0) (2022-04-25)\n\n\n### Bug Fixes\n\n* **Clean Code Sequelize:** bug Fixes for Clean code sequelize ([fc7ba02](https://github.com/DhiWise/dhiwise-nodejs/commit/fc7ba024dae562f758f89dac6fada9bf04d52809))\n* **clean-code:** ejs variable updated ([44f91af](https://github.com/DhiWise/dhiwise-nodejs/commit/44f91afd4bd249d2ae528acd1b56a7e2909e02b4))\n* **eslint fixes:** eslint rules violation removed ([7682a2a](https://github.com/DhiWise/dhiwise-nodejs/commit/7682a2af8031955655e5c943be580fb18f2cce5a))\n* **file upload in cc:** fix file upload in controller of cc ([387562a](https://github.com/DhiWise/dhiwise-nodejs/commit/387562a1b9ecc6636200c6c9fb7d56451a0c5878))\n* **file-upload-cc:** steps added ([f06995e](https://github.com/DhiWise/dhiwise-nodejs/commit/f06995e53f9eb75c63bc54da5f61b9e7d3e5bdb0))\n* **minor bug fixes:** - ([876f01a](https://github.com/DhiWise/dhiwise-nodejs/commit/876f01aea94c8f803030554fd123c9aa4654555b))\n\n\n### Features\n\n* **Clean-code file uplaod:** file upload use-cases added for clean-code architecture ([af56105](https://github.com/DhiWise/dhiwise-nodejs/commit/af5610501d7d98897ab02115873c76ee9f75b4bc))\n* **Clean-code mongoose:** comments added ([c6b432c](https://github.com/DhiWise/dhiwise-nodejs/commit/c6b432cf69dbe0ff58745f554af92e9d04129473))\n* **server:** custom routes with query builder for mvc architecture ([6949d44](https://github.com/DhiWise/dhiwise-nodejs/commit/6949d441687cdb2a23b76f580a0b88f408663678))\n\n\n\n\n\n# [1.2.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.1.0...v1.2.0) (2022-02-02)\n\n\n### Bug Fixes\n\n* **bug fixes and code enhancement:** fixed some issues ([501675e](https://github.com/DhiWise/nodejs-code-generator/commit/501675e7f528d79a5cb4e84c5d24a4562e74fe2d))\n\n\n### Features\n\n* **custom routes in clean-code architecture with use case:** custom routes with query builder added ([f38092d](https://github.com/DhiWise/nodejs-code-generator/commit/f38092d1790f21a562403a6c1638245c846665ee))\n* **use-case added in clean code architecture:** a service layer in clean code architecture ([e7cbfc4](https://github.com/DhiWise/nodejs-code-generator/commit/e7cbfc4f15956d7b2343eb6275fcea6beaf0fa40))\n\n\n\n\n\n# [1.1.0](https://github.com/DhiWise/nodejs-code-generator/compare/v1.0.0...v1.1.0) (2022-01-11)\n\n\n### Bug Fixes\n\n* **eslint formatting:** resolved eslint errors ([2c71bf2](https://github.com/DhiWise/nodejs-code-generator/commit/2c71bf2661c5e1599de3cb242b5431dce8720137))\n"
  },
  {
    "path": "packages/server/README.md",
    "content": "# Server\n\nTo run: ```node app```\n\n## About\n\nBackend Service wil run on 3053 Port.\n\nThis backend service is used to store input to generate the code. Using the front-end You can add your custom Inputs and code will be generated According to your inputs.\n\n- For Data Store, Memory-Db with Mongoose ORM is used.\n\n- Eslint rules are used in Server as well as in Generated code.\n\n- When you will call the generate api it will store the input file inside the input folder (server -> input) and code will be generated inside the output folder (server -> output).\n\n## Folder Structure\n\n```\n  ├── app.js       - starting point of the application\n  ├── assets\n  ├── config\n  │   ├── db.js    - contains api database connection\n  ├── constants    - contains commonly used constants \n  ├── controllers               \n  │   ├── web      - contains usecases call with dependency injection\n  ├── models       - models of application\n  ├── output       - generated code\n  ├── repo         - classes of models\n  ├── responses \n  ├── routes       - contains all the routes of application\n  ├── usecase      - contains business logic\n  └── util-service - conatins utility functions     \n  ```\n\n  - You can find the readme of generated code inside the generated code folder.\n"
  },
  {
    "path": "packages/server/__test__/application.test.js",
    "content": "/* eslint-disable no-undef */\nconst request = require('supertest');\n\nprocess.env.NODE_ENV = 'test';\nconst app = require('../app');\n\njest.setTimeout(50000);\n\ntest('should create a new application and generate a project with default setting', async () => {\n  const createdApp = await request(app)\n    .post('/web/v1/application/create')\n    .send({\n      name: 'App1',\n      configInput: {\n        port: '5000',\n        databaseName: 'node_demo',\n        isAuthentication: true,\n      },\n      stepInput: {\n        ormType: 1,\n        databaseType: 1,\n      },\n      authModel: 1,\n      projectId: null,\n      definitionId: null,\n      projectDefinitionCode: 'NODE_EXPRESS',\n    });\n  expect(createdApp.headers['content-type']).toEqual('application/json; charset=utf-8');\n  expect(createdApp.statusCode).toBe(200);\n  expect(createdApp.body.status).toBe(200);\n  const generatedApp = await request(app)\n    .post('/web/v1/application/generate')\n    .send({\n      applicationId: createdApp.body.data._id,\n      projectType: 'MVC',\n    });\n  expect(generatedApp.statusCode).toBe(200);\n  expect(generatedApp.body.status).toBe(200);\n});\n"
  },
  {
    "path": "packages/server/app.js",
    "content": "global._ = require('lodash');\nconst express = require('express');\nconst logger = require('morgan');\nglobal.message = require('./models/constants/message');\n\nglobal.MESSAGE = require('./models/constants/message').MESSAGE;\nglobal.COMMON_CONSTANTS = require('./models/constants/common');\n\nglobal.__appRootDir = __dirname;\nconst cors = require('cors');\nconst compression = require('compression');\nrequire('./config/db');\n\nrequire('./models');\nrequire('events').EventEmitter.defaultMaxListeners = 0;\n\nglobal.appRootPath = __dirname;\n\nconst {\n  ok, badRequest, serverError, forbidden, unauthorized, notFound, setResponse,\n} = require('./responses');\n\nconst PORT = 3053;\nconst HOST = 'localhost';\n\nconst app = express();\n\n// Response compression using `gzip`.\napp.use(compression({\n  level: 6,\n  threshold: 0,\n  filter: (req, res) => {\n    if (req.headers['x-no-compression']) {\n      return false;\n    }\n    return compression.filter(req, res);\n  },\n}));\n\napp.use(cors());\napp.use(express.json({ limit: '50mb' }));\n\napp.use(express.static(`${__dirname}/uploads`));\napp.use('/uploads', express.static(`${__dirname}/uploads`));\n\napp.use((req, res, next) => {\n  res.ok = (body) => {\n    ok(res, body);\n  };\n  res.badRequest = (body) => {\n    badRequest(res, body);\n  };\n  res.serverError = (body) => {\n    serverError(res, body);\n  };\n  res.forbidden = (body) => {\n    forbidden(res, body);\n  };\n  res.unauthorized = (body) => {\n    unauthorized(res, body);\n  };\n  res.notFound = (body) => {\n    notFound(res, body);\n  };\n  res.setResponse = (body) => {\n    setResponse(res, body);\n  };\n  next();\n});\n\napp.use(logger('dev'));\n// routes\nconst routes = require('./routes');\n\napp.use(routes);\n\nif (process.env.NODE_ENV === 'test') {\n  module.exports = app;\n} else {\n  // listen for requests\n  app.listen(PORT, HOST, () => {\n    console.log(`Server is listening on port ${HOST}:${PORT}`);\n  });\n}\n"
  },
  {
    "path": "packages/server/assets/master.js",
    "content": "module.exports = {\n  masterData: [\n    {\n      _id: '605428a436854e2d85821db5',\n      name: 'Designation',\n      code: 'DESIGNATION',\n      isActive: true,\n      isDefault: false,\n      image: '',\n      description: '',\n    },\n    {\n      _id: '60545ac536854e2d85821db6',\n      name: 'Project manager',\n      code: 'PROJECT_MANAGER',\n      isActive: true,\n      isDefault: false,\n      image: '',\n      description: '',\n      parentId: '605428a436854e2d85821db5',\n      parentCode: 'DESIGNATION',\n    },\n    {\n      _id: '608cdc5fcfb64d3ffd8c96cb',\n      name: 'Github',\n      code: 'GITHUB',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '608cdb63cfb64d3ffd8c96c7',\n      parentCode: 'SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'callbackUrl',\n          displayName: 'Callback url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/github/callback',\n        },\n        {\n          fieldName: 'errorUrl',\n          displayName: 'Error url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/github/error',\n        },\n      ],\n    },\n    {\n      _id: '608cdc5fcfb64d3ffd8c96ca',\n      name: 'Linkedin',\n      code: 'LINKEDIN',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '608cdb63cfb64d3ffd8c96c7',\n      parentCode: 'SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'callbackUrl',\n          displayName: 'Callback url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/linkedin/callback',\n        },\n        {\n          fieldName: 'errorUrl',\n          displayName: 'Error url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/linkedin/error',\n        },\n      ],\n    },\n    {\n      _id: '608cdc5fcfb64d3ffd8c96c9',\n      name: 'Google',\n      code: 'GOOGLE',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '608cdb63cfb64d3ffd8c96c7',\n      parentCode: 'SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'callbackUrl',\n          displayName: 'Callback url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/google/callback',\n        },\n        {\n          fieldName: 'errorUrl',\n          displayName: 'Error url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/google/error',\n        },\n      ],\n    },\n    {\n      _id: '608cdb63cfb64d3ffd8c96c7',\n      name: 'Social auth',\n      code: 'SOCIAL_AUTH',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n    },\n    {\n      _id: '608a443ad126c49dbdd2eacd',\n      name: 'AWS',\n      code: 'AWS_EMAIL',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '60867d62ebfd00625f9c68b6',\n      parentCode: 'EMAIL',\n      customJson: [\n        {\n          displayName: 'Access key ID',\n          fieldName: 'accessKeyId',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Secret access key',\n          fieldName: 'secretAccessKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Region',\n          fieldName: 'region',\n          inputType: 'text',\n          isRequired: true,\n        },\n        {\n          displayName: 'Registered email',\n          fieldName: 'registeredEmail',\n          inputType: 'text',\n          pattern: 'email',\n          isRequired: true,\n        },\n      ],\n    },\n    {\n      _id: '608959db31997257c9239f6e',\n      name: 'Admin',\n      code: 'ADMIN',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'admin' },\n      parentCode: 'USER_ROLES',\n      parentId: '6089532431997257c923893e',\n    },\n    {\n      _id: '608959c631997257c9239f2f',\n      name: 'Guest',\n      code: 'GUEST',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'guest' },\n      parentCode: 'USER_ROLES',\n      parentId: '6089532431997257c923893e',\n    },\n    {\n      _id: '608959ab31997257c9239ece',\n      name: 'Developer',\n      code: 'DEVELOPER',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'developer' },\n      parentCode: 'USER_ROLES',\n      parentId: '6089532431997257c923893e',\n    },\n    {\n      _id: '6089594f31997257c9239d68',\n      name: 'Maintainer',\n      code: 'MAINTAINER',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'maintainer' },\n      parentCode: 'USER_ROLES',\n      parentId: '6089532431997257c923893e',\n    },\n    {\n      _id: '6089592b31997257c9239ced',\n      name: 'Owner',\n      code: 'OWNER',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'owner' },\n      parentCode: 'USER_ROLES',\n      parentId: '6089532431997257c923893e',\n    },\n    {\n      _id: '6089532431997257c923893e',\n      name: 'User roles',\n      code: 'USER_ROLES',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n    },\n    {\n      _id: '6086b45cebfd00625f9c68ba',\n      name: 'Notification',\n      code: 'NOTIFICATION',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n    },\n    {\n      _id: '60868da2f4e4425c2fc9a50c',\n      likeKeyWords: [],\n      parentId: null,\n      isDeleted: false,\n      isActive: true,\n      name: 'abc',\n      code: 'ABC',\n      parentCode: 'TEST1',\n      customJson: [\n        {\n          fieldName: 'clientId',\n          inputType: 'text',\n        },\n        {\n          fieldName: 'clientSecret',\n          inputType: 'text',\n        },\n      ],\n      addedBy: '6076d3e8b748740014be63dc',\n      createdAt: '2021-04-26T09:53:38.397Z',\n      updatedAt: '2021-04-26T09:53:38.397Z',\n      slug: 'abc',\n      __v: 0.0,\n    },\n    {\n      _id: '60867debebfd00625f9c68b9',\n      name: 'Gupshup',\n      code: 'GUPSHUP_SMS',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: [\n        {\n          fieldName: 'clientId',\n          displayName: 'Client ID',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          fieldName: 'clientSecret',\n          displayName: 'Client secret',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n      parentId: '60867d6bebfd00625f9c68b7',\n      parentCode: 'SMS',\n    },\n    {\n      _id: '60867dd3ebfd00625f9c68b8',\n      name: 'Mailgun',\n      code: 'MAILGUN_EMAIL',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '60867d62ebfd00625f9c68b6',\n      parentCode: 'EMAIL',\n      customJson: [\n        {\n          fieldName: 'username',\n          displayName: 'Username',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          fieldName: 'password',\n          displayName: 'Password',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n    },\n    {\n      _id: '60867d6bebfd00625f9c68b7',\n      name: 'SMS',\n      code: 'SMS',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      customJson: { fieldName: 'sms' },\n      parentCode: 'NOTIFICATION',\n      parentId: '6086b45cebfd00625f9c68ba',\n    },\n    {\n      _id: '60867d62ebfd00625f9c68b6',\n      name: 'Email',\n      code: 'EMAIL',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '6086b45cebfd00625f9c68ba',\n      parentCode: 'NOTIFICATION',\n      customJson: { fieldName: 'email' },\n    },\n    {\n      _id: '60dd550c32bf43744dc51cb2',\n      name: 'Instagram',\n      code: 'INSTAGRAM',\n      isActive: true,\n      isDefault: false,\n      isDeleted: true,\n      image: '',\n      description: '',\n      parentId: '60dd529532bf43744dc51cad',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'isInstagram',\n          displayName: 'Instagram',\n          inputType: 'checkbox',\n        },\n      ],\n    },\n    {\n      _id: '60dd550c32bf43744dc51cb1',\n      name: 'LinkedIn',\n      code: 'LINKEDIN',\n      isActive: true,\n      isDefault: false,\n      isDeleted: true,\n      image: '',\n      description: '',\n      parentId: '60dd529532bf43744dc51cad',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'isLinkedin',\n          displayName: 'Client ID',\n          inputType: 'checkbox',\n        },\n      ],\n    },\n    {\n      _id: '60dd550c32bf43744dc51cb0',\n      name: 'Google',\n      code: 'GOOGLE',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '60dd529532bf43744dc51cad',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'isGoogle',\n          displayName: 'Google',\n          inputType: 'checkbox',\n        },\n      ],\n    },\n    {\n      _id: '60dd550c32bf43744dc51caf',\n      name: 'Facebook',\n      code: 'FACEBOOK',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '60dd529532bf43744dc51cad',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'isFacebook',\n          displayName: 'Facebook',\n          inputType: 'checkbox',\n        },\n      ],\n    },\n    {\n      _id: '60dd529532bf43744dc51cad',\n      name: 'Social auth',\n      code: 'ANDROID_SOCIAL_AUTH',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n    },\n    {\n      _id: '60ed0a018b8bcb298fa88c0a',\n      name: 'Facebook',\n      code: 'FACEBOOK',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '608cdb63cfb64d3ffd8c96c7',\n      parentCode: 'SOCIAL_AUTH',\n      customJson: [\n        {\n          fieldName: 'callbackUrl',\n          displayName: 'Callback url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/facebook/callback',\n        },\n        {\n          fieldName: 'errorUrl',\n          displayName: 'Error url',\n          pattern: 'url',\n          inputType: 'text',\n          isRequired: true,\n          defaultUrl: '/auth/facebook/error',\n        },\n      ],\n    },\n    {\n      _id: '6131bc6ea330ee35e0ebca6e',\n      code: 'GOOGLE_PUSH_NOTIFICATION',\n      customJson: [\n        {\n          displayName: 'App ID',\n          fieldName: 'app_id',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'API key',\n          fieldName: 'api_key',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Registration Token',\n          fieldName: 'registrationToken',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Database URL',\n          fieldName: 'databaseURL',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Project ID',\n          fieldName: 'projectId',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Client Email',\n          fieldName: 'clientEmail',\n          inputType: 'text',\n          pattern: 'email',\n          isRequired: true,\n        },\n        {\n          displayName: 'Private Key',\n          fieldName: 'privateKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'Google',\n      parentCode: 'PUSH_NOTIFICATION',\n      parentId: '6130ba00e02284725258b788',\n    },\n    {\n      _id: '6131bbb6a330ee35e0ebca6d',\n      code: 'ONE_SIGNAL_PUSH_NOTIFICATION',\n      customJson: [\n        {\n          displayName: 'App ID',\n          fieldName: 'app_id',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'API key',\n          fieldName: 'api_key',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'One signal',\n      parentCode: 'PUSH_NOTIFICATION',\n      parentId: '6130ba00e02284725258b788',\n    },\n    {\n      _id: '6131bb49a330ee35e0ebca6c',\n      code: 'AWS_SNS_PUSH_NOTIFICATION',\n      customJson: [\n        {\n          displayName: 'App ID',\n          fieldName: 'app_id',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Key',\n          fieldName: 'key',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Access key',\n          fieldName: 'accessKeyId',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Secret access Key',\n          fieldName: 'secretAccessKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Region',\n          fieldName: 'region',\n          inputType: 'text',\n          isRequired: true,\n        },\n        {\n          displayName: 'ARN',\n          fieldName: 'arn',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'AWS SNS',\n      parentCode: 'PUSH_NOTIFICATION',\n      parentId: '6130ba00e02284725258b788',\n    },\n    {\n      _id: '6131b6ada330ee35e0ebca6b',\n      code: 'AWS_SNS_SMS',\n      customJson: [\n        {\n          displayName: 'AccessKey key',\n          fieldName: 'accessKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Secret Key',\n          fieldName: 'secretKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Region',\n          fieldName: 'region',\n          inputType: 'text',\n          isRequired: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'AWS SNS',\n      parentCode: 'SMS',\n      parentId: '60867d6bebfd00625f9c68b7',\n    },\n    {\n      _id: '6131b667a330ee35e0ebca6a',\n      code: 'TWILIO_SMS',\n      customJson: [\n        {\n          displayName: 'Account SID',\n          fieldName: 'accountSid',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Auth Token',\n          fieldName: 'authToken',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'Messaging service sid',\n          fieldName: 'messagingServiceSid',\n          inputType: 'text',\n          isRequired: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'Twilio',\n      parentCode: 'SMS',\n      parentId: '60867d6bebfd00625f9c68b7',\n    },\n    {\n      _id: '6131b5dea330ee35e0ebca69',\n      code: 'NEXMO_SMS',\n      customJson: [\n        {\n          displayName: 'API key',\n          fieldName: 'apiKey',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          displayName: 'API secret',\n          fieldName: 'apiSecret',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'Nexmo',\n      parentCode: 'SMS',\n      parentId: '60867d6bebfd00625f9c68b7',\n    },\n    {\n      _id: '6130ba00e02284725258b788',\n      code: 'PUSH_NOTIFICATION',\n      customJson: { fieldName: 'pushNotification' },\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      name: 'Push notification',\n      parentCode: 'NOTIFICATION',\n      parentId: '6086b45cebfd00625f9c68ba',\n    },\n    {\n      _id: '60c47896ecbdb87e93b4faf3',\n      code: 'INSTAGRAM',\n      customJson: [\n        {\n          displayName: 'Instagram',\n          fieldName: 'isInstagram',\n          inputType: 'checkbox',\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: true,\n      name: 'Instagram',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      parentId: '60c47455ecbdb87e93b4faef',\n    },\n    {\n      _id: '60c47896ecbdb87e93b4faf2',\n      code: 'LINKEDIN',\n      customJson: [\n        {\n          displayName: 'LinkedIn',\n          fieldName: 'isLinkedin',\n          inputType: 'checkbox',\n        },\n      ],\n      description: '',\n      image: '',\n      isActive: true,\n      isDefault: false,\n      isDeleted: true,\n      name: 'LinkedIn',\n      parentCode: 'ANDROID_SOCIAL_AUTH',\n      parentId: '60c47455ecbdb87e93b4faef',\n    },\n    {\n      _id: '6138bdfdf84b7f60093adf9f',\n      name: 'Sandgrid',\n      code: 'SANDGRID_EMAIL',\n      isActive: true,\n      isDefault: false,\n      isDeleted: false,\n      image: '',\n      description: '',\n      parentId: '60867d62ebfd00625f9c68b6',\n      parentCode: 'EMAIL',\n      customJson: [\n        {\n          fieldName: 'username',\n          displayName: 'Username',\n          inputType: 'text',\n          isHidden: true,\n        },\n        {\n          fieldName: 'password',\n          displayName: 'Password',\n          inputType: 'text',\n          isHidden: true,\n        },\n      ],\n    },\n  ],\n};\n"
  },
  {
    "path": "packages/server/config/database/test",
    "content": ""
  },
  {
    "path": "packages/server/config/db.js",
    "content": "const mongoose = require('mongoose');\nconst { MongoMemoryServer } = require('mongodb-memory-server');\nconst path = require('path');\n\n(async () => {\n  const mongoServer = await MongoMemoryServer.create({\n    instance: {\n      dbName: 'nodejs-code-generator',\n      dbPath: path.join(__dirname, 'database'),\n      storageEngine: 'wiredTiger',\n    },\n  });\n  mongoose.connect(mongoServer.getUri(), {\n    useNewUrlParser: true,\n    useUnifiedTopology: true,\n  });\n  const db = mongoose.connection;\n\n  db.once('open', () => {\n    // console.log('Connection Successful');\n  });\n\n  db.on('error', () => {\n    // console.log('Error in mongodb connection');\n  });\n})();\nmodule.exports = mongoose;\n"
  },
  {
    "path": "packages/server/constants/common.js",
    "content": "module.exports = {\n  TXT_FILE_EXTENSION: [\n    'TXT',\n    'CFG',\n    'CONFIG',\n    'CSS',\n    'CSV',\n    'JSX',\n    'HTML',\n    'INF',\n    'INFO',\n    'JSON',\n    'INI',\n    'JS',\n    'LOG',\n    'XML',\n    'MAP',\n    'SVG',\n    'KT',\n    'GRADLE',\n    'BAT',\n    'JAVA',\n    'PROPERTIES',\n    'GITIGNORE',\n    'MD',\n    'ENV',\n    'EJS',\n    'PRO',\n    'CPP',\n    'COFFEE',\n    'LITCOFFEE',\n    'C',\n    'TS',\n    'SCSS',\n    'SCALA',\n    'SC',\n    'HBS',\n    'SHELL',\n    'XML',\n    'YAML',\n    'PY',\n    'PHP',\n    'SQL',\n    'VB',\n    'PERL',\n    'ST',\n    'SWIFT',\n    'PASCAL',\n    'DART',\n  ],\n  IMAGE_FILE_EXTENSION: [\n    'JPEG',\n    'JPG',\n    'PNG',\n    'GIF',\n    'TIFF',\n    'PSD',\n    'PDF',\n    'EPS',\n    'AI',\n    'RAW',\n    'INDD',\n    'TIFF',\n    'BMP',\n    'ICO',\n  ],\n  TXT_SECOND_LAST_FILE_EXTENSION: [\n    'ENV',\n  ],\n  EXTENSION_TYPE: {\n    DEFAULT: 1,\n    TEXT: 2,\n    IMAGE: 3,\n  },\n\n};\n"
  },
  {
    "path": "packages/server/constants/dataTypes/dataTypes.js",
    "content": "const { PROPS } = require('./props');\n\nmodule.exports = {\n\n  STRING: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.UNIQUE,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN_LENGTH,\n      PROPS.MAX_LENGTH,\n      PROPS.LOWER_CASE,\n      PROPS.PATTERN,\n    ],\n    VALUE: 'STRING',\n  },\n  TEXT: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.UNIQUE,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.TINY,\n      PROPS.MIN_LENGTH,\n      PROPS.MAX_LENGTH,\n      PROPS.LOWER_CASE,\n      PROPS.PATTERN,\n    ],\n    VALUE: 'TEXT',\n  },\n  CHAR: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.UNIQUE,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN_LENGTH,\n      PROPS.MAX_LENGTH,\n      PROPS.LOWER_CASE,\n      PROPS.PATTERN,\n    ],\n    VALUE: 'CHAR',\n  },\n  BOOLEAN: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n    ],\n    VALUE: 'BOOLEAN',\n  },\n  INTEGER: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.IS_AUTO_INCREMENT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'INTEGER',\n  },\n  BIGINT: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.IS_AUTO_INCREMENT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'BIGINT',\n  },\n  FLOAT: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'FLOAT',\n  },\n  REAL: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'REAL',\n  },\n  DOUBLE: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'DOUBLE',\n  },\n  DECIMAL: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'DECIMAL',\n  },\n  DATE: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'DATE',\n  },\n  DATETIME: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'DATETIME',\n  },\n  TIMESTAMP: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'TIMESTAMP',\n  },\n  DATEONLY: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'DATEONLY',\n  },\n  UUID: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'UUID',\n  },\n  UUIDV4: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.PRIMARY,\n    ],\n    VALUE: 'UUIDV4',\n  },\n  BLOB: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.TINY,\n    ],\n    VALUE: 'BLOB',\n  },\n  ENUM: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n    ],\n    VALUE: 'ENUM',\n  },\n  JSONB: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n    ],\n    VALUE: 'JSONB',\n  },\n  JSON: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n    ],\n    VALUE: 'JSON',\n  },\n  ARRAY: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.INNER_DATA_TYPE,\n    ],\n    VALUE: 'ARRAY',\n  },\n  GEOMETRY: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n    ],\n    VALUE: 'GEOMETRY',\n  },\n  VIRTUAL: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n    ],\n    VALUE: 'VIRTUAL',\n  },\n  GEOGRAPHY: {\n    ALLOW_PROPS: [\n      PROPS.GEOGRAPHY,\n    ],\n    VALUE: 'GEOGRAPHY',\n  },\n  RANGE: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.INNER_DATA_TYPE,\n    ],\n    VALUE: 'RANGE',\n  },\n  TINYSTRING: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.UNIQUE,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN_LENGTH,\n      PROPS.MAX_LENGTH,\n      PROPS.LOWER_CASE,\n      PROPS.PATTERN,\n    ],\n    VALUE: 'TINYSTRING',\n  },\n  TINYINTEGER: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.IS_AUTO_INCREMENT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'TINYINTEGER',\n  },\n  UnsignedBigInt: {\n    ALLOW_PROPS: [\n      PROPS.REF,\n      PROPS.REF_ATTR,\n      PROPS.RELATION_TYPE,\n      PROPS.DEFAULT,\n      PROPS.PRIMARY,\n      PROPS.DEFAULT,\n      PROPS.IS_AUTO_INCREMENT,\n      PROPS.PRIMARY,\n      PROPS.REQUIRED,\n      PROPS.MIN,\n      PROPS.MAX,\n    ],\n    VALUE: 'UnsignedBigInt',\n  },\n};\n"
  },
  {
    "path": "packages/server/constants/dataTypes/props.js",
    "content": "module.exports = {\n\n  PROPS: {\n    DEFAULT: 'default',\n    IS_AUTO_INCREMENT: 'isAutoIncrement',\n    UNIQUE: 'unique',\n    PRIMARY: 'primary',\n    REQUIRED: 'required',\n    TINY: 'tiny',\n    REF: 'ref',\n    REF_ATTR: 'refAttribute',\n    MIN: 'min',\n    MAX: 'max',\n    MIN_LENGTH: 'minLength',\n    MAX_LENGTH: 'maxLength',\n    TRIM: 'trim',\n    PATTERN: 'match',\n    LOWER_CASE: 'lowercase',\n    INNER_DATA_TYPE: 'innerDataType',\n    LOCAL_FIELD: 'localField',\n    FOREIGN_FIELD: 'foreignField',\n    RELATION_TYPE: 'relType',\n  },\n};\n"
  },
  {
    "path": "packages/server/constants/dataTypes/sequelize/index.js",
    "content": "const sqlDataTypes = require('./sqlDataTypes');\nconst mySqlDataTypes = require('./mySqlDataTypes');\nconst postGreSqlDataTypes = require('./postGreSqlDataTypes');\n\nmodule.exports = {\n  sqlDataTypes,\n  mySqlDataTypes,\n  postGreSqlDataTypes,\n};\n"
  },
  {
    "path": "packages/server/constants/dataTypes/sequelize/mySqlDataTypes.js",
    "content": "/* global _ */\n\nlet DATA_TYPES = require('../dataTypes');\n\n/**\n * To omit some properties from defined dataTypes.\n * Ex:\n */\n\n/*\n * const STRING = { ...DATA_TYPES.STRING, ...{ NA_PROPS: [PROPS.DEFAULT] } };\n * const ARRAY = { ...DATA_TYPES.ARRAY, ...{ NA_PROPS: [PROPS.REQUIRED] } };\n *\n * DATA_TYPES = { ...DATA_TYPES, ...{ STRING, ARRAY } };\n */\n\nDATA_TYPES = _.omit(DATA_TYPES, [\n  DATA_TYPES.UUID.VALUE,\n  DATA_TYPES.UUIDV4.VALUE,\n  DATA_TYPES.BLOB.VALUE,\n  DATA_TYPES.JSONB.VALUE,\n  DATA_TYPES.ARRAY.VALUE,\n  DATA_TYPES.RANGE.VALUE,\n]);\nmodule.exports = { DATA_TYPES };\n"
  },
  {
    "path": "packages/server/constants/dataTypes/sequelize/postGreSqlDataTypes.js",
    "content": "const DATA_TYPES = require('../dataTypes');\n/**\n * To omit some properties from defined dataTypes.\n * Ex:\n */\n\n/*\n * const STRING = { ...DATA_TYPES.STRING, ...{ NA_PROPS: [PROPS.DEFAULT] } };\n * const ARRAY = { ...DATA_TYPES.ARRAY, ...{ NA_PROPS: [PROPS.REQUIRED] } };\n *\n * DATA_TYPES = { ...DATA_TYPES, ...{ STRING, ARRAY } };\n */\n\nmodule.exports = { DATA_TYPES };\n"
  },
  {
    "path": "packages/server/constants/dataTypes/sequelize/sqlDataTypes.js",
    "content": "/* global _ */\n\nlet DATA_TYPES = require('../dataTypes');\n\nDATA_TYPES = _.omit(DATA_TYPES, [\n  DATA_TYPES.UUID.VALUE,\n  DATA_TYPES.UUIDV4.VALUE,\n  DATA_TYPES.BLOB.VALUE,\n  DATA_TYPES.JSONB.VALUE,\n  DATA_TYPES.JSON.VALUE,\n  DATA_TYPES.ARRAY.VALUE,\n  DATA_TYPES.GEOMETRY.VALUE,\n  DATA_TYPES.GEOGRAPHY.VALUE,\n  DATA_TYPES.RANGE.VALUE,\n]);\n\nmodule.exports = { DATA_TYPES };\n"
  },
  {
    "path": "packages/server/constants/envVariables.js",
    "content": "module.exports = {\n  QA: 'QA',\n  DEVELOPMENT: 'DEVELOPMENT',\n  PRODUCTION: 'PRODUCTION',\n};\n"
  },
  {
    "path": "packages/server/constants/jsonInput.js",
    "content": "module.exports = {\n  JSON_INPUT: {\n    AUTH_MODEL: 'user',\n    PROJECT_TYPE: 'MVC',\n  },\n};\n"
  },
  {
    "path": "packages/server/constants/master.js",
    "content": "module.exports = {\n  PARENT_CODES: {\n    EMAIL: 'EMAIL',\n    SMS: 'SMS',\n  },\n};\n"
  },
  {
    "path": "packages/server/constants/message.js",
    "content": "module.exports = {\n  message: {\n    ALREADY_EXISTS: {\n      code: 'E_DUPLICATE',\n      message: 'data already exists.',\n      status: 200,\n    },\n    BAD_REQUEST: {\n      code: 'E_BAD_REQUEST',\n      message: 'The request cannot be fulfilled due to bad syntax',\n      status: 400,\n      data: null,\n    },\n    OK: {\n      code: 'OK',\n      message: 'Operation is successfully executed',\n      status: 200,\n    },\n    // common-message-for-project\n    RECORD_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Record not found.',\n      status: 200,\n      data: null,\n    },\n    SCHEMA_NOT_FOUND: {\n      code: 'OK',\n      message: 'Schema not found.',\n      status: 200,\n      data: null,\n    },\n    APPLICATION_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Application not found',\n      status: 200,\n      data: null,\n    },\n    APPLICATION_DELETED: {\n      code: 'OK',\n      message: 'Application deleted successfully.',\n      status: 200,\n    },\n    APPLICATION_CONFIG_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Application config not found',\n      status: 200,\n      data: null,\n    },\n    SERVER_ERROR: {\n      code: 'E_INTERNAL_SERVER_ERROR',\n      message: 'Something bad happened on the server',\n      status: 500,\n    },\n    // common-message-for-create-failed\n    FAILED_TO_CREATE: {\n      message: 'Failed to create.',\n      code: 'E_CREATE_FAILED',\n      status: 500,\n    },\n    FAILED_TO_UPDATE: {\n      message: 'failed to update.',\n      code: 'E_UPDATE_FAILED',\n      status: 500,\n    },\n    APPLICATION_FAILED_CREATE: {\n      message: 'Failed to create application.',\n      code: 'E_CREATE_FAILED',\n      status: 500,\n    },\n    GENERATOR_FAILED_CREATE: {\n      message: 'Failed to generator application.',\n      code: 'E_CREATE_FAILED',\n      status: 500,\n    },\n    PROJECT_FAILED_CREATE: {\n      message: 'Failed to create project.',\n      code: 'E_CREATE_FAILED',\n      status: 500,\n    },\n    PROJECT_GENERATED_SUCCESSFULLY: {\n      code: 'OK',\n      message: 'project generated successfully.',\n      status: 200,\n    },\n    INVALID_REQUEST_PARAMS: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invalid Request Parameters.',\n      status: 400,\n      data: null,\n    },\n    SCHEMA_IS_EMPTY: {\n      code: 'E_BAD_REQUEST',\n      message: 'Schema not present for this application',\n      status: 400,\n      data: null,\n    },\n    RECORD_WITH_SAME_NAME_EXISTS: {\n      code: 'E_BAD_REQUEST',\n      message: 'Record with same name already exists',\n      status: 400,\n      data: null,\n    },\n    PROJECT_POLICY_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Middleware not found.',\n      status: 200,\n    },\n    ALREADY_USED_POLICY: {\n      code: 'E_BAD_REQUEST',\n      message: 'Middleware already in use.',\n      status: 200,\n    },\n    FILE_UPLOAD_FAILED: {\n      message: 'Upoad failed.',\n      code: 'E_CREATE_FAILED',\n      status: 500,\n    },\n    ENV_VARIABLE_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'ENV variables details not found',\n      status: 200,\n      data: null,\n    },\n    PROJECT_ROUTE_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Project route not found.',\n      status: 200,\n    },\n    INVALID_JSON: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invalid JSON file.',\n      status: 200,\n    },\n    EMPTY_JSON_FILE: {\n      code: 'E_BAD_REQUEST',\n      message: 'Empty JSON file.',\n      status: 200,\n    },\n    MIDDLEWARE_CREATED: {\n      code: 'OK',\n      message: 'Middleware created successfully.',\n      status: 200,\n    },\n    MIDDLEWARE_UPDATED: {\n      code: 'OK',\n      message: 'Middleware updated successfully.',\n      status: 200,\n    },\n    PROJECT_UPDATED: {\n      code: 'OK',\n      message: 'Project updated successfully.',\n      status: 200,\n    },\n    MIDDLEWARE_DELETED: {\n      code: 'OK',\n      message: 'Middleware deleted successfully.',\n      status: 200,\n    },\n    ROUTE_CREATED: {\n      code: 'OK',\n      message: 'Route created successfully.',\n      status: 200,\n    },\n    ROUTE_UPDATED: {\n      code: 'OK',\n      message: 'Route updated successfully.',\n      status: 200,\n    },\n    ROUTE_DELETED: {\n      code: 'OK',\n      message: 'Route deleted successfully.',\n      status: 200,\n    },\n    POSTMAN_UPLOADED: {\n      code: 'OK',\n      message: 'Routes uploaded successfully.',\n      status: 200,\n    },\n    ENV_DETAILS_UPDATED: {\n      code: 'OK',\n      message: 'Environment variable details updated successfully.',\n      status: 200,\n    },\n    APPLICATION_CONFIG_CREATED: {\n      code: 'OK',\n      message: 'Application config created successfully.',\n      status: 200,\n    },\n    APPLICATION_CONFIG_UPDATED: {\n      code: 'OK',\n      message: 'Application config updated successfully.',\n      status: 200,\n    },\n    APPLICATION_CREATED: {\n      code: 'OK',\n      message: 'Application created successfully.',\n      status: 200,\n    },\n    MODEL_CREATED: {\n      code: 'OK',\n      message: 'Model created successfully.',\n      status: 200,\n    },\n    MODEL_UPDATED: {\n      code: 'OK',\n      message: 'Model updated successfully.',\n      status: 200,\n    },\n    MODELS_UPDATED: {\n      code: 'OK',\n      message: 'Model(s) updated successfully.',\n      status: 200,\n    },\n    MODEL_DELETED: {\n      code: 'OK',\n      message: 'Model deleted successfully.',\n      status: 200,\n    },\n    MODEL_UPLOADED: {\n      code: 'OK',\n      message: 'Model uploaded successfully.',\n      status: 200,\n    },\n    MODEL_PERMISSION_UPDATED: {\n      code: 'OK',\n      message: 'Model permission updated successfully.',\n      status: 200,\n    },\n    CONSTANT_CREATED: {\n      code: 'OK',\n      message: 'Constant created successfully.',\n      status: 200,\n    },\n    CONSTANT_UPDATED: {\n      code: 'OK',\n      message: 'Constant updated successfully.',\n      status: 200,\n    },\n    CONSTANT_DELETED: {\n      code: 'OK',\n      message: 'Constant deleted successfully.',\n      status: 200,\n    },\n    PROJECT_GENERATED: {\n      code: 'OK',\n      message: 'Your applications is build successfully. Review or download source code to proceed further.',\n      status: 200,\n    },\n    ROLE_PERMISSIONS_CREATED: {\n      code: 'OK',\n      message: 'Role access permission created successfully.',\n      status: 200,\n    },\n    ROLE_PERMISSIONS_UPDATED: {\n      code: 'OK',\n      message: 'Role access permission updated successfully.',\n      status: 200,\n    },\n    ROLE_PERMISSIONS_DELETED: {\n      code: 'OK',\n      message: 'Role access permission deleted successfully.',\n      status: 200,\n    },\n    ROLE_PERMISSIONS_RETRIEVED: {\n      code: 'OK',\n      message: 'Role access permissions retrieved successfully.',\n      status: 200,\n    },\n    APPLICATION_UPDATED: {\n      code: 'OK',\n      message: 'Application updated successfully.',\n      status: 200,\n    },\n    INVALID_REGEXP: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invalid regular expression.',\n      status: 400,\n      data: null,\n    },\n    INVALID_SCHEMA_ATTR: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invalid schema attribute.',\n      status: 200,\n    },\n    FILE_UPLOADED: {\n      code: 'OK',\n      message: 'File uploaded successfully.',\n      status: 200,\n    },\n    INVALID_FILE: {\n      code: 'E_BAD_REQUEST',\n      status: 400,\n      message: 'You have uploaded an invalid file.',\n    },\n    SQL_PARSER_ERROR: {\n      code: 'E_INTERNAL_SERVER_ERROR',\n      status: 500,\n      message: 'Some error(s) occur, while updating tables.',\n    },\n    SCHEMA_DETAIL_NOT_FOUND: {\n      code: 'E_BAD_REQUEST',\n      message: 'Schema details not found.',\n      status: 400,\n      data: null,\n    },\n    APP_CONFIG_MODEL: {\n      code: 'E_APP_CONFIG_MODEL',\n      message: 'Model used in application config, you will not able to delete model.',\n      status: 400,\n      data: null,\n    },\n    APP_CONFIG_TABLE: {\n      code: 'E_APP_CONFIG_TABLE',\n      message: 'Table used in application config, you will not able to delete table.',\n      status: 400,\n      data: null,\n    },\n    SCHEMA_DELETE_DEPENDENCY: {\n      code: 'OK',\n      message: 'Dependency retrieved successfully.',\n      status: 200,\n      data: null,\n    },\n    DEFAULT_MODELS_INSERTED: {\n      code: 'OK',\n      message: 'Default models inserted successfully.',\n      status: 200,\n    },\n    DATA_TYPES_SUGGESTIONS: {\n      code: 'OK',\n      status: 200,\n      message: 'Data types retrieved successfully.',\n    },\n    NODE_APP_NOT_FOUND: {\n      code: 'E_BAD_REQUEST',\n      message: 'You not selected Node application.',\n      status: 400,\n      data: null,\n    },\n    APPLICATION_DETAILS_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Application not found',\n      status: 400,\n      data: null,\n    },\n    EMPTY_FILE: {\n      code: 'OK',\n      message: 'File is empty.',\n      status: 200,\n    },\n    DHIWISE_FILE_NOT_EXISTS: {\n      code: 'E_BAD_REQUEST',\n      message: 'Dhiwise.json file not exists.',\n      status: 400,\n    },\n    DEFINITION_NOT_FOUND: {\n      code: 'E_BAD_REQUEST',\n      message: 'Project definition not found.',\n      status: 400,\n    },\n    SCHEMA_SEARCH_FAILED: {\n      code: 'E_SCHEMA_SEARCH_FAILED',\n      message: 'Failed to search.',\n      status: 400,\n      data: null,\n    },\n    SAME_ROUTES_EXISTS: {\n      code: 'E_BAD_REQUEST',\n      message: 'Record with same route or action already exists.',\n      status: 400,\n      data: null,\n    },\n  },\n\n};\n"
  },
  {
    "path": "packages/server/constants/queryBuilder.js",
    "content": "module.exports = { TYPES: { ROUTES: 1 } };\n"
  },
  {
    "path": "packages/server/constants/schema.js",
    "content": "module.exports = {\n\n  DATA_TYPES: {\n    EMAIL: {\n      attributes: ['default', 'lowercase', 'trim'],\n      value: 'Email',\n    },\n    STRING: {\n      attributes: ['default', 'lowercase', 'trim', 'minLength', 'maxLength', 'match'],\n      value: 'String',\n    },\n    NUMBER: {\n      attributes: ['default', 'min', 'max'],\n      value: 'Number',\n    },\n    BOOLEAN: {\n      attributes: ['default'],\n      value: 'Boolean',\n    },\n    MIXED: {\n      attributes: [],\n      value: 'Mixed',\n    },\n    DATE: {\n      attributes: ['default'],\n      value: 'Date',\n    },\n    BUFFER: {\n      attributes: ['Buffer'],\n      value: 'Buffer',\n    },\n    MAP: {\n      attributes: ['Map'],\n      value: 'Map',\n    },\n    OBJECTID: {\n      attributes: ['ref'],\n      value: 'ObjectId',\n    },\n    // REF: ['ref'],\n    SINGLELINE: {\n      attributes: ['minLength', 'maxLength', 'lowercase', 'trim'],\n      value: 'SingleLine',\n    },\n    MULTILINE: {\n      attributes: ['minLength', 'maxLength', 'lowercase', 'trim'],\n      value: 'MultiLine',\n    },\n    URL: {\n      attributes: ['default', 'lowercase', 'trim'],\n      value: 'URL',\n    },\n    DECIMAL: {\n      attributes: ['default'],\n      value: 'Decimal',\n    },\n    PERCENT: {\n      attributes: ['default'],\n      value: 'Percentage',\n    },\n    VIRTUAL_RELATION: {\n      attributes: ['ref', 'localField', 'foreignField'],\n      value: 'virtualRelation',\n    },\n    JSON: {\n      attributes: [],\n      value: 'JSON',\n    },\n    ARRAY: {\n      attributes: [],\n      value: 'Array',\n    },\n  },\n  DATA_TYPES_DEFAULT_PROPS: ['required', 'unique', 'type', 'isAutoIncrement'],\n  MONGOOSE_TYPES: {\n    SCHEMA_TYPES_OBJ: 'mongoose.schema.types.objectid',\n    TYPES_OBJ: 'mongoose.types.objectid',\n  },\n  VALIDATION_MESSAGES: {\n\n    INVALID_TYPE_PROP: 'Invalid type property.',\n    MISSING_TYPE_PROP: 'Missing type property.',\n    MISSING_REF_PROPS: 'Missing ref property.',\n    MISSING_LOCAL_FIELD_PROPS: 'Missing localField property.',\n    MISSING_FOREIGN_FIELD_PROPS: 'Missing foreignField property.',\n    MAX_MUST_GREATER_TO_MIN: 'Max value must be greater than Min value.',\n    DEFAULT_MUST_GREATER_OR_EQUAL_TO_MIN: 'Default value must be greater than or equal to Min value.',\n    DEFAULT_MUST_LOWER_OR_EQUAL_TO_MAX: 'Default value must be less than or equal to Max value.',\n    MAX_LENGTH_MUST_GREATER_TO_MIN_LENGTH: 'MaxLength value must be greater than MinLength value.',\n    DEFAULT_LENGTH_MUST_GREATER_OR_EQUAL_TO_MIN_LENGTH: 'Default value length must be greater than or equal to MinLength.',\n    DEFAULT_LENGTH_MUST_LOWER_OR_EQUAL_TO_MAX_LENGTH: 'Default value length must be less than or equal to MaxLength.',\n    ONLY_ZERO_INDEX_ALLOW: 'Only 0 index allow in array.',\n    PROP_NOT_ALLOWED: 'Property not allowed',\n    INVALID_REGEXP: 'Invalid regular expression',\n    MISSING_RELATION_ATTR_PROP: 'Missing ref attribute property.',\n    INVALID_DEFAULT_PROP_VALUE: 'Invalid value in default property.',\n    UPDATE_MODEL_ERROR: 'Something went wrong, while updating model.',\n    MODEL_NOT_FOUND: 'Oops! model not found.',\n    SCHEMA_ALREADY_EXISTS: 'Schema of same name already exists.',\n    INVALID_RELATION_TYPE_VAL: 'Invalid relation type value.',\n  },\n  SQL_EXTENSION: {\n    APP_SQL: 'application/sql',\n    APP_X_SQL: 'application/x-sql',\n    TEXT_PLAIN: 'text/plain',\n    APP_OCTET_STREAM: 'application/octet-stream',\n  },\n  RELATIONS_TYPES: {\n    HAS_ONE: 1,\n    HAS_MANY: 2,\n  },\n  SCHEMA_ORG_URL: 'https://schema.org',\n  DEFAULT_TABLE_NAME: 'user',\n  DEFAULT_FIELDS: {\n    ID: 'id',\n    IS_ACTIVE: 'isactive',\n    ADDED_BY: 'addedby',\n    UPDATED_BY: 'updatedby',\n    CREATED_AT: 'createdat',\n    UPDATED_AT: 'updatedat',\n  },\n};\n"
  },
  {
    "path": "packages/server/constants/validation.js",
    "content": "module.exports = {\n  validation: {\n    name: {\n      min: 1,\n      max: 250,\n    },\n    description: {\n      min: 1,\n      max: 500,\n    },\n    template: {\n      min: 1,\n      max: 250,\n    },\n    fileName: {\n      min: 1,\n      max: 250,\n    },\n    method: {\n      min: 1,\n      max: 250,\n    },\n    route: {\n      min: 1,\n      max: 250,\n    },\n    controller: {\n      min: 1,\n      max: 250,\n    },\n    content: {\n      min: 1,\n      max: 250,\n    },\n    pagePath: {\n      min: 1,\n      max: 250,\n    },\n    databaseName: {\n      min: 1,\n      max: 200,\n    },\n    port: {\n      min: 1000,\n      max: 9999,\n    },\n    figmaFileId: {\n      min: 1,\n      max: 200,\n    },\n    figmaToken: {\n      min: 1,\n      max: 200,\n    },\n    navigateTo: {\n      min: 1,\n      max: 200,\n    },\n    navigateFrom: {\n      min: 1,\n      max: 200,\n    },\n    authModel: {\n      min: 1,\n      max: 200,\n    },\n    packageName: {\n      min: 1,\n      max: 200,\n    },\n    image: {\n      min: 1,\n      max: 200,\n    },\n    entryPath: {\n      min: 1,\n      max: 200,\n    },\n  },\n  VALIDATION_RULES: {\n    DESCRIPTION: {\n      MIN: 1,\n      MAX: 500,\n    },\n    PROJECT_NAME: {\n      MIN: 3,\n      MAX: 40,\n      REGEX: /^[a-zA-Z0-9]+[\\w _-]*$/,\n    },\n    APPLICATION: {\n      NAME: {\n        MIN: 3,\n        MAX: 40,\n        REGEX: /^([0-9 _-]*[a-zA-Z]){3,}[0-9 _-]*$/,\n      },\n      BUNDLE_ID: { REGEX: /^[a-z][a-z_]+\\.[a-z][a-z_]+\\.[a-z][a-z_]+/ },\n      PACKAGE_NAME: { REGEX: /^[a-z][a-z_]+\\.[a-z][a-z_]+\\.[a-z][a-z_]+/ },\n      SCREEN_IDS: { REGEX: /(^\\d+$)|(^\\d+:?\\d+$)/ },\n    },\n    PROJECT_DEFINITION_CODE: /^[A-Z_]+$/,\n    APPLICATION_FILE_NAME: /^[a-zA-Z]+[\\w0-9_-]*$/,\n    CONSTANT_FILE_NAME: /^[_a-zA-Z]+[\\w0-9_-]*$/,\n    APPLICATION_FILE_NAME_WITHOUT_DASH: /^[a-zA-Z_]+[\\w0-9_]*$/,\n    ROUTE_REGEX: /^[/]+[a-zA-Z]+[\\w0-9/_\\-{}]*$/,\n    URL_REGEX: /^((http|https):\\/\\/)/,\n    PORT_REGEX: /^(102[4-9]|10[3-9]\\d|1[1-9]\\d{2}|[2-9]\\d{3}|[1-5]\\d{4}|6[0-4]\\d{3}|65[0-4]\\d{2}|655[0-2]\\d|6553[0-5])$/,\n  },\n  NAME_REGEX: /^[a-zA-Z0-9]+[\\w_-]*$/,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/application/application.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst get = ({ getUseCase }) => async (req, res) => {\n  const response = await getUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase({ params: req.body });\n  return res.setResponse(response);\n};\nconst generate = ({ generateUseCase }) => async (req, res) => {\n  const response = await generateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst structure = ({ structureUseCase }) => async (req, res) => {\n  const response = await structureUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst upsert = ({ upsertUseCase }) => async (req, res) => {\n  const response = await upsertUseCase({\n    id: req.params.id,\n    params: req.body,\n    req,\n  });\n  return res.setResponse(response);\n};\n\nconst view = ({ viewUseCase }) => async (req, res) => {\n  const response = await viewUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst openCode = ({ openCodeUseCase }) => async (req, res) => {\n  const response = await openCodeUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst getLastApplication = ({ getLastApplicationUseCase }) => async (req, res) => {\n  const response = await getLastApplicationUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  paginate,\n  generate,\n  structure,\n  update,\n  destroy,\n  upsert,\n  view,\n  get,\n  openCode,\n  getLastApplication,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/application/index.js",
    "content": "const ApplicationRepository = require('../../../repo/application');\nconst SchemaRepository = require('../../../repo/schema');\nconst GenerateRepository = require('../../../repo/generate');\nconst ProjectRepository = require('../../../repo/project');\n\nconst applicationRepo = new ApplicationRepository();\nconst schemaRepo = new SchemaRepository();\nconst generateRepo = new GenerateRepository();\nconst projectRepo = new ProjectRepository();\n\nconst createUseCase = require('../../../usecase/application/create')(applicationRepo, schemaRepo, projectRepo);\nconst paginateUseCase = require('../../../usecase/application/paginate')(applicationRepo);\nconst generateUseCase = require('../../../usecase/application/generate')(applicationRepo, schemaRepo, generateRepo);\nconst structureUseCase = require('../../../usecase/application/structure')(applicationRepo, schemaRepo, generateRepo, projectRepo);\nconst deleteUseCase = require('../../../usecase/application/delete')(applicationRepo, schemaRepo, generateRepo);\nconst updateUseCase = require('../../../usecase/application/update')(applicationRepo, schemaRepo, generateRepo);\nconst getUseCase = require('../../../usecase/application/get')(applicationRepo);\nconst upsertUseCase = require('../../../usecase/application/upsert')(applicationRepo, projectRepo);\n// eslint-disable-next-line max-len\nconst viewUseCase = require('../../../usecase/application/view')(applicationRepo, projectRepo);\n// eslint-disable-next-line max-len\nconst openCodeUseCase = require('../../../usecase/application/openCode')();\nconst getLastApplicationUseCase = require('../../../usecase/application/getLastApplication')(applicationRepo);\nconst application = require('./application');\n\nconst create = application.create({ createUseCase });\nconst paginate = application.paginate({ paginateUseCase });\nconst generate = application.generate({ generateUseCase });\nconst structure = application.structure({ structureUseCase });\nconst update = application.update({ updateUseCase });\nconst get = application.get({ getUseCase });\nconst destroy = application.destroy({ deleteUseCase });\nconst upsert = application.upsert({ upsertUseCase });\nconst view = application.view({ viewUseCase });\nconst openCode = application.openCode({ openCodeUseCase });\nconst getLastApplication = application.getLastApplication({ getLastApplicationUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  generate,\n  structure,\n  update,\n  destroy,\n  upsert,\n  view,\n  get,\n  openCode,\n  getLastApplication,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/applicationConfig/applicationConfig.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst get = ({ getUseCase }) => async (req, res) => {\n  const response = await getUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  get,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/applicationConfig/index.js",
    "content": "const ApplicationConfigRepository = require('../../../repo/applicationConfig');\nconst ApplicationRepository = require('../../../repo/application');\n\nconst applicationRepo = new ApplicationRepository();\nconst applicationConfigRepo = new ApplicationConfigRepository();\n\nconst createUseCase = require('../../../usecase/applicationConfig/create')(applicationConfigRepo, applicationRepo);\nconst paginateUseCase = require('../../../usecase/applicationConfig/paginate')(applicationConfigRepo);\nconst deleteUseCase = require('../../../usecase/applicationConfig/delete')(applicationConfigRepo, applicationRepo);\nconst updateUseCase = require('../../../usecase/applicationConfig/update')(applicationConfigRepo, applicationRepo);\nconst getUseCase = require('../../../usecase/applicationConfig/get')(applicationConfigRepo);\n\nconst applicationConfig = require('./applicationConfig');\n\nconst create = applicationConfig.create({ createUseCase });\nconst paginate = applicationConfig.paginate({ paginateUseCase });\nconst update = applicationConfig.update({ updateUseCase });\nconst destroy = applicationConfig.destroy({ deleteUseCase });\nconst get = applicationConfig.get({ getUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  get,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/envVariables/envVariables.js",
    "content": "const upsert = ({ upsertUseCase }) => async (req, res) => {\n  const response = await upsertUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst get = ({ getUseCase }) => async (req, res) => {\n  const response = await getUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  upsert,\n  get,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/envVariables/index.js",
    "content": "const EnvVariablesRepository = require('../../../repo/envVariables');\nconst ApplicationRepo = require('../../../repo/application');\n\nconst envVariablesRepo = new EnvVariablesRepository();\nconst applicationRepo = new ApplicationRepo();\n\nconst upsertUseCase = require('../../../usecase/envVariables/upsert')(envVariablesRepo, applicationRepo);\nconst getUseCase = require('../../../usecase/envVariables/get')(envVariablesRepo);\n\nconst envVariables = require('./envVariables');\n\nconst upsert = envVariables.upsert({ upsertUseCase });\nconst get = envVariables.get({ getUseCase });\n\nmodule.exports = {\n  upsert,\n  get,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/jsonInput/index.js",
    "content": "const jsonInputUseCase = require('../../../usecase/jsonInput/jsonInput')();\n\nconst jsonInputData = require('./jsonInput');\n\nconst jsonInput = jsonInputData.jsonInput({ jsonInputUseCase });\n\nmodule.exports = { jsonInput };\n"
  },
  {
    "path": "packages/server/controllers/web/jsonInput/jsonInput.js",
    "content": "const jsonInput = ({ jsonInputUseCase }) => async (req, res) => {\n  const response = await jsonInputUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = { jsonInput };\n"
  },
  {
    "path": "packages/server/controllers/web/master/index.js",
    "content": "const MasterRepository = require('../../../repo/master');\n\nconst masterRepo = new MasterRepository();\nconst getByCodeUseCase = require('../../../usecase/master/getByCode')(masterRepo);\n\nconst master = require('./master');\n\nmodule.exports = { getByCode: master.getByCode({ getByCodeUseCase }) };\n"
  },
  {
    "path": "packages/server/controllers/web/master/master.js",
    "content": "const getByCode = ({ getByCodeUseCase }) => async (req, res) => {\n  const response = await getByCodeUseCase(req.body, null, null);\n  return res.setResponse(response);\n};\n\nmodule.exports = { getByCode };\n"
  },
  {
    "path": "packages/server/controllers/web/project/index.js",
    "content": "const ProjectRepository = require('../../../repo/project');\nconst ApplicationRepository = require('../../../repo/application');\n\nconst projectRepo = new ProjectRepository();\nconst applicationRepo = new ApplicationRepository();\n\nconst createUseCase = require('../../../usecase/project/create')(projectRepo);\nconst paginateUseCase = require('../../../usecase/project/paginate')(projectRepo, applicationRepo);\nconst deleteUseCase = require('../../../usecase/project/delete')(projectRepo);\nconst updateUseCase = require('../../../usecase/project/update')(projectRepo);\nconst getUseCase = require('../../../usecase/project/get')(projectRepo);\nconst upsertUseCase = require('../../../usecase/project/upsert')(projectRepo, applicationRepo);\n\nconst project = require('./project');\n\nconst create = project.create({ createUseCase });\nconst paginate = project.paginate({ paginateUseCase });\nconst update = project.update({ updateUseCase });\nconst destroy = project.destroy({ deleteUseCase });\nconst get = project.get({ getUseCase });\nconst upsert = project.upsert({ upsertUseCase });\nconst applicationRestriction = project.applicationRestriction({});\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  get,\n  upsert,\n  applicationRestriction,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/project/project.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst get = ({ getUseCase }) => async (req, res) => {\n  const response = await getUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst upsert = ({ upsertUseCase }) => async (req, res) => {\n  const response = await upsertUseCase(req.params.id, req.body, req.headers);\n  return res.setResponse(response);\n};\n\nconst applicationRestriction = ({ applicationRestrictionUseCase }) => async (req, res) => {\n  req.body.companyId = req.headers.companyid;\n  const response = await applicationRestrictionUseCase(req.body, res);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  get,\n  upsert,\n  applicationRestriction,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectConstant/index.js",
    "content": "const ProjectConstantRepository = require('../../../repo/projectConstant');\nconst ApplicationRepository = require('../../../repo/application');\n\nconst applicationRepo = new ApplicationRepository();\nconst projectConstantRepo = new ProjectConstantRepository();\n\nconst createUseCase = require('../../../usecase/projectConstant/create')(projectConstantRepo, applicationRepo);\nconst paginateUseCase = require('../../../usecase/projectConstant/paginate')(projectConstantRepo);\nconst deleteUseCase = require('../../../usecase/projectConstant/delete')(projectConstantRepo, applicationRepo);\nconst updateUseCase = require('../../../usecase/projectConstant/update')(projectConstantRepo, applicationRepo);\n\nconst projectConstant = require('./projectConstant');\n\nconst create = projectConstant.create({ createUseCase });\nconst paginate = projectConstant.paginate({ paginateUseCase });\nconst update = projectConstant.update({ updateUseCase });\nconst destroy = projectConstant.destroy({ deleteUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectConstant/projectConstant.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  update,\n  destroy,\n  paginate,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectPolicy/index.js",
    "content": "const ProjectPolicyRepository = require('../../../repo/projectPolicy');\nconst ApplicationRepository = require('../../../repo/application');\n\nconst applicationRepo = new ApplicationRepository();\nconst projectPolicyRepo = new ProjectPolicyRepository();\n\nconst createUseCase = require('../../../usecase/projectPolicy/create')(projectPolicyRepo, applicationRepo);\nconst paginateUseCase = require('../../../usecase/projectPolicy/paginate')(projectPolicyRepo);\nconst deleteUseCase = require('../../../usecase/projectPolicy/delete')(projectPolicyRepo, applicationRepo);\nconst updateUseCase = require('../../../usecase/projectPolicy/update')(projectPolicyRepo, applicationRepo);\n\nconst projectPolicy = require('./projectPolicy');\n\nconst create = projectPolicy.create({ createUseCase });\nconst paginate = projectPolicy.paginate({ paginateUseCase });\nconst update = projectPolicy.update({ updateUseCase });\nconst destroy = projectPolicy.destroy({ deleteUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectPolicy/projectPolicy.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  update,\n  destroy,\n  paginate,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectRoleAccessPermissions/index.js",
    "content": "const ProjectRoleAccessPermissionsRepository = require('../../../repo/projectRoleAccessPermissions');\n\nconst projectRoleAccessPermissionsRepo = new ProjectRoleAccessPermissionsRepository();\n\nconst upsertUseCase = require('../../../usecase/projectRoleAccessPermissions/upsert')(projectRoleAccessPermissionsRepo);\nconst paginateUseCase = require('../../../usecase/projectRoleAccessPermissions/paginate')(projectRoleAccessPermissionsRepo);\nconst destroyUseCase = require('../../../usecase/projectRoleAccessPermissions/delete')(projectRoleAccessPermissionsRepo);\n\nconst roleAccessPermissions = require('./roleAccessPermissions');\n\nconst upsert = roleAccessPermissions.upsert({ upsertUseCase });\nconst paginate = roleAccessPermissions.paginate({ paginateUseCase });\nconst destroy = roleAccessPermissions.destroy({ destroyUseCase });\n\nmodule.exports = {\n  upsert,\n  paginate,\n  destroy,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectRoleAccessPermissions/roleAccessPermissions.js",
    "content": "const upsert = ({ upsertUseCase }) => async (req, res) => {\n  const response = await upsertUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ destroyUseCase }) => async (req, res) => {\n  const response = await destroyUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  upsert,\n  destroy,\n  paginate,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectRoute/index.js",
    "content": "const ProjectRouteRepository = require('../../../repo/projectRoute');\nconst ApplicationRepository = require('../../../repo/application');\n\nconst applicationRepo = new ApplicationRepository();\nconst projectRouteRepo = new ProjectRouteRepository();\n\nconst createUseCase = require('../../../usecase/projectRoute/create')(projectRouteRepo, applicationRepo);\nconst paginateUseCase = require('../../../usecase/projectRoute/paginate')(projectRouteRepo);\nconst deleteUseCase = require('../../../usecase/projectRoute/delete')(projectRouteRepo, applicationRepo);\nconst updateUseCase = require('../../../usecase/projectRoute/update')(projectRouteRepo, applicationRepo);\nconst uploadPostmanFileUseCase = require('../../../usecase/projectRoute/uploadPostmanFile')(projectRouteRepo, applicationRepo);\n\nconst requestApiUseCase = require('../../../usecase/projectRoute/requestApi')();\n\nconst projectRoute = require('./projectRoute');\n\nconst create = projectRoute.create({ createUseCase });\nconst paginate = projectRoute.paginate({ paginateUseCase });\nconst update = projectRoute.update({ updateUseCase });\nconst destroy = projectRoute.destroy({ deleteUseCase });\nconst uploadPostmanFile = projectRoute.uploadPostmanFile({ uploadPostmanFileUseCase });\nconst requestApi = projectRoute.requestApi({ requestApiUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  uploadPostmanFile,\n  requestApi,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/projectRoute/projectRoute.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst uploadPostmanFile = ({ uploadPostmanFileUseCase }) => async (req, res) => {\n  const response = await uploadPostmanFileUseCase(req);\n  return res.setResponse(response);\n};\n\nconst requestApi = ({ requestApiUseCase }) => async (req, res) => {\n  const response = await requestApiUseCase({ params: req.body });\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  update,\n  destroy,\n  paginate,\n  uploadPostmanFile,\n  requestApi,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/schema/index.js",
    "content": "const ApplicationRepository = require('../../../repo/application');\nconst SchemaRepository = require('../../../repo/schema');\n\nconst applicationRepo = new ApplicationRepository();\nconst schemaRepo = new SchemaRepository();\n\nconst createUseCase = require('../../../usecase/schema/create')(schemaRepo, applicationRepo);\nconst insertManyUseCase = require('../../../usecase/schema/insertMany')(schemaRepo, applicationRepo);\nconst paginateUseCase = require('../../../usecase/schema/paginate')(schemaRepo, applicationRepo);\nconst updateUseCase = require('../../../usecase/schema/update')(schemaRepo, applicationRepo);\nconst deleteUseCase = require('../../../usecase/schema/delete')(schemaRepo, applicationRepo);\nconst existsSchemaUpdateUseCase = require('../../../usecase/schema/existsSchemaUpdate')(schemaRepo);\nconst sqlSchemaExistsUseCase = require('../../../usecase/schema/sequelize/existsSchemaUpdate')(schemaRepo, applicationRepo);\nconst getSchemaUseCase = require('../../../usecase/schema/get')(schemaRepo);\nconst insertDefaultModelsUseCase = require('../../../usecase/schema/InsertDefaultModels/insertDefaultModels')(schemaRepo, applicationRepo);\nconst searchSchemaUseCase = require('../../../usecase/schema/searchSchema')(applicationRepo);\n\nconst schema = require('./schema');\n\nconst create = schema.create({ createUseCase });\nconst insertMany = schema.insertMany({ insertManyUseCase });\nconst paginate = schema.paginate({ paginateUseCase });\nconst update = schema.update({ updateUseCase });\nconst destroy = schema.destroy({ deleteUseCase });\nconst schemaExists = schema.schemaExists({ existsSchemaUpdateUseCase });\nconst sqlSchemaExists = schema.sqlSchemaExists({ sqlSchemaExistsUseCase });\nconst getSchema = schema.getSchema({ getSchemaUseCase });\nconst insertDefaultModels = schema.insertDefaultModels({ insertDefaultModelsUseCase });\nconst searchSchema = schema.searchSchema({ searchSchemaUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  insertMany,\n  schemaExists,\n  sqlSchemaExists,\n  getSchema,\n  insertDefaultModels,\n  searchSchema,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/schema/schema.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\nconst insertMany = ({ insertManyUseCase }) => async (req, res) => {\n  const response = await insertManyUseCase(req);\n  return res.setResponse(response);\n};\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\nconst destroy = ({ deleteUseCase }) => async (req, res) => {\n  const response = await deleteUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst schemaExists = ({ existsSchemaUpdateUseCase }) => async (req, res) => {\n  const response = await existsSchemaUpdateUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst sqlSchemaExists = ({ sqlSchemaExistsUseCase }) => async (req, res) => {\n  const response = await sqlSchemaExistsUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst sqlInsertMany = ({ sqlInsertManyUseCase }) => async (req, res) => {\n  const response = await sqlInsertManyUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst getSchema = ({ getSchemaUseCase }) => async (req, res) => {\n  const response = await getSchemaUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst insertDefaultModels = ({ insertDefaultModelsUseCase }) => async (req, res) => {\n  const response = await insertDefaultModelsUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst dataTypeSuggestions = ({ dataTypeSuggestionsUseCase }) => async (req, res) => {\n  const response = await dataTypeSuggestionsUseCase(req.body);\n  return res.setResponse(response);\n};\n\nconst searchSchema = ({ searchSchemaUseCase }) => async (req, res) => {\n  const response = await searchSchemaUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  destroy,\n  insertMany,\n  schemaExists,\n  sqlSchemaExists,\n  sqlInsertMany,\n  getSchema,\n  insertDefaultModels,\n  dataTypeSuggestions,\n  searchSchema,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/schemaDetail/index.js",
    "content": "const SchemaRepository = require('../../../repo/schema');\nconst SchemaDetailRepository = require('../../../repo/schemaDetail');\n\nconst SchemaDetailRepo = new SchemaDetailRepository();\nconst schemaRepo = new SchemaRepository();\nconst createUseCase = require('../../../usecase/schemaDetail/create')(SchemaDetailRepo, schemaRepo);\nconst paginateUseCase = require('../../../usecase/schemaDetail/paginate')(SchemaDetailRepo, schemaRepo);\nconst updateUseCase = require('../../../usecase/schemaDetail/update')(SchemaDetailRepo, schemaRepo);\nconst upsertUseCase = require('../../../usecase/schemaDetail/upsert')(SchemaDetailRepo, schemaRepo);\n\nconst schema = require('./schemaDetail');\n\nconst create = schema.create({ createUseCase });\nconst paginate = schema.paginate({ paginateUseCase });\nconst update = schema.update({ updateUseCase });\nconst upsert = schema.upsert({ upsertUseCase });\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  upsert,\n};\n"
  },
  {
    "path": "packages/server/controllers/web/schemaDetail/schemaDetail.js",
    "content": "const create = ({ createUseCase }) => async (req, res) => {\n  const response = await createUseCase(req.body);\n  return res.setResponse(response);\n};\nconst paginate = ({ paginateUseCase }) => async (req, res) => {\n  const response = await paginateUseCase(req.body);\n  return res.setResponse(response);\n};\nconst update = ({ updateUseCase }) => async (req, res) => {\n  const response = await updateUseCase(req.params.id, req.body);\n  return res.setResponse(response);\n};\n\nconst upsert = ({ upsertUseCase }) => async (req, res) => {\n  const response = await upsertUseCase(req.body);\n  return res.setResponse(response);\n};\n\nmodule.exports = {\n  create,\n  paginate,\n  update,\n  upsert,\n};\n"
  },
  {
    "path": "packages/server/middleware/responses/ok.js",
    "content": "/* global _, */\nmodule.exports = (data, config) => {\n  const response = _.assign({\n    code: _.get(config, 'code', 'OK'),\n    message: _.get(config, 'message', 'Operation is successfully executed'),\n    data: data || {},\n  }, _.get(config, 'root', {}));\n\n  this.res.status(200);\n  this.res.json(response);\n};\n"
  },
  {
    "path": "packages/server/models/Models/Queue.js",
    "content": "const mongoose = require('mongoose');\n\nconst QueueSchema = new mongoose.Schema({\n  isUpdated: {\n    type: 'boolean',\n    default: false,\n  },\n  syncApi: { type: 'string' },\n  data: { type: [] },\n  homeAreaId: {\n    type: 'ObjectId',\n    ref: 'org-home',\n  },\n  dataId: { type: 'string' },\n}, { toJSON: { virtuals: true } }, { timestamp: true });\nQueueSchema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model('queue', QueueSchema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/Application.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n  projectId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.PROJECT.MODEL_NAME,\n  },\n  generatedId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.GENERATOR.MODEL_NAME,\n  },\n  adminPanelGeneratedId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.GENERATOR.MODEL_NAME,\n  },\n  tempGeneratedId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.GENERATOR.MODEL_NAME,\n  },\n  definitionId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.PROJECT_DEFINITION.MODEL_NAME,\n  },\n  parentId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n\n  name: {\n    type: 'string',\n    required: true,\n  },\n  description: { type: 'string' },\n  image: { type: 'string' },\n\n  stepInput: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {},\n  },\n  configInput: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {},\n  },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  isArchive: {\n    type: 'boolean',\n    default: false,\n  },\n  isPublic: {\n    type: 'boolean',\n    default: false,\n  },\n  isPublicConsent: {\n    type: 'boolean',\n    default: false,\n  },\n  port: { type: 'Number' },\n\n  projectType: { type: 'string' },\n\n  inProcessStatus: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {\n      build_app: 0,\n      get_apk: 0,\n    },\n  },\n  statics: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {},\n  },\n  processStep: { type: 'number' },\n  processDoneOnced: {\n    type: 'boolean', // first time true when open on dashboard\n    default: false,\n  },\n  lastBuildAt: { type: Date },\n  output: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {},\n  },\n  isClone: {\n    type: 'boolean',\n    default: false,\n  },\n  inActiveReason: { type: String },\n  imageScale: { type: 'number' },\n  isDefaultPublic: {\n    type: 'boolean',\n    default: false,\n  },\n  tags: { type: Array },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  selfUpdatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.APPLICATION.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/ApplicationConfig.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n\n  authModuleId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n\n  authModule: { type: 'string' },\n\n  loginWith: {\n    username: { type: mongoose.Schema.Types.Mixed },\n    password: { type: mongoose.Schema.Types.Mixed },\n  },\n\n  isTwoFA: {\n    type: 'boolean',\n    default: false,\n  },\n\n  /*\n   *\"twoFAType\":{\n   * type: 'numbeisTwoFA_FA_AUTHENTICATION_TYPE.OTP,\n   *},\n   *\"platform\":{\n   * \"admin\": false,\n   * \"device\": true,\n   * \"desktop\": true,\n   * \"client\": true\n   *},\n   *\"otpSendMedium\": { type: mongoose.Schema.Types.Mixed,}\n   *{\n   *   masterIds:  {\n   *     type: mongoose.Schema.Types.ObjectId,\n   *     ref: MODULE.MASTER.MODEL_NAME,\n   *   },\n   *   \"sms\": true,\n   *   \"email\": false\n   *}\n   */\n  twoFactorAuthentication: { type: mongoose.Schema.Types.Mixed },\n\n  /*\n   * { min : 3\n   *   max : 5\n   * }\n   */\n  loginRetryLimit: { type: mongoose.Schema.Types.Mixed },\n\n  /*\n   * { min : 3\n   *   max : 5\n   *   reActiveTime:20\n   * }\n   */\n  loginRateLimit: { type: mongoose.Schema.Types.Mixed },\n\n  loginNextRetryTime: { type: 'number' },\n\n  /*\n   *  \"otp\":{\n   *    masterIds:  {\n   *    type: mongoose.Schema.Types.ObjectId,\n   *    ref: MODULE.MASTER.MODEL_NAME,\n   *    },\n   *  //       \"email\": true,\n   *  //       \"sms\": false\n   *  //   },\n   *  //   \"link\": {\n   *        masterIds:  {\n   *          type: mongoose.Schema.Types.ObjectId,\n   *          ref: MODULE.MASTER.MODEL_NAME,\n   *        },\n   *  //       \"email\": true,\n   *  //       \"sms\": false\n   *  //   },number\n   */\n  resetPassword: { type: mongoose.Schema.Types.Mixed },\n\n  isSocialMediaAuth: {\n    type: 'boolean',\n    default: false,\n  },\n\n  socialPlatform: [{\n    typeId: { type: mongoose.Schema.Types.ObjectId },\n    type: { type: 'string' },\n    isChecked: { type: 'boolean' },\n    platform: { type: mongoose.Schema.Types.Mixed },\n    credential: { type: mongoose.Schema.Types.Mixed },\n  }],\n\n  tokenExpiryTime: { type: 'number' },\n\n  restrictNoOfDevice: { type: 'boolean' },\n\n  noOfDevice: {\n    type: 'number',\n    default: 1,\n  },\n\n  externalServiceProviderData: [\n    {\n      typeId: {\n        type: mongoose.Schema.Types.ObjectId,\n        ref: MODULE.MASTER.MODEL_NAME,\n      },\n      type: { type: 'string' },\n      serviceProviderId: {\n        type: mongoose.Schema.Types.ObjectId,\n        ref: MODULE.MASTER.MODEL_NAME,\n      },\n      serviceProvide: { type: 'string' },\n      customJson: { type: mongoose.Schema.Types.Mixed },\n    },\n  ],\n\n  fileUpload: {\n    uploads: [\n      {\n        platform: { type: mongoose.Schema.Types.Mixed },\n        validationType: [\n          { type: 'String' },\n        ],\n        storage: { type: 'string' },\n        authentication: { type: 'boolean' },\n        maxSize: { type: 'number' },\n        isSingle: { type: 'boolean' },\n      },\n    ],\n  },\n\n  isBiometric: { // kotlin config\n    type: 'boolean',\n  },\n\n  isSocket: { // node config\n    type: 'boolean',\n  },\n\n  isActivityLog: { // node config\n    type: 'boolean',\n  },\n\n  responseFormatter: [\n    {\n      _id: false,\n      isAllModels: { type: 'boolean' },\n      modelId: {\n        type: mongoose.Schema.Types.ObjectId,\n        ref: MODULE.SCHEMA.MODEL_NAME,\n      },\n      title: { type: 'string' },\n      dataType: { type: 'string' },\n      targetAttr: { type: 'string' },\n      operator: { type: 'string' },\n      attribute: { type: mongoose.Schema.Types.Mixed },\n    },\n  ],\n  authentication: { type: mongoose.Schema.Types.Mixed },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.APPLICATION_CONFIG.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/EnvVariables.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  environments: {\n    type: 'array',\n    columnType: 'array',\n  },\n  customJson: { type: mongoose.Schema.Types.Mixed },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\n\nmodule.exports = mongoose.model(MODULE.ENV_VARIABLES.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/Generator.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  type: {\n    type: 'number',\n    default: 1,\n  },\n  config: { type: mongoose.Schema.Types.Mixed },\n  output: { type: mongoose.Schema.Types.Mixed },\n  projectPath: { type: 'string' },\n  status: {\n    type: 'number',\n    default: 1,\n  },\n  versionNumber: {\n    type: 'number',\n    default: 0,\n  },\n  semanticVersionNumber: { type: 'string' },\n  inProcessStatus: {\n    type: mongoose.Schema.Types.Mixed,\n    default: {\n      build_app: 0,\n      get_apk: 0,\n    },\n  },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.GENERATOR.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/Master.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst MasterSchema = new mongoose.Schema(\n  {\n    name: { type: 'string' },\n    normalizeName: { type: 'string' },\n    slug: { type: 'string' },\n    code: { type: 'string' },\n    group: { type: 'string' },\n    description: { type: 'string' },\n    isActive: { type: 'boolean' },\n    isDefault: { type: 'boolean' },\n    sortingSequence: { type: 'number' },\n    image: { type: 'string' },\n    icon: { type: 'string' },\n    customJson: { type: mongoose.Schema.Types.Mixed },\n    // self relation\n    parentId: {\n      type: mongoose.Schema.Types.ObjectId,\n      ref: MODULE.MASTER.MODEL_NAME,\n      default: null,\n    },\n    parentCode: { type: 'string' },\n    documentUrl: { type: String },\n    isDeleted: {\n      type: 'boolean',\n      default: false,\n    },\n\n    masterForMedium: { type: 'number' },\n  },\n  { timestamps: true },\n  { toJSON: { virtuals: true } },\n);\nMasterSchema.virtual('subMaster', {\n  ref: MODULE.MASTER.MODEL_NAME,\n  localField: '_id',\n  foreignField: 'parentId',\n});\n\nMasterSchema.pre('save', (next) => {\n  // 'this' refers to the current document about to be saved\n  const user = this;\n  // create slug using code\n  const slug = user.code.toLowerCase();\n  // Replace and then store it\n  user.slug = slug;\n  // Indicates we're done and moves on to the next middleware\n  next();\n});\nMasterSchema.pre(\n  'findOneAndUpdate',\n  {\n    document: true,\n    query: false,\n  },\n  (next) => {\n    const user = this._update;\n    // console.log('user.$set.code');\n    if (user.$set.code) {\n      const slug = user.$set.code.toLowerCase();\n      user.$set.slug = slug;\n    }\n    next();\n  },\n);\nmodule.exports = mongoose.model(MODULE.MASTER.MODEL_NAME, MasterSchema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/NestedQueryBuilder.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  platform: { type: 'string' },\n  operation: { type: 'string' },\n  operationMode: { type: 'string' },\n\n  referenceId: { type: mongoose.Schema.Types.ObjectId },\n\n  referenceType: { type: 'number' },\n\n  requestParams: { type: mongoose.Schema.Types.Mixed },\n\n  requestModelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n\n  requestModel: { type: 'string' },\n\n  model: { type: 'string' },\n\n  modelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n\n  queryMode: { type: 'string' },\n\n  existingVariable: { type: 'string' },\n\n  outputVariable: { type: 'string' },\n\n  filter: { type: mongoose.Schema.Types.Mixed },\n\n  filterJson: { type: mongoose.Schema.Types.Mixed },\n\n  populate: { type: 'array' },\n\n  select: { type: 'array' },\n\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.NESTED_QUERY_BUILDER.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/Project.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n  name: {\n    type: 'string',\n    required: true,\n  },\n  description: { type: 'string' },\n  image: { type: 'string' },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  isArchive: {\n    type: 'boolean',\n    default: false,\n  },\n  isPublic: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  selfUpdatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.PROJECT.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/ProjectConstant.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\nconst { CONSTANT_GENERATE_TYPE } = require('../../constants/project');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  fileName: { type: 'string' },\n  type: {\n    type: 'number',\n    default: CONSTANT_GENERATE_TYPE.AUTO,\n  },\n  customJson: { type: mongoose.Schema.Types.Mixed },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  modelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  description: { type: 'string' },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.PROJECT_CONSTANT.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/ProjectPolicy.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\nconst { POLICY_GENERATE_TYPE } = require('../../constants/project');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  fileName: { type: 'string' },\n  type: {\n    type: 'number',\n    default: POLICY_GENERATE_TYPE.AUTO,\n  },\n  customJson: { type: mongoose.Schema.Types.Mixed },\n  description: { type: 'string' },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.PROJECT_POLICY.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/ProjectRoleAccessPermissions.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  name: { type: 'string' },\n  description: { type: 'string' },\n  customJson: [{\n    _id: false,\n    modelId: {\n      type: mongoose.Schema.Types.ObjectId,\n      ref: MODULE.SCHEMA.MODEL_NAME,\n    },\n    actions: { type: mongoose.Schema.Types.Mixed },\n  }],\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.PROJECT_ROLE_ACCESS_PERMISSIONS.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/ProjectRoute.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\nconst { ROUTE_GENERATE_TYPE } = require('../../constants/project');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  fileName: { type: 'string' },\n  method: { type: 'string' },\n  route: { type: 'string' },\n  controller: { type: 'string' },\n  action: { type: 'string' },\n  description: { type: 'string' },\n  platform: { type: 'string' },\n  policies: { type: mongoose.Schema.Types.Mixed },\n  type: {\n    type: 'number',\n    default: ROUTE_GENERATE_TYPE.AUTO,\n  },\n  customJson: { type: mongoose.Schema.Types.Mixed },\n  modelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  groupName: { type: 'string' },\n  headers: [{\n    _id: false,\n    key: { type: 'string' },\n    value: { type: 'string' },\n  }],\n  params: [{\n    _id: false,\n    key: { type: 'string' },\n    value: { type: 'string' },\n  }],\n  request: { type: mongoose.Schema.Types.Mixed },\n  response: { type: mongoose.Schema.Types.Mixed },\n  fileUpload: {\n    uploads: [\n      {\n        platform: { type: mongoose.Schema.Types.Mixed },\n        validationType: [{ type: 'String' }],\n        storage: { type: 'String' },\n        authentication: { type: 'boolean' },\n        maxSize: { type: 'number' },\n        isSingle: { type: 'boolean' },\n      },\n    ],\n  },\n  attributes: { type: mongoose.Schema.Types.Mixed },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.PROJECT_ROUTE.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/QueryBuilder.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  referenceId: { type: mongoose.Schema.Types.ObjectId },\n  referenceType: { type: 'number' },\n  requestParams: { type: mongoose.Schema.Types.Mixed },\n  requestModelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  requestModel: { type: 'string' },\n  model: { type: 'string' },\n  modelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  queryMode: { type: 'string' },\n  outputVariable: { type: 'string' },\n  filter: { type: mongoose.Schema.Types.Mixed },\n  filterJson: { type: mongoose.Schema.Types.Mixed },\n  populate: { type: 'array' },\n  select: { type: 'array' },\n  code: { type: 'string' },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.QUERY_BUILDER.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/RawModel.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  modelId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  parentId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.RAW_MODEL.MODEL_NAME,\n    default: null,\n  },\n  // attribute level from main parent\n  level: {\n    type: 'number',\n    default: 1,\n  },\n  // siblings sequence\n  sequence: {\n    type: 'number',\n    default: 1,\n  },\n  attribute: { type: 'string' },\n  dataType: {\n    type: 'string',\n    default: '',\n  },\n  /**\n   * 1:none\n   * 2:as define\n   * 3:current time\n   * 4:null\n   * 4:empty string\n   */\n  defaultValueType: {\n    type: 'number',\n    default: 1,\n  },\n  defaultValue: { type: mongoose.Schema.Types.Mixed },\n  isRequired: {\n    type: 'boolean',\n    default: false,\n  },\n  isUnique: {\n    type: 'boolean',\n    default: false,\n  },\n  isAllowNull: {\n    type: 'boolean',\n    default: false,\n  },\n  isAutoIncrement: {\n    type: 'boolean',\n    default: false,\n  },\n  description: { type: 'string' },\n  enumValues: { type: mongoose.Schema.Types.Array },\n\n  // relation\n\n  relationModel: { type: 'string' },\n  relationAttribute: { type: 'string' },\n  relationType: { type: 'string' },\n\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.RAW_MODEL.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/Schema.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  name: {\n    type: 'string',\n    required: true,\n  },\n  tableName: { type: 'string' },\n  description: { type: 'string' },\n  schemaJson: { type: mongoose.Schema.Types.Mixed },\n  hooks: [{\n    type: { type: 'string' },\n    operation: { type: 'string' },\n    code: { type: mongoose.Schema.Types.Mixed },\n  }],\n\n  modelIndexes: [{\n    name: { type: 'string' },\n    isParserRequired: { // temp key for if parse required for old data\n      type: 'boolean',\n      default: false,\n    },\n    indexFields: { type: mongoose.Schema.Types.Mixed },\n    options: { type: mongoose.Schema.Types.Mixed },\n    isDefault: {\n      type: 'boolean',\n      default: false,\n    },\n    indexType: { type: 'string' },\n    fields: { type: 'array' },\n    operator: { type: 'string' },\n  }],\n\n  customJson: { additionalSetting: { type: mongoose.Schema.Types.Mixed } },\n  adapter: { type: 'string' },\n  isDefault: {\n    type: 'boolean',\n    default: false,\n  },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.SCHEMA.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/SchemaDetail.js",
    "content": "const mongoose = require('mongoose');\nconst { MODULE } = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n  schemaId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.SCHEMA.MODEL_NAME,\n  },\n  name: { type: 'string' },\n  type: {\n    type: 'number',\n    default: 1,\n  },\n  schemaJson: { type: mongoose.Schema.Types.Mixed },\n  additionalJson: { type: mongoose.Schema.Types.Mixed },\n  isActive: {\n    type: 'boolean',\n    default: true,\n  },\n  isDeleted: {\n    type: 'boolean',\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(MODULE.SCHEMA_DETAIL.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Models/tenant/SchemaUploadVersion.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  MODULE, SUB_MODULE,\n} = require('../../constants/common');\n\nconst schema = new mongoose.Schema({\n\n  semanticVersion: { type: 'string' },\n  version: { type: 'string' },\n  applicationId: {\n    type: mongoose.Schema.Types.ObjectId,\n    ref: MODULE.APPLICATION.MODEL_NAME,\n  },\n  adapter: { type: 'string' },\n  isActive: {\n    type: Boolean,\n    default: true,\n  },\n  isDeleted: {\n    type: Boolean,\n    default: false,\n  },\n  createdAt: {\n    type: Date,\n    default: Date.now,\n  },\n  updatedAt: {\n    type: Date,\n    default: Date.now,\n  },\n  dataId: { type: 'string' },\n}, { timestamps: true }, { toJSON: { virtuals: true } });\nschema.index({\n  dataId: 1,\n  isActive: 1,\n  isDeleted: 1,\n});\nmodule.exports = mongoose.model(SUB_MODULE.SCHEMA_UPLOAD_VERSION.MODEL_NAME, schema);\n"
  },
  {
    "path": "packages/server/models/Repo/Connection.js",
    "content": "/* eslint-disable no-plusplus ,no-await-in-loop , no-unused-expressions ,class-methods-use-this ,no-return-await */\n/* global  _ */\nrequire('dotenv').config({ path: './variables.env' });\nconst ObjectId = require('mongodb').ObjectID;\nconst mongoose = require('mongoose');\n/*  */\n\nclass MongoAtlasRepository {\n  constructor (model) {\n    this.model = mongoose.model(model.MODEL_NAME);\n  }\n\n  /*\n   *\n   * Function used to create conditional criteria.\n   *\n   * `key` = DB collection column name.\n   * `val` = value\n   *\n   *\n   * find : { \"find\" : { key : val } }\n   * $in :  { \"in\" : [ { key : val(Array) } ] }\n   * $nin :  { \"nin\" : [ { key : val(Array) } ] }\n   * $ne :  { \"ne\" : [ { key : val } ] }\n   * populate : { \"populate\" : [ { \"{relationName | relationKey}\" : fields(Array) | null } ] }\n   * $lt(e) : { \"lt\" : [ { key : val } ] }\n   * $gt(e) : { \"gt\" : [ { key : val } ] }\n   * between : { \"between\" : [ { key : [lt_value, gt_value] } ] }\n   * between_eq : { \"between_eq\" : [ { key : [lt_value, gt_value] } ] }\n   *\n   *\n   * @param  {} filter\n   */\n  async prepareQuery (filter) {\n    let criteria = {};\n\n    // Prepare conditions for `search`.\n    if (filter && filter.search && filter.search.keys && filter.search.keyword) {\n      const searchData = [];\n      const keyword = new RegExp(filter.search.keyword, 'i');\n      filter.search.keys.forEach((value) => {\n        const data = {};\n        data[value] = keyword;\n        searchData.push(data);\n      });\n\n      if (filter?.or) {\n        filter.or = [...filter.or, ...searchData];\n      } else {\n        criteria = _.extend(criteria, { $or: searchData });\n      }\n    }\n\n    // Prepare conditions for `multiple search`.\n    if (filter && filter.multipleSearch && filter.multipleSearch.keys && filter.multipleSearch.keywords) {\n      const searchData = [];\n      _.map(filter.multipleSearch.keys, (fieldKey) => {\n        _.map(filter.multipleSearch.keywords, (val) => {\n          const sObj = {};\n          sObj[fieldKey] = new RegExp(val, 'i');\n          searchData.push(sObj);\n        });\n      });\n\n      if (filter?.or) {\n        filter.or = [...filter.or, ...searchData];\n      } else {\n        criteria = _.extend(criteria, { $or: searchData });\n      }\n    }\n\n    // Prepare conditions for `find`.\n    if (filter && filter.find) {\n      criteria = _.extend(criteria, filter.find);\n    }\n\n    // Prepare conditions for `$in`.\n    if (filter && filter.in) {\n      filter.in.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$in\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $in: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$or`.\n    if (filter && filter.or) {\n      // criteria = _.extend(criteria.$or, filter.or);\n      criteria = _.extend(criteria, { $or: filter.or });\n    }\n    // Prepare conditions for `$nin`.\n    if (filter && filter.nin) {\n      filter.nin.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$nin\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $nin: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$ne`.\n    if (filter && filter.ne) {\n      filter.ne.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$ne\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $ne: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$lt`.\n    if (filter && filter.lt) {\n      filter.lt.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$lt\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $lt: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$gt`.\n    if (filter && filter.gt) {\n      filter.gt.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$gt\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $gt: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$lte`.\n    if (filter && filter.lte) {\n      filter.lte.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$lte\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $lte: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `$gte`.\n    if (filter && filter.gte) {\n      filter.gte.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$gte\": value[key]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], { $gte: value[key] });\n        });\n      });\n    }\n\n    // Prepare conditions for `between`.\n    if (filter && filter.between) {\n      filter.between.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$gt\": value[key][0],\n           *          \"$lt\": value[key][1]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], {\n            $gt: value[key][0],\n            $lt: value[key][1],\n          });\n        });\n      });\n    }\n\n    // Prepare conditions for `between_eq`.\n    if (filter && filter.between_eq) {\n      filter.between_eq.forEach((value) => {\n        Object.keys(value).forEach((key) => {\n          /*\n           * criteria[key] = {\n           *          \"$gte\": value[key][0],\n           *          \"$lte\": value[key][1]\n           *        }\n           */\n          criteria[key] = _.extend(criteria[key], {\n            $gte: value[key][0],\n            $lte: value[key][1],\n          });\n        });\n      });\n    }\n\n    // if in criteria no isDeleted , isActive then set default\n    if (!_.has(criteria, 'isDeleted')) {\n      criteria.isDeleted = false;\n    }\n    if (!_.has(criteria, 'isActive')) {\n      criteria.isActive = true;\n    }\n    if (_.has(criteria, 'isActiveDeactivateDisplay')) {\n      criteria.isActive = { $in: [true, false] };\n    }\n    // Prepare `pagination`.\n    const paginate = await this.managePagination(filter);\n\n    // Prepare `orderBy`\n    const sortBy = await this.manageOrderBy(filter);\n\n    // Prepare `populate`.\n    const populate = await this.managePopulate(filter);\n\n    const query = {\n\n      criteria,\n      populate,\n      paginate,\n      sortBy,\n    };\n    return query;\n  }\n\n  /**\n   *\n   * Function used to manage order by.\n   *\n   * @param  {} filter\n   */\n  async manageOrderBy (filter) {\n    let sort = { createdAt: -1 };\n\n    if (filter && filter.sortBy) {\n      Object.keys(filter.sortBy).forEach((val) => {\n        if (filter.sortBy[val] === 'ASC' || filter.sortBy[val] === 'asc') {\n          filter.sortBy[val] = 1;\n        } else if (filter.sortBy[val] === 'DESC' || filter.sortBy[val] === 'desc') {\n          filter.sortBy[val] = -1;\n        }\n      });\n\n      sort = filter.sortBy;\n    }\n\n    return sort;\n  }\n\n  /**\n   * @param  {} filter\n   */\n  async managePagination (filter) {\n    const paginate = {\n      page: 0,\n      limit: 0,\n    };\n\n    if (filter && filter.page && filter.limit) {\n      paginate.page = ((filter.page * filter.limit) - filter.limit);\n      paginate.limit = filter.limit;\n    } else {\n      if (filter.skip) {\n        paginate.page = filter.skip;\n      }\n      if (filter.limit) {\n        paginate.limit = filter.limit;\n      }\n    }\n\n    return paginate;\n  }\n\n  /**\n   *\n   * Function used to manage populate data.\n   *\n   * `path` = relation name\n   * `select` = fields to be given\n   *\n   * @param  {} filter\n   */\n  async managePopulate (filter) {\n    const populates = [];\n    if (filter && filter.populate) {\n      const modelInstance = {};\n\n      let nestedModelInstance = [];\n      _.forEach(filter.populate, (val) => {\n        Object.keys(val).forEach((j) => {\n          const letInstance = _.without(_.map(val[j], 'model'), undefined);\n          if (letInstance && _.size(letInstance) > 0) {\n            nestedModelInstance.push(letInstance);\n          }\n\n          if (Array.isArray(val[j])) {\n            _.forEach(val[j], (i) => {\n              if (typeof i === 'object') {\n                Object.keys(i).forEach((k) => {\n                  const letInstance2 = _.without(_.map(i[k], 'model'), undefined);\n                  if (letInstance2 && _.size(letInstance2) > 0) {\n                    nestedModelInstance.push(letInstance2);\n                  }\n                });\n              }\n            });\n          }\n        });\n      });\n      nestedModelInstance = _.flatten(nestedModelInstance);\n\n      let crossDbPopulate = _.without(_.map(filter.populate, 'model'), undefined);\n      crossDbPopulate = _.uniq([...nestedModelInstance, ...crossDbPopulate]);\n\n      for (let index = 0; index < crossDbPopulate.length; index++) {\n        const mInstance = await this.crossDBConnect(crossDbPopulate[index]);\n        modelInstance[crossDbPopulate[index]] = mInstance;\n      }\n\n      filter.populate.forEach((value) => {\n        let populateData = {};\n\n        if (value.model) {\n          Object.keys(value).forEach(async (key) => {\n            if (key !== 'model' && key !== 'match') {\n              // =======================  Cross DB in populate  =================================\n              const selectFields = [];\n              let fPopulate = null;\n              value[key].forEach((dt) => {\n                if (_.isObject(dt)) {\n                  Object.keys(dt).forEach(async (k1) => {\n                    if (k1 !== 'model' && k1 !== 'match') {\n                      const nestedSelectFields = [];\n                      let nestedFPopulate = [];\n                      dt[k1].forEach((dts) => {\n                        if (_.isObject(dts)) {\n                          Object.keys(dts).forEach(async (k2) => {\n                            if (k2 !== 'model' && k2 !== 'match') {\n                              nestedFPopulate = {\n                                path: k2,\n                                select: _.filter(dts[k2], (o) => {\n                                  if (typeof o === 'string') return o;\n                                  return false;\n                                }).join(' '),\n                                model: dts.model,\n                                match: dts.match,\n                              };\n                            }\n                          });\n                        } else {\n                          nestedSelectFields.push(dts);\n                        }\n                      });\n\n                      fPopulate = {\n                        path: k1,\n                        select: nestedSelectFields,\n                        model: dt.model,\n                        match: dt.match,\n                        populate: nestedFPopulate,\n                      };\n                    }\n                  });\n                } else {\n                  selectFields.push(dt);\n                }\n              });\n\n              populateData = {\n                path: key,\n                select: selectFields ? selectFields.join(' ') : null,\n                model: modelInstance[value.model],\n                match: value.match,\n                populate: fPopulate,\n              };\n            }\n\n            if (populateData && Object.keys(populateData).length > 1) {\n              populates.push(populateData);\n            }\n          });\n        } else {\n          Object.keys(value).forEach(async (key) => {\n            let isNestedPopulate = false;\n            _.map(value[key], (val) => {\n              if (_.isObject(val)) {\n                isNestedPopulate = true;\n              }\n            });\n\n            // Nested Populate Logic\n            if (isNestedPopulate === true) {\n              const parentSelectKeys = _.filter(value[key], (o) => _.isString(o));\n\n              const populateLevel1Array = [];\n\n              _.forEach(value[key], (pl1Values) => {\n                if (_.isObject(pl1Values)) {\n                  _.forEach(pl1Values, (pl1Value, pl1Key) => {\n                    const tempPopulate = {};\n\n                    const populateLevel1SelectKeys = _.filter(pl1Value, (o) => _.isString(o));\n\n                    if (pl1Key !== 'model' && pl1Key !== 'match') {\n                      tempPopulate.path = pl1Key;\n                      tempPopulate.select = populateLevel1SelectKeys ? populateLevel1SelectKeys.join(' ') : null;\n                      tempPopulate.match = pl1Values.match;\n                      tempPopulate.model = modelInstance[pl1Values.model];\n                    }\n\n                    // Add Second level population\n                    const populateLevel2Array = [];\n                    if (pl1Key !== 'match') {\n                      _.forEach(pl1Value, (pl1v) => {\n                        if (_.isObject(pl1v)) {\n                          _.map(pl1v, (pl2Value, pl2Key) => {\n                            const tempPopulate2 = {};\n\n                            const populateLevel2SelectKeys = _.filter(pl2Value, (o) => _.isString(o));\n\n                            if (pl2Key !== 'model' && pl2Key !== 'match') {\n                              tempPopulate2.path = pl2Key;\n                              tempPopulate2.select = populateLevel2SelectKeys ? populateLevel2SelectKeys.join(' ') : null;\n                              tempPopulate2.match = pl1v.match;\n                              tempPopulate2.model = modelInstance[pl1v.model];\n                            }\n\n                            if (tempPopulate2 && Object.keys(tempPopulate2).length > 0) {\n                              populateLevel2Array.push(tempPopulate2);\n                            }\n                          });\n                        }\n                      });\n                    }\n\n                    if (_.isEmpty(populateLevel2Array) === false) {\n                      tempPopulate.populate = populateLevel2Array;\n                    }\n\n                    if (tempPopulate && Object.keys(tempPopulate).length > 0) {\n                      populateLevel1Array.push(tempPopulate);\n                    }\n                  });\n                }\n              });\n\n              populateData = {\n                path: key,\n                select: parentSelectKeys ? parentSelectKeys.join(' ') : null,\n                match: value.match,\n              };\n              if (_.isEmpty(populateLevel1Array) === false) {\n                populateData = _.extend(populateData, { populate: populateLevel1Array });\n              }\n\n              /*\n               * let parentSelectKeys = _.filter(value[key], function (o) { return _.isString(o); });\n               *\n               *            let populateLevel1Array = [];\n               *\n               *            _.forEach(value[key], function (pl1Values) {\n               *\n               *              if (_.isObject(pl1Values)) {\n               *\n               *                _.forEach(pl1Values, function (pl1Value, pl1Key) {\n               *\n               *                  let tempPopulate = {};\n               *\n               *                  let populateLevel1SelectKeys = _.filter(pl1Value, function (o) { return _.isString(o); });\n               *\n               *                  tempPopulate.path = pl1Key;\n               *                  tempPopulate.select = populateLevel1SelectKeys ? populateLevel1SelectKeys.join(\" \") : null\n               *\n               *                  //Add Second level population\n               *                  let populateLevel2Array = [];\n               *                  _.forEach(pl1Value, function (pl1v) {\n               *                    if (_.isObject(pl1v)) {\n               *                      _.map(pl1v, function (pl2Value, pl2Key) {\n               *                        let tempPopulate2 = {};\n               *\n               *                        let populateLevel2SelectKeys = _.filter(pl2Value, function (o) { return _.isString(o); });\n               *                        tempPopulate2.path = pl2Key;\n               *                        tempPopulate2.select = populateLevel2SelectKeys ? populateLevel2SelectKeys.join(\" \") : null\n               *\n               *                        populateLevel2Array.push(tempPopulate2);\n               *\n               *                      });\n               *                    }\n               *                  });\n               *                  if (_.isEmpty(populateLevel2Array) === false) {\n               *                    tempPopulate.populate = populateLevel2Array;\n               *                  }\n               *                  populateLevel1Array.push(tempPopulate);\n               *                });\n               *              }\n               *            });\n               *            populateData = {\n               *              path: key,\n               *              select: parentSelectKeys ? parentSelectKeys.join(\" \") : null\n               *            }\n               *            if (_.isEmpty(populateLevel1Array) === false) {\n               *              populateData = _.extend(populateData, { populate: populateLevel1Array })\n               *            }\n               */\n            } else if (key && key !== 'match') {\n              populateData = {\n                path: key,\n                select: value[key] ? value[key]?.join(' ') : null,\n                match: value.match,\n              };\n            }\n          });\n          populates.push(populateData);\n        }\n      });\n    }\n\n    return populates;\n  }\n\n  // Basic CRUD\n  /**\n   *\n   * Function used to create.\n   *\n   * @param  {} insertData\n   */\n  async create (insertData) {\n    const result = await this.model.create(insertData);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to delete data.\n   *\n   * @param  {} id\n   */\n  async deleteById (id) {\n    const filter = { _id: ObjectId(id) };\n    const result = await this.model.deleteOne(filter);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to get data by Id.\n   *\n   * @param  {} options {id,fields}\n   */\n  async getById (options) {\n    const filter = {\n      _id: ObjectId(options.id),\n      isDeleted: false,\n      isActive: true,\n    };\n    const fields = options.fields ? options.fields.join(' ') : null;\n    const result = await this.model.findOne(filter, fields);\n    return result;\n  }\n\n  async insertMany (data) {\n    const result = await this.model.insertMany(data);\n    return result;\n  }\n\n  async getOne (options) {\n    const fields = options.fields ? options.fields.join(' ') : null;\n    let filterOptions = options;\n    if (options.filter) {\n      filterOptions = options.filter;\n    }\n    const query = await this.prepareQuery(filterOptions);\n    const result = await this.model.findOne(query.criteria).select(fields)\n      .populate(query.populate)\n      .lean();\n    return result;\n  }\n\n  /**\n   *\n   * Function used to update data by Id.\n   *\n   * @param  {} id\n   * @param  {} data\n   */\n  async updateById (id, data) {\n    const filter = { _id: ObjectId(id) };\n    const result = await this.model.findByIdAndUpdate(filter, { $set: data }, {\n      new: true,\n      useFindAndModify: false,\n    });\n    return result;\n  }\n\n  /**\n   *\n   * Function used to update single document.\n   *\n   * @param  {} options\n   * @param  {} data\n   */\n  async updateOne (options, data) {\n    let filterOptions = options;\n    if (options.filter) {\n      filterOptions = options.filter;\n    }\n    const query = await this.prepareQuery(filterOptions);\n    const result = await this.model.findOneAndUpdate(query.criteria, { $set: data }, {\n      new: true,\n      upsert: true,\n    });\n    return result;\n  }\n\n  async createOrUpdate (data, keys) {\n    const query = {};\n    keys.forEach((key) => {\n      query[key] = data[key];\n    });\n    const result = await this.model.findOneAndUpdate(query, data, {\n      new: true,\n      upsert: true,\n    });\n    return result;\n  }\n\n  /**\n   *\n   * Function used to get details.\n   *\n   * @param  {} filter\n   */\n  async getDetails (filter) {\n    const fields = (filter && filter.fields) ? filter.fields : '';\n    const query = await this.prepareQuery(filter);\n    const result = await this.model.find(query.criteria).select(fields)\n      .populate(query.populate)\n      .skip(query.paginate.page)\n      .limit(query.paginate.limit)\n      .sort(query.sortBy)\n      .lean();\n    return result;\n  }\n\n  async getAll (filter) {\n    const result = await this.model.find({})\n      .sort(filter);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to get count.\n   *\n   * @param  {} filter\n   */\n  async getCount (filter) {\n    const query = await this.prepareQuery(filter);\n    const result = await this.model.countDocuments(query.criteria);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to update multiple records.\n   * @param  {} options\n   */\n  async updateMany (options) {\n    let filterOptions = options;\n    if (options.filter) {\n      filterOptions = options.filter;\n    }\n    const query = await this.prepareQuery(filterOptions);\n    const result = await this.model.updateMany(query.criteria, { $set: options.data }, { new: true });\n    return result;\n  }\n\n  /**\n   *\n   * Function used to delete multiple records.\n   *\n   * @param  {} options\n   */\n  async deleteMany (filter) {\n    const query = await this.prepareQuery(filter);\n    const result = await this.model.deleteMany(query.criteria);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to execute aggregate query.\n   * @param  {} options\n   */\n  async aggregate (options) {\n    const result = await this.model.aggregate(options.queryStages);\n    return result;\n  }\n\n  async deleteOne (filter) {\n    const result = await this.model.deleteOne(filter);\n    return result;\n  }\n\n  /**\n   *\n   * Function used to update multiple records with raw query.\n   * @param  {} options\n   */\n  async rawUpdateMany (options) {\n    const query = await this.prepareQuery(options.filter);\n    const result = await this.model.updateMany(query.criteria, options.data, { new: true });\n    return result;\n  }\n}\nmodule.exports = MongoAtlasRepository;\n"
  },
  {
    "path": "packages/server/models/Repo/index.js",
    "content": "const mongoose = require('mongoose');\nconst MongoAtlasRepository = require('./Connection');\n\nclass CommonQueryRepository extends MongoAtlasRepository {\n  constructor (model) {\n    super(model);\n    this.model = mongoose.model(model.MODEL_NAME);\n  }\n\n  async getById (options) {\n    const result = await super.getById(options);\n    return result;\n  }\n\n  // Revised function with Response object\n\n  async getDetails (filter) {\n    const result = await super.getDetails(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async get (filter) {\n    const result = await super.getOne(filter);\n    if (result && result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async create (data) {\n    const result = await super.create(data);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async update (id, data) {\n    const result = await super.updateById(id, data);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async deleteById (userId) {\n    const result = await super.deleteById(userId);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async getCount (filter) {\n    const result = await super.getCount(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async search (filter) {\n    const result = await this.model.findOne({ $or: [{ username: filter.search }, { seriesNo: filter.search }] }).select(filter.fields).populate(filter.populate);\n    if (result && result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async deleteMany (filter) {\n    const result = await super.deleteMany(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async updateMany (filter) {\n    const result = await super.updateMany(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async insertMany (data) {\n    const result = await super.insertMany(data);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async rawUpdateMany (filter) {\n    const result = await super.rawUpdateMany(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async aggregate (options) {\n    const result = await super.aggregate(options);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async updateOne (filter, data) {\n    const result = await super.updateOne(filter, data);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async getAll (filter) {\n    const result = await super.getAll(filter);\n    if (result?.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n}\n\nmodule.exports = CommonQueryRepository;\n"
  },
  {
    "path": "packages/server/models/constants/action.js",
    "content": "module.exports = {\n  VIEW: 'VIEW',\n  UPDATE: 'UPDATE',\n  DELETE: 'DELETE',\n  CREATE: 'CREATE',\n  DOWNLOAD: 'DOWNLOAD',\n  BUILD: 'BUILD',\n};\n"
  },
  {
    "path": "packages/server/models/constants/activityLog.js",
    "content": "module.exports = [\n  {\n    url: '/web/v1/application-config/paginate',\n    model: 'applicationConfig',\n    action: 'paginate',\n  },\n  {\n    url: '/web/v1/project-constant/paginate',\n    model: 'projectConstant',\n    action: 'paginate',\n  },\n];\n"
  },
  {
    "path": "packages/server/models/constants/application.js",
    "content": "module.exports = {\n  IN_PROCESS_STATUS: {\n    IN_QUEUE: 1,\n    IN_PROCESS: 2,\n    COMPLETED: 3,\n    FAILED: 4,\n    QUEUE_BUILD_REJECTED: 5,\n  },\n  DEFAULT_POLICY_NAME: 'auth',\n  DEFAULT_POLICY_DESCRIPTION: 'Auto generated policy for authentication module in a read only mode.',\n  DEFAULT_POLICY: `const passport = require('passport');\n    const { ROLE_RIGHTS, USER_ROLE } = require('../config/authConstant');\n    const util = require(\"../utils/messages\");\n    \n    const verifyCallback = (req, resolve, reject, requiredRights) => async (err, user, info) => {\n        if (err || info || !user) {\n            return reject(\"Unauthorized User\");\n        }\n        req.user = user;\n        if (!user.isActive) {\n            return reject(\"User is deactivated\");\n        }\n        if (requiredRights.length) {\n            for(role in USER_ROLE){\n                if(USER_ROLE[role]===user.role){\n                    const userRights = ROLE_RIGHTS[user.role];\n                    const hasRequiredRights = requiredRights.some((requiredRight) => userRights.includes(requiredRight));\n                    if (!hasRequiredRights || !user.id) {\n                        return reject('Unauthorized user');\n                    }\n                }\n            }\n        }\n        resolve();\n    };\n    \n    const auth = (...requiredRights) => async (req, res, next) => {\n    \n    let url =req.originalUrl;\n    \n                if(url.includes('admin')){\n                    return new Promise((resolve, reject) => {\n                        passport.authenticate('admin-rule', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(\n                            req,\n                            res,\n                            next\n                        );\n                    })\n                    .then(() => next())\n                    .catch((err) => {\n                        return util.unAuthorizedRequest(err,res);\n                     });\n                }\n    \n                else if(url.includes('device')){\n                    return new Promise((resolve, reject) => {\n                        passport.authenticate('device-rule', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(\n                            req,\n                            res,\n                            next\n                        );\n                    })\n                    .then(() => next())\n                    .catch((err) => {\n                        return util.unAuthorizedRequest(err,res);\n                     });\n                }\n    \n                else if(url.includes('client')){\n                    return new Promise((resolve, reject) => {\n                        passport.authenticate('client-rule', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(\n                            req,\n                            res,\n                            next\n                        );\n                    })\n                    .then(() => next())\n                    .catch((err) => {\n                        return util.unAuthorizedRequest(err,res);\n                     });\n                }\n    \n                else if(url.includes('desktop')){\n                    return new Promise((resolve, reject) => {\n                        passport.authenticate('desktop-rule', { session: false }, verifyCallback(req, resolve, reject, requiredRights))(\n                            req,\n                            res,\n                            next\n                        );\n                    })\n                    .then(() => next())\n                    .catch((err) => {\n                        return util.unAuthorizedRequest(err,res);\n                     });\n                }\n    \n    \n    };\n    module.exports = auth;`,\n\n  DEFAULT_CONSTANT_NAME: 'authConstant',\n  DEFAULT_CONSTANT_DESCRIPTION: 'Auto generated constant for authentication module in a read only mode.',\n  DEFAULT_CONSTANT: {\n    JWT: {\n      ADMIN_SECRET: 'myjwtadminsecret',\n      DEVICE_SECRET: 'myjwtdevicesecret',\n      CLIENT_SECRET: 'myjwtclientsecret',\n      DESKTOP_SECRET: 'myjwtdesktopsecret',\n      EXPIRES_IN: 10000,\n    },\n    USER_ROLE: {\n      Admin: 1,\n      User: 2,\n    },\n    PLATFORM: {\n      ADMIN: 1,\n      DEVICE: 2,\n      CLIENT: 3,\n      DESKTOP: 4,\n    },\n    DEFAULT_ROLE: 1,\n  },\n  ORM_TYPE: {\n    MONGOOSE: 1,\n    SEQUELIZE: 2,\n    ELOQUENT: 3,\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/applicationConfig.js",
    "content": "module.exports = {\n  ORM_TYPE: {\n    MONGOOSE: 1,\n    SEQUELIZE: 2,\n    ELOQUENT: 3,\n  },\n  DATABASE_TYPE: {\n    MONGODB: 1,\n    SQL: 2,\n    MYSQL: 3,\n    POSTGRE_SQL: 4,\n  },\n  FILE_TYPES: {\n    FILE: 1,\n    DIRECTORY: 2,\n  },\n  APPLICATION_ID_URL: ['/web/v1/application/download-zip'],\n  GENERATOR_ORM_TYPE: {\n    1: 'mongoose',\n    2: 'sequelize',\n  },\n  GENERATOR_DATABASE_TYPE: {\n    1: 'mongodb',\n    2: 'mssql',\n    3: 'mysql',\n    4: 'postgres',\n  },\n  FIRE_STORE_SCHEMA_TYPE: {\n    COLLECTION: 1,\n    RULES: 2,\n  },\n  SCREEN_WISE_DATA_TYPE: {\n    SCREEN_NAME_CHANGE: 1,\n    SPLASH_SCREEN: 2,\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/common.js",
    "content": "module.exports = {\n  MODULE: {\n    MASTER: {\n      VALUE: 3,\n      MODEL_NAME: 'masters',\n      LOG_ATTRIBUTES: ['name', 'code'],\n      GLOBAL_SEARCH_KEYS: ['code', 'slug', 'name'],\n    },\n    PROJECT: {\n      VALUE: 7,\n      MODEL_NAME: 'project',\n    },\n    SCHEMA: {\n      VALUE: 8,\n      MODEL_NAME: 'schema',\n    },\n    GENERATOR: {\n      VALUE: 9,\n      MODEL_NAME: 'generator',\n    },\n    SCHEMA_DETAIL: {\n      VALUE: 10,\n      MODEL_NAME: 'schema-detail',\n    },\n    APPLICATION: {\n      VALUE: 11,\n      MODEL_NAME: 'application',\n    },\n    PROJECT_DEFINITION: {\n      VALUE: 13,\n      MODEL_NAME: 'project-definition',\n    },\n    RAW_MODEL: {\n      VALUE: 15,\n      MODEL_NAME: 'raw-model',\n    },\n    PROJECT_ROUTE: {\n      VALUE: 17,\n      MODEL_NAME: 'projectRoute',\n    },\n    PROJECT_CONSTANT: {\n      VALUE: 18,\n      MODEL_NAME: 'projectConstant',\n    },\n    PROJECT_POLICY: {\n      VALUE: 20,\n      MODEL_NAME: 'projectPolicy',\n    },\n    APPLICATION_CONFIG: {\n      VALUE: 24,\n      MODEL_NAME: 'applicationConfig',\n    },\n    ENV_VARIABLES: {\n      VALUE: 31,\n      MODEL_NAME: 'env-variables',\n    },\n    QUERY_BUILDER: {\n      VALUE: 39,\n      MODEL_NAME: 'query-builders',\n    },\n    PROJECT_ROLE_ACCESS_PERMISSIONS: {\n      VALUE: 46,\n      MODEL_NAME: 'project-role-access-permissions',\n    },\n    NESTED_QUERY_BUILDER: {\n      VALUE: 51,\n      MODEL_NAME: 'nested-query-builder',\n    },\n    SETTING: {\n      VALUE: 60,\n      MODEL_NAME: 'settings',\n    },\n  },\n  SUB_MODULE: {\n    SCHEMA_UPLOAD_VERSION: {\n      VALUE: 112,\n      MODEL_NAME: 'schema-upload-versions',\n    },\n  },\n  SOURCE_MEDIUM: {\n    WEB: 1,\n    ANDROID: 2,\n    IOS: 3,\n    DESKTOP: 4,\n  },\n  ACTION: {\n    ADD: 1,\n    UPDATE: 2,\n    DELETE: 3,\n  },\n  ERROR_LOGS_TYPE: {\n    FRONT: 1,\n    BACK: 2,\n  },\n\n  TWO_FA_AUTHENTICATION_TYPE: { OTP: 1 },\n\n  RESPONSE_CODE: {\n    OK: 'OK',\n    NOT_FOUND: 'E_NOT_FOUND',\n    BAD_REQUEST: 'E_BAD_REQUEST',\n    ERROR: 'E_ERROR',\n    FORBIDDEN: 'E_FORBIDDEN',\n    SERVER_ERROR: 'E_INTERNAL_SERVER_ERROR',\n    UNAUTHORIZED: 'E_UNAUTHORIZED',\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/jobQueue.js",
    "content": "module.exports = {\n  JOB_QUEUE: {\n    STATUS: {\n      IN_QUEUE: 1,\n      PROCESSING: 2,\n      FINISHED: 3,\n      FAILED: 4,\n      ON_HOLD: 5,\n    },\n    TYPE: {\n      ORDER_GENERATE: 1,\n      TODO_ACTION: 2,\n    },\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/master.js",
    "content": "module.exports = {\n  MASTER_MEDIUM: { GENERAL: 1 },\n  MASTER_PARENT_CODES: { SOCIAL_AUTH: 'SOCIAL_AUTH' },\n};\n"
  },
  {
    "path": "packages/server/models/constants/message.js",
    "content": "module.exports = {\n  MESSAGE: {\n    ALREADY_EXISTS: {\n      code: 'E_DUPLICATE',\n      message: 'data already exists.',\n      status: 200,\n    },\n    OK: {\n      code: 'OK',\n      message: 'Operation is successfully executed',\n      status: 200,\n    },\n    BAD_REQUEST: {\n      code: 'E_BAD_REQUEST',\n      message: 'The request cannot be fulfilled due to bad syntax',\n      status: 400,\n    },\n    UNAUTHORIZED: {\n      code: 'E_UNAUTHORIZED',\n      message: 'You are not authorized to perform this action.',\n      status: 401,\n    },\n    UNAUTHORIZED_ACTION: {\n      code: 'E_BAD_REQUEST',\n      message: 'You are not authorized to perform this action.',\n      status: 400,\n    },\n    PERMISSION_NOT_FOUND: {\n      code: 'PERMISSION_NOT_FOUND',\n      message: 'We are not able to find permission for this action.',\n      status: 400,\n    },\n    FORBIDDEN: {\n      code: 'E_FORBIDDEN',\n      message: 'Access Denied You don`t have permission to access.',\n      status: 403,\n    },\n    NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'The requested resource could not be found but may be available again in the future.',\n      status: 404,\n    },\n    SERVER_ERROR: {\n      code: 'E_INTERNAL_SERVER_ERROR',\n      message: 'Something bad happened on the server',\n      status: 500,\n    },\n    ERROR: {\n      code: 'E_ERROR',\n      message: 'Something went wrong, Please try again',\n      status: 400,\n    },\n    USERNAME_REGISTERED: {\n      code: 'E_DUPLICATE',\n      message: 'Username already registered.',\n      status: 200,\n    },\n    USER_NOT_FOUND: {\n      code: 'E_USER_NOT_FOUND',\n      message: 'User with specified credentials is not found',\n      status: 404,\n    },\n    RESET_PASSWORD_LINK_EXPIRE: {\n      code: 'E_BAD_REQUEST',\n      message: 'Your reset password link is expired or invalid',\n      status: 400,\n    },\n    RESET_PASSWORD_LINK: {\n      code: 'OK',\n      message: 'Please check your email to reset password.',\n      status: 200,\n    },\n    USER_PASSWORD_RESET: {\n      code: 'OK',\n      message: 'Password reset successfully.',\n      status: 200,\n    },\n    SESSION_EXPIRE: {\n      code: 'E_UNAUTHORIZED',\n      message: 'Your current session has expired',\n      status: 401,\n    },\n    USER_NOT_ACTIVE: {\n      code: 'E_UNAUTHORIZED',\n      message: 'User not active.',\n      status: 200,\n    },\n    INVALID_DEVICE: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invalid device for the requested user.',\n      status: 400,\n    },\n    LOGOUT: {\n      code: 'OK',\n      message: 'Successfully logout.',\n      status: 200,\n    },\n    EMAIL_PASS_NOT_MATCHED: {\n      code: 'E_BAD_REQUEST',\n      message: 'You\\'ve entered an invalid password. Please check and try again.',\n      status: 200,\n    },\n    DUPLICATE_DEVICE_ID: {\n      code: 'E_BAD_REQUEST',\n      message: 'Order is already generated. Please visit Digital Binder to view the order.',\n      status: 200,\n    },\n    UNAUTHORIZED_USER_X_RAY: {\n      code: 'E_BAD_REQUEST',\n      message: 'You are not authorized to create request for this x-ray.',\n      status: 400,\n    },\n\n    INVALID_TOKEN: {\n      code: 'E_INVALID_TOKEN',\n      message: 'Invalid token.',\n      status: 401,\n    },\n\n    FAILED_TO_EXEC_CHHOMD_CMD: {\n      code: 'ERROR',\n      message: 'Failed to execute chmod command.',\n      status: 400,\n    },\n\n    INVALID_FILE_MIMETYPE: {\n      code: 'OERROR',\n      message: 'Invalid file type.',\n      status: 400,\n    },\n    VALID_FILE_MIMETYPE: {\n      code: 'OK',\n      message: 'Valid file mime type.',\n      status: 200,\n    },\n    AWS_S3_FILE_UPLOAD_ISSUE: {\n      code: 'ERROR',\n      message: 'File not uploaded to S3, plz try again later.',\n      status: 400,\n    },\n    AWS_S3_FILE_UPLOAD_SUCCESS: {\n      code: 'OK',\n      message: 'File uploaded successfully.',\n      status: 200,\n    },\n\n    OTP_EXPIRE: {\n      code: 'E_BAD_REQUEST',\n      message: 'Your OTP has expired.',\n      status: 400,\n    },\n    OTP_VERIFIED: {\n      code: 'OK',\n      message: 'Your OTP is verified.',\n      status: 200,\n    },\n    INVALID_OTP: {\n      code: 'E_BAD_REQUEST',\n      message: 'You\\'ve entered an incorrect OTP. Please check and try again.',\n      status: 400,\n    },\n    VERSION_UPDATE_SUCCESS: {\n      code: 'OK',\n      message: 'Version detail successfully updated.',\n      status: 200,\n    },\n    VERSION_CREATE_FAILED: {\n      code: 'E_INTERNAL_SERVER_ERROR',\n      message: 'Failed to added Version.',\n      status: 200,\n    },\n    VERSION_DELETED: {\n      code: 'OK',\n      message: 'Version(s) deleted successfully.',\n      status: 200,\n    },\n    VERSION_ALREADY_EXISTS: {\n      code: 'E_DUPLICATE',\n      message: 'Version with same version already exists.',\n      status: 200,\n    },\n    VERSION_APKS_ALREADY_EXISTS: {\n      code: 'E_DUPLICATE',\n      message: 'Apks with same version already exists.',\n      status: 200,\n    },\n    VERSION_DEVICES_ALREADY_EXISTS: {\n      code: 'E_DUPLICATE',\n      message: 'Devices with same version already exists.',\n      status: 200,\n    },\n    VERSION_STILL_ACTIVE: {\n      code: 'E_DUPLICATE',\n      message: 'You cant delete current active version.',\n      status: 200,\n    },\n    VERSION_CREATE_SUCCESS: {\n      code: 'OK',\n      message: 'Version Created Successfully.',\n      status: 200,\n    },\n    VERSION_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Not Found.',\n      status: 200,\n    },\n\n    EMAIL_REGISTERED: {\n      code: 'E_DUPLICATE',\n      message: 'Email already registered.',\n      status: 200,\n    },\n\n    INVITATION_ACCEPTED: {\n      code: 'E_BAD_REQUEST',\n      message: 'Invitation already accepted.',\n      status: 200,\n    },\n\n    DE_ACTIVE_USER: {\n      code: 'E_UNAUTHORIZED',\n      message: 'Your account is de-active.',\n      status: 401,\n    },\n    ACTIVE_SUBSCRIPTION_PLAN_NOT_FOUND: {\n      code: 'E_NOT_FOUND',\n      message: 'Active subscription plan not found.',\n      status: 200,\n    },\n    PROJECT_PLAN_LIMIT_OVER: {\n      code: 'OK',\n      message: 'You cant create new project.',\n      status: 200,\n    },\n    PLAN_DOWNGRADE: {\n      code: 'E_BAD_REQUEST',\n      message: 'Sorry, you can not downgrade your plan. Contact support for more information.',\n      status: 400,\n    },\n    DE_ACTIVE_USER_FROM_COMPANY: {\n      code: 'DE_ACTIVE_USER_FROM_COMPANY',\n      message: 'You have been deactivated from this workspace.',\n      status: 401,\n    },\n    REMOVED_FROM_WORKSPACE: {\n      code: 'REMOVE_USER_FROM_COMPANY',\n      message: 'Your are no longer part of this workspace',\n      status: 401,\n    },\n    DE_ACTIVE_COMPAND_FOUND_AND_DEFAULT_COMPANY_CHANGED: {\n      code: 'DE_ACTIVE_COMPAND_FOUND_AND_DEFAULT_COMPANY_CHANGED',\n      message: 'The company you are trying to sign in is not longer active. Your default company has been changed',\n      status: 400,\n    },\n    DE_ACTIVE_COMPAND_FOUND: {\n      code: 'DE_ACTIVE_COMPAND_FOUND',\n      message: 'The company you are trying to sign in is not longer active.',\n      status: 400,\n    },\n    USER_TYPE_NOT_FOUND: {\n      code: 'USER_TYPE_NOT_FOUND',\n      message: 'We are not able to find user type.',\n      status: 404,\n    },\n    USER_PLAN_NOT_FOUND: {\n      code: 'USER_PLAN_NOT_FOUND',\n      message: 'We are not able to find user plan.',\n      status: 404,\n    },\n    APPLICATION_UNASSIGNED: {\n      code: 'APPLICATION_UNASSIGNED',\n      message: 'You are no longer authorized to access this application.',\n      status: 400,\n    },\n    PERMISSION_NOT_FOUND_FOR_USER: {\n      code: 'PERMISSION_NOT_FOUND_FOR_USER',\n      message: 'We are not able to find permission.',\n      status: 400,\n    },\n    TOKEN_EXPIRED: {\n      code: 'TOKEN_EXPIRED',\n      message: 'Token Expired.',\n      status: 400,\n    },\n    TOO_MANY_REQUEST: {\n      code: 'TOO_MANY_REQUEST',\n      message: 'Too Many Request',\n      status: 400,\n    },\n    UNVERIFIED_EMAIL_ID: {\n      code: 'E_BAD_REQUEST',\n      message: 'Please verify your email address.',\n      status: 400,\n    },\n    APPLICATION_IS_DELETED: {\n      code: 'APPLICATION_IS_DELETED',\n      message: 'Selected application is deleted.',\n      status: 400,\n    },\n    INVALID_EMAIL_OR_PASSWORD: {\n      code: 'E_USER_NOT_FOUND',\n      message: 'Email address or password is invalid. Please check and try again.',\n      status: 404,\n    },\n    ACCOUNT_BLOCKED: {\n      code: 'ACCOUNT_BLOCKED',\n      message: 'Your account has been blocked for multiple wrong password attempts.',\n      status: 404,\n    },\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/method.js",
    "content": "module.exports = {\n\n  PUT: 'PUT',\n  POST: 'POST',\n  GET: 'GET',\n  DELETE: 'DELETE',\n\n};\n"
  },
  {
    "path": "packages/server/models/constants/permission.js",
    "content": "const {\n  MODULE, SERVICE, SUB_MODULE,\n} = require('./common');\nconst ACTION = require('./action');\nconst METHOD = require('./method');\n\nmodule.exports = [\n\n  // Project\n  {\n    url: '/web/v1/project/create',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.CREATE,\n  },\n  {\n    url: '/web/v1/project/paginate',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/project',\n    method: METHOD.PUT,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project',\n    method: METHOD.VIEW,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/project/destroy',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.DELETE,\n  },\n  {\n    url: '/web/v1/project/upload-logo',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.CREATE,\n  },\n\n  // Application\n  {\n    url: '/web/v1/application/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.CREATE,\n  },\n  {\n    url: '/web/v1/application/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application/generate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.BUILD,\n  },\n  {\n    url: '/web/v1/application/structure',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application/view-file',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.DELETE,\n  },\n  {\n    url: '/web/v1/application/upload-folder',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.CREATE,\n  },\n  {\n    url: '/web/v1/application/upload-logo',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application/react-command-executer',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  {\n    url: '/web/v1/application/download-zip',\n    method: METHOD.GET,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.DOWNLOAD,\n  },\n  {\n    url: '/web/v1/application/app-process-logs',\n    method: METHOD.GET,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application/html-upload-folder',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application/update-file-code',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application/view-file-input',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application/update-file-input',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // Member Manage\n  {\n    url: '/web/v1/application/member-update',\n    method: METHOD.PUT,\n    module: SERVICE.MEMBER.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application/member-list',\n    method: METHOD.POST,\n    module: SERVICE.MEMBER.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/application/member-delete',\n    method: METHOD.DELETE,\n    module: SERVICE.MEMBER.VALUE,\n    action: ACTION.DELETE,\n  },\n  // Invite User\n  {\n    url: '/web/v1/application/invite',\n    method: METHOD.PUT,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.CREATE,\n  },\n  {\n    url: '/web/v1/user/remove-invited-member',\n    method: METHOD.POST,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.DELETE,\n  },\n  {\n    url: '/web/v1/company-invites/invite-user-list',\n    method: METHOD.POST,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.CREATE,\n  },\n  {\n    url: '/web/v1/company-invites/resend-invitation',\n    method: METHOD.POST,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/company-invites/delete-invitation',\n    method: METHOD.POST,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.DELETE,\n  },\n  {\n    url: '/web/v1/company-invites/remove-invited-user',\n    method: METHOD.PUT,\n    module: SUB_MODULE.COMPANY_INVITES.VALUE,\n    action: ACTION.DELETE,\n  },\n\n  // Schema\n  {\n    url: '/web/v1/schema/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // Schema-Detail\n  {\n    url: '/web/v1/schema-detail/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema-detail/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema-detail/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/schema-detail',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // stared-project\n  {\n    url: '/web/v1/stared-project/upsert',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/stared-project/paginate',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.VIEW,\n  },\n  {\n    url: '/web/v1/stared-project/destroy',\n    method: METHOD.POST,\n    module: MODULE.PROJECT.VALUE,\n    action: ACTION.DELETE,\n  },\n  // project-route\n  {\n    url: '/web/v1/project-route/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-route/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-route/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-route',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // project-constant\n  {\n    url: '/web/v1/project-constant/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-constant/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-constant/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-constant',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // project-cron\n  {\n    url: '/web/v1/project-cron/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-cron/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-cron/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-cron',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // project-policy\n  {\n    url: '/web/v1/project-policy/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-policy/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-policy/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/project-policy',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // document\n  {\n    url: '/web/v1/document/get-postman-collection',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // application-config\n  {\n    url: '/web/v1/application-config/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application-config/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application-config/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/application-config',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  {\n    url: '/web/v1/application-config',\n    method: METHOD.GET,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n  // notification-template-tags\n  {\n    url: '/web/v1/notification-template-tags/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template-tags/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template-tags/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template-tags',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // notification-template\n  {\n    url: '/web/v1/notification-template/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/notification-template',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // device-action\n  {\n    url: '/web/v1/device-action/create',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/device-action/paginate',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/device-action/destroy',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/device-action',\n    method: METHOD.PUT,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // env-variables\n  {\n    url: '/web/v1/env-variables/upsert',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/env-variables/details',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  // app-global-headers\n  {\n    url: '/web/v1/app-global-headers/upsert',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n  {\n    url: '/web/v1/app-global-headers/details',\n    method: METHOD.POST,\n    module: MODULE.APPLICATION.VALUE,\n    action: ACTION.UPDATE,\n  },\n\n];\n"
  },
  {
    "path": "packages/server/models/constants/project.js",
    "content": "module.exports = {\n  TYPE: { DEFAULT: 1 },\n  PROJECT_INTERFACE_TYPE: {\n    OWNER: 1,\n    MAINTAINER: 2,\n    DEVELOPER: 3,\n    GUEST: 5,\n  },\n  ROUTE_GENERATE_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  CONSTANT_GENERATE_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  CRON_GENERATE_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  POLICY_GENERATE_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  DEVICE_ACTION_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  PROCESS_STEP_TYPE: {\n    PENDING: 1,\n    COMPLETE: 2,\n  },\n  TAG_COMPONENT_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  ACTION_VALIDATION_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  CONVERTED_VIEW_DETAIL: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  CUSTOM_ACTION_VALIDATION_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n  SCREEN_WISE_INFO_TYPE: {\n    AUTO: 1,\n    MANUAL: 2,\n  },\n};\n"
  },
  {
    "path": "packages/server/models/constants/projectDefinition.js",
    "content": "module.exports = { PROJECT_DEFINITION_CODE: { NODE_EXPRESS: 'NODE_EXPRESS' } };\n"
  },
  {
    "path": "packages/server/models/constants/version.js",
    "content": "module.exports = {\n  service: {\n    version: {\n      PLATFORM: {\n        WINDOWS_PLATFORM: 1,\n        ANDROID_PLATFORM: 2,\n        IOS_PLATFORM: 3,\n        HOME_BACKUP: 4,\n        PRINT_EXE: 5,\n      },\n      INCLUDES: {\n        CREATED_BY: 'created_by',\n        UPDATED_BY: 'updated_by',\n      },\n      DEFAULT_USER_FORMAT: [\n        'id',\n        'type',\n        'name',\n        'education',\n        'cell',\n        'cell2',\n        'email',\n      ],\n    },\n\n  },\n};\n"
  },
  {
    "path": "packages/server/models/index.js",
    "content": "/* eslint-disable global-require */\nmodule.exports = {\n\n  // Special model\n  Queue: require('./Models/Queue'),\n\n  // separate tenant models\n  Project: require('./Models/tenant/Project'),\n  Application: require('./Models/tenant/Application'),\n  RawModel: require('./Models/tenant/RawModel'),\n  Schema: require('./Models/tenant/Schema'),\n  SchemaDetail: require('./Models/tenant/SchemaDetail'),\n  Generator: require('./Models/tenant/Generator'),\n  ProjectRoute: require('./Models/tenant/ProjectRoute'),\n  ProjectConstant: require('./Models/tenant/ProjectConstant'),\n  ProjectPolicy: require('./Models/tenant/ProjectPolicy'),\n  ApplicationConfig: require('./Models/tenant/ApplicationConfig'),\n  QueryBuilder: require('./Models/tenant/QueryBuilder'),\n  ProjectRoleAccessPermissions: require('./Models/tenant/ProjectRoleAccessPermissions'),\n  NestedQueryBuilder: require('./Models/tenant/NestedQueryBuilder'),\n  SchemaUploadVersion: require('./Models/tenant/SchemaUploadVersion'),\n\n  // general model\n  EnvVariables: require('./Models/tenant/EnvVariables'),\n  MasterSubMaster: require('./Models/tenant/Master'),\n\n};\n"
  },
  {
    "path": "packages/server/models/responses/badRequest.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = async (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.ERROR.code),\n    message: _.get(data, 'message', MESSAGE.ERROR.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.BAD_REQUEST.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/error.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.ERROR.code),\n    message: _.get(data, 'message', MESSAGE.ERROR.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.ERROR.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/forbidden.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.FORBIDDEN.code),\n    message: _.get(data, 'message', MESSAGE.FORBIDDEN.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.FORBIDDEN.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/index.js",
    "content": "const ok = require('./ok');\nconst badRequest = require('./badRequest');\nconst notFound = require('./notFound');\nconst forbidden = require('./forbidden');\nconst serverError = require('./serverError');\nconst setResponse = require('./setResponse');\nconst unauthorized = require('./unauthorized');\n\nmodule.exports = {\n  ok,\n  badRequest,\n  serverError,\n  notFound,\n  forbidden,\n  unauthorized,\n  setResponse,\n};\n"
  },
  {
    "path": "packages/server/models/responses/notFound.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = async (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.ERROR.code),\n    message: _.get(data, 'message', MESSAGE.ERROR.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.NOT_FOUND.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/ok.js",
    "content": "/* global MESSAGE, _ */\n\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = async (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.ERROR.code),\n    message: _.get(data, 'message', MESSAGE.ERROR.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.OK.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/serverError.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = ok = (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.SERVER_ERROR.code),\n    message: _.get(data, 'message', MESSAGE.SERVER_ERROR.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.SERVER_ERROR.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/setResponse.js",
    "content": "/* eslint-disable guard-for-in */\n/* global  _ */\nconst { OK } = require('../constants/message').MESSAGE;\n\nmodule.exports = async (res, body) => {\n  // Memory Usage\n  body = {\n    code: _.get(body, 'code', OK.code),\n    message: _.get(body, 'message', OK.message),\n    data: _.get(body, 'data', null),\n    otherData: _.get(body, 'otherData', {}),\n    status: _.get(body, 'status', OK.status),\n  };\n\n  let { status } = OK;\n  if (body.status) {\n    status = body.status;\n  }\n  return res.status(status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/responses/unauthorized.js",
    "content": "/* global MESSAGE, _ */\n// eslint-disable-next-line no-multi-assign ,no-undef\nmodule.exports = unauthorized = (res, body) => {\n  const used = process.memoryUsage();\n  const memUsage = [];\n  // eslint-disable-next-line no-restricted-syntax,guard-for-in\n  for (const key in used) {\n    memUsage.push(`${key} - ${(Math.round(used[key] / 1024 / 1024) * 100) / 100} MB`);\n  }\n  const data = body;\n  body = {\n    code: _.get(data, 'code', MESSAGE.UNAUTHORIZED.code),\n    message: _.get(data, 'message', MESSAGE.UNAUTHORIZED.message),\n    data: _.get(data, 'data', {}),\n    memUsage,\n  };\n  return res.status(MESSAGE.UNAUTHORIZED.status).send(body);\n};\n"
  },
  {
    "path": "packages/server/models/usecase/getSetting.js",
    "content": "/* global */\nconst Repo = require('../Repo/Connection');\nconst { MODULE } = require('../constants/common');\n\nconst repo = new Repo(MODULE.SETTING);\n\nconst getSetting = async () => repo.getOne({});\n\nconst getSettingByKey = async (key) => {\n  const setting = await getSetting();\n  return setting?.[key] || '';\n};\n\nconst getFrontSiteVersionTag = async () => { await getSettingByKey('frontSiteVersionTag'); };\n\nmodule.exports = {\n  getSetting,\n  getSettingByKey,\n  getFrontSiteVersionTag,\n};\n"
  },
  {
    "path": "packages/server/package.json",
    "content": "{\n  \"name\": \"@nodejs-code-generator/server\",\n  \"private\": true,\n  \"version\": \"1.3.1\",\n  \"description\": \"\",\n  \"main\": \"handler.js\",\n  \"scripts\": {\n    \"start\": \"node --inspect=0.0.0.0 app.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"eslint\": \"^8.10.0\",\n    \"eslint-config-airbnb\": \"^18.2.1\",\n    \"eslint-plugin-import\": \"^2.25.4\",\n    \"supertest\": \"^6.1.6\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^0.21.1\",\n    \"bson-objectid\": \"^2.0.1\",\n    \"cheerio\": \"^1.0.0-rc.6\",\n    \"compression\": \"^1.7.4\",\n    \"cors\": \"^2.8.5\",\n    \"crypto-js\": \"^4.1.1\",\n    \"dayjs\": \"^1.10.7\",\n    \"dotenv\": \"^8.2.0\",\n    \"ejs\": \"^3.1.5\",\n    \"express\": \"^4.17.1\",\n    \"faker\": \"^5.5.3\",\n    \"flat\": \"^5.0.2\",\n    \"formidable\": \"^2.0.1\",\n    \"fs-extra\": \"^10.0.0\",\n    \"joi\": \"^17.4.0\",\n    \"key-value-replace\": \"^3.0.0\",\n    \"lodash\": \"^4.17.20\",\n    \"minimatch\": \"^3.0.4\",\n    \"mkdirp\": \"^1.0.4\",\n    \"mongodb\": \"^3.6.4\",\n    \"mongodb-memory-server\": \"^7.5.1\",\n    \"mongoose\": \"^6.2.5\",\n    \"morgan\": \"^1.10.0\",\n    \"path\": \"^0.12.7\",\n    \"pluralize\": \"^8.0.0\",\n    \"postman-collection\": \"^4.1.0\",\n    \"randexp\": \"^0.5.3\",\n    \"readline\": \"^1.3.0\",\n    \"sorted-object\": \"^2.0.1\",\n    \"uuid\": \"^8.3.2\",\n    \"valid-url\": \"^1.0.9\",\n    \"validate.js\": \"^0.13.1\"\n  }\n}\n"
  },
  {
    "path": "packages/server/repo/application.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass ProjectRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.APPLICATION);\n  }\n}\n\nmodule.exports = ProjectRepository;\n"
  },
  {
    "path": "packages/server/repo/applicationConfig.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ApplicationConfigRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.APPLICATION_CONFIG);\n  }\n}\nmodule.exports = ApplicationConfigRepository;\n"
  },
  {
    "path": "packages/server/repo/dataTypeSuggestions.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass DataTypeSuggestionsRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.DATATYPE_SUGGESTIONS);\n  }\n}\n\nmodule.exports = DataTypeSuggestionsRepository;\n"
  },
  {
    "path": "packages/server/repo/db.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\n\nclass DbRepository extends MongoAtlasRepository {\n  constructor (MODULE_DATA) {\n    super();\n    this.table = MODULE_DATA.MODEL_NAME;\n    this.module = MODULE_DATA;\n  }\n\n  async getById (options) {\n    const result = await super.getById(this.module, options);\n    return result;\n  }\n\n  // Revised function with Response object\n\n  async getDetails (filter) {\n    const result = await super.getDetails(this.module, filter);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async get (filter) {\n    const result = await super.getOne(this.module, filter);\n    if (result && result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async create (data) {\n    const result = await super.create(this.module, data);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async update (id, data) {\n    const result = await super.updateById(this.module, id, data);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async deleteById (userId) {\n    const result = await super.deleteById(this.module, userId);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async getCount (filter) {\n    const result = await super.getCount(this.module, filter);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async search (filter) {\n    const model = await this.multiTenancy(this.table);\n    const result = await model.findOne({ $or: [{ username: filter.search }, { seriesNo: filter.search }] }).select(filter.fields).populate(filter.populate);\n    if (result && result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n\n  async deleteMany (filter) {\n    const result = await super.deleteMany(this.module, filter);\n    if (result.error) {\n      throw new Error(result.error);\n    }\n    return result;\n  }\n}\n\nmodule.exports = DbRepository;\n"
  },
  {
    "path": "packages/server/repo/envVariables.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass envVariables extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.ENV_VARIABLES);\n  }\n}\n\nmodule.exports = envVariables;\n"
  },
  {
    "path": "packages/server/repo/generate.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst MongoAtlasRepository = require('../models/Repo');\n\nclass SchemaRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.GENERATOR);\n  }\n}\n\nmodule.exports = SchemaRepository;\n"
  },
  {
    "path": "packages/server/repo/master.js",
    "content": "/* eslint-disable class-methods-use-this */\nconst { masterData } = require('../assets/master');\nconst { MASTER_PARENT_CODES } = require('../models/constants/master');\n\nclass masterRepository {\n  async getDetailsForInput () {\n    const results = [];\n    for (let i = 0; i < masterData.length; i += 1) {\n      if (masterData[i].parentCode === MASTER_PARENT_CODES.SOCIAL_AUTH) {\n        results.push(masterData[i]);\n      }\n    }\n    return results;\n  }\n\n  async getMasterByCode (filter) {\n    const results = [];\n    const field = filter.code ? 'code' : 'parentCode';\n    for (let i = 0; i < masterData.length; i += 1) {\n      if (masterData[i][field] === filter[field]) {\n        results.push(masterData[i]);\n      }\n    }\n    return results;\n  }\n\n  async getChildDetails (filter) {\n    const results = [];\n    for (let i = 0; i < masterData.length; i += 1) {\n      if (filter.includes(masterData[i].parentId)) {\n        results.push(masterData[i]);\n      }\n    }\n    return results;\n  }\n}\n\nmodule.exports = masterRepository;\n"
  },
  {
    "path": "packages/server/repo/nestedQueryBuilder.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass NestedQueryBuilderRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.NESTED_QUERY_BUILDER);\n  }\n}\n\nmodule.exports = NestedQueryBuilderRepository;\n"
  },
  {
    "path": "packages/server/repo/port.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass PortRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PORT);\n  }\n}\nmodule.exports = PortRepository;\n"
  },
  {
    "path": "packages/server/repo/project.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ProjectRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PROJECT);\n  }\n}\nmodule.exports = ProjectRepository;\n"
  },
  {
    "path": "packages/server/repo/projectConstant.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ProjectConstantRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PROJECT_CONSTANT);\n  }\n}\nmodule.exports = ProjectConstantRepository;\n"
  },
  {
    "path": "packages/server/repo/projectPolicy.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ProjectCronRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PROJECT_POLICY);\n  }\n}\nmodule.exports = ProjectCronRepository;\n"
  },
  {
    "path": "packages/server/repo/projectRoleAccessPermissions.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ProjectRoleAccessPermissionsRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PROJECT_ROLE_ACCESS_PERMISSIONS);\n  }\n}\nmodule.exports = ProjectRoleAccessPermissionsRepository;\n"
  },
  {
    "path": "packages/server/repo/projectRoute.js",
    "content": "const { MODULE } = require('../models/constants/common');\nconst CommonQueryRepository = require('../models/Repo');\n\nclass ProjectRouteRepository extends CommonQueryRepository {\n  constructor () {\n    super(MODULE.PROJECT_ROUTE);\n  }\n}\nmodule.exports = ProjectRouteRepository;\n"
  },
  {
    "path": "packages/server/repo/queryBuilder.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass QueryBuilderRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.QUERY_BUILDER);\n  }\n}\n\nmodule.exports = QueryBuilderRepository;\n"
  },
  {
    "path": "packages/server/repo/schema.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass SchemaRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.SCHEMA);\n  }\n}\n\nmodule.exports = SchemaRepository;\n"
  },
  {
    "path": "packages/server/repo/schemaDetail.js",
    "content": "const MongoAtlasRepository = require('../models/Repo');\nconst { MODULE } = require('../models/constants/common');\n\nclass SchemaRepository extends MongoAtlasRepository {\n  constructor () {\n    super(MODULE.SCHEMA_DETAIL);\n  }\n}\n\nmodule.exports = SchemaRepository;\n"
  },
  {
    "path": "packages/server/responses/index.js",
    "content": "const {\n  ok, badRequest, serverError, forbidden, notFound, setResponse, unauthorized,\n} = require('../models/responses');\n\nmodule.exports = {\n  ok,\n  badRequest,\n  serverError,\n  notFound,\n  forbidden,\n  unauthorized,\n  setResponse,\n};\n"
  },
  {
    "path": "packages/server/routes/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst webRoute = require('./web');\n\nrouter.use('/web', webRoute);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/application/application.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, generate, structure, destroy, update, view,\n  get, openCode, getLastApplication,\n} = require('../../../controllers/web/application');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.get('/last-application', getLastApplication);\nrouter.get('/:id', get);\nrouter.post('/generate', generate);\nrouter.post('/structure', structure);\nrouter.put('/invite/:id', update);\nrouter.put('/:id', update);\nrouter.post('/destroy', destroy);\nrouter.post('/view', view);\nrouter.post('/open-generated-code', openCode);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/application/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst application = require('./application');\n\nrouter.use('/application', application);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/applicationConfig/applicationConfig.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, update, get, destroy, paginate,\n} = require('../../../controllers/web/applicationConfig');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.get('/:id', get);\nrouter.post('/destroy', destroy);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/applicationConfig/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst applicationConfig = require('./applicationConfig');\n\nrouter.use('/application-config', applicationConfig);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/envVariables/envVariables.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  upsert, get,\n} = require('../../../controllers/web/envVariables');\n\nrouter.post('/upsert', upsert);\nrouter.post('/details', get);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/envVariables/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst environmentVariables = require('./envVariables');\n\nrouter.use('/env-variables', environmentVariables);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst project = require('./project');\nconst application = require('./application');\nconst schema = require('./schema');\nconst schemaDetail = require('./schemaDetail');\nconst projectRoute = require('./projectRoute');\nconst projectConstant = require('./projectConstant');\nconst projectPolicy = require('./projectPolicy');\nconst applicationConfig = require('./applicationConfig');\nconst envVariables = require('./envVariables');\nconst jsonInput = require('./jsonInput');\nconst roleAccess = require('./projectRoleAccessPermissions');\nconst masterRoute = require('./master');\n\nrouter.use('/v1', application);\nrouter.use('/v1', project);\nrouter.use('/v1', schema);\nrouter.use('/v1', schemaDetail);\nrouter.use('/v1', projectRoute);\nrouter.use('/v1', projectConstant);\nrouter.use('/v1', projectPolicy);\nrouter.use('/v1', applicationConfig);\nrouter.use('/v1', envVariables);\nrouter.use('/v1', jsonInput);\nrouter.use('/v1', roleAccess);\nrouter.use('/v1', masterRoute);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/jsonInput/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst jsonInput = require('./jsonInput');\n\nrouter.use('/json-input', jsonInput);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/jsonInput/jsonInput.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst { jsonInput } = require('../../../controllers/web/jsonInput');\n\nrouter.post('/store', jsonInput);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/master/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst master = require('./master');\n\nrouter.use('/master', master);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/master/master.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst { getByCode } = require('../../../controllers/web/master');\n\nrouter.post('/get-by-code', getByCode);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/project/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst project = require('./project');\n\nrouter.use('/project', project);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/project/project.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, destroy, update, get, upsert, applicationRestriction,\n} = require('../../../controllers/web/project');\n\nrouter.post('/create', create);\nrouter.post('/applicationRestriction', applicationRestriction);\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.put('/archive/:id', upsert);\nrouter.get('/:id', get);\nrouter.post('/destroy', destroy);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectConstant/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst projectConstantRoute = require('./projectConstant');\n\nrouter.use('/project-constant', projectConstantRoute);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectConstant/projectConstant.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, update, destroy,\n} = require('../../../controllers/web/projectConstant');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.post('/destroy', destroy);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectPolicy/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst projectPolicyRoute = require('./projectPolicy');\n\nrouter.use('/project-policy', projectPolicyRoute);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectPolicy/projectPolicy.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, update, destroy,\n} = require('../../../controllers/web/projectPolicy');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.post('/destroy', destroy);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectRoleAccessPermissions/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst projectRoleAccessPermissions = require('./projectRoleAccessPermissions');\n\nrouter.use('/project-role-access', projectRoleAccessPermissions);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectRoleAccessPermissions/projectRoleAccessPermissions.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  upsert, paginate, destroy,\n} = require('../../../controllers/web/projectRoleAccessPermissions');\n\nrouter.post('/upsert', upsert);\nrouter.post('/paginate', paginate);\nrouter.post('/destroy', destroy);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectRoute/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst projectRoute = require('./projectRoute');\n\nrouter.use('/project-route', projectRoute);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/projectRoute/projectRoute.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, update, destroy, uploadPostmanFile,\n  requestApi,\n} = require('../../../controllers/web/projectRoute');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.post('/destroy', destroy);\nrouter.post('/upload-postman-file', uploadPostmanFile);\nrouter.post('/request', requestApi);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/schema/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst schema = require('./schema');\n\nrouter.use('/schema', schema);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/schema/schema.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, update, destroy, insertMany, schemaExists, sqlSchemaExists, getSchema,\n  insertDefaultModels, searchSchema,\n} = require('../../../controllers/web/schema');\n\nrouter.post('/create', create);\nrouter.post('/upload-models', insertMany);\nrouter.post('/paginate', paginate);\nrouter.post('/destroy', destroy);\nrouter.put('/:id', update);\nrouter.post('/update-exists-schema', schemaExists);\nrouter.post('/sql-schema-exists', sqlSchemaExists);\nrouter.get('/get/:id', getSchema);\nrouter.post('/insert-default-models', insertDefaultModels);\nrouter.post('/search', searchSchema);\nrouter.post('/import-sql');\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/schemaDetail/index.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\nconst schema = require('./schemaDetail');\n\nrouter.use('/schema-detail', schema);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/routes/web/schemaDetail/schemaDetail.js",
    "content": "const express = require('express');\n\nconst router = express.Router();\n\nconst {\n  create, paginate, update, upsert,\n} = require('../../../controllers/web/schemaDetail');\n\nrouter.post('/create', create);\nrouter.post('/paginate', paginate);\nrouter.put('/:id', update);\nrouter.post('/upsert', upsert);\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/actionWiseCount.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  OK, SERVER_ERROR, INVALID_REQUEST_PARAMS,\n} = require('../../constants/message').message;\n\nconst actionWiseCount = ({ deviceActionRepo }) => async (id) => {\n  try {\n    if (!id) return INVALID_REQUEST_PARAMS;\n\n    const data = await deviceActionRepo.aggregate({\n      queryStages: [\n        { $match: { applicationId: mongoose.Types.ObjectId(id) } }, {\n          $group: {\n            _id: {\n              type: '$customJson.action.type',\n              screenId: '$screenId',\n            },\n            count: { $sum: 1 },\n          },\n        },\n      ],\n    });\n    return {\n      ...OK,\n      data,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = actionWiseCount;\n"
  },
  {
    "path": "packages/server/usecase/application/create.js",
    "content": "/* global MESSAGE, _ */\nconst mongoose = require('mongoose');\nconst faker = require('faker');\nconst {\n  DEFAULT_POLICY_NAME, DEFAULT_POLICY, DEFAULT_CONSTANT_NAME, DEFAULT_CONSTANT, DEFAULT_POLICY_DESCRIPTION,\n  DEFAULT_CONSTANT_DESCRIPTION, ORM_TYPE,\n} = require('../../models/constants/application');\n\nconst { PROJECT_DEFINITION_CODE } = require('../../models/constants/projectDefinition');\nconst { VALIDATION_RULES } = require('../../constants/validation');\n\nconst { DEFAULT_TABLE_NAME } = require('../../constants/schema');\n\nconst {\n  getDefaultFieldsForMongoDB, getDefaultFieldsForSequelize,\n} = require('../schema/util/staticData');\n\nconst {\n  APPLICATION_FAILED_CREATE, INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, APPLICATION_CREATED,\n\n} = require('../../constants/message').message;\n\nconst projectPaginateUseCase = require('../project/paginate');\n\nconst projectCreateUseCase = require('../project/create');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst schemaAddUseCase = require('../schema/create');\nconst projectConstantAddUseCase = require('../projectConstant/create');\nconst projectPolicyAddUseCase = require('../projectPolicy/create');\nconst applicationConfigCreateUseCase = require('../applicationConfig/create');\nconst ProjectRoleAccessPermissionRepository = require('../../repo/projectRoleAccessPermissions');\n\nconst ProjectPolicyRepo = require('../../repo/projectPolicy');\nconst ProjectConstantRepo = require('../../repo/projectConstant');\nconst ApplicationConfigRepository = require('../../repo/applicationConfig');\n\nconst projectRoleAccessPermissionRepo = new ProjectRoleAccessPermissionRepository();\n\nconst projectPolicyRepo = new ProjectPolicyRepo();\nconst projectConstantRepo = new ProjectConstantRepo();\nconst applicationConfigRepo = new ApplicationConfigRepository();\n\nconst { APPLICATION_FIELDS } = require('../util/fieldsList');\nconst {\n  applicationCreationValidation, nodeExpressValidation,\n} = require('../util/validation/applicationCreate');\n\nconst projectRoleAccessPermission = require('../projectRoleAccessPermissions/upsert');\n\n/**\n * Function used to default project assign or create\n * @param {*} param0\n * @returns\n */\nconst defaultProjectAssignOrCreate = ({ projectRepo }) => async ({ params }) => {\n  let defaultProject = await projectRepo.get({\n    filter: { find: { isActive: false } },\n    sortBy: { createdAt: 'DESC' },\n  });\n\n  if (!defaultProject) {\n    const data = { name: 'Default' };\n\n    const projectResponse = await projectCreateUseCase(projectRepo)(data);\n\n    if (projectResponse?.code === 'OK') {\n      defaultProject = projectResponse?.data;\n    }\n  }\n\n  params.projectId = defaultProject?._id?.toString();\n\n  return params;\n};\n\nconst validateTypeRequest = (params) => {\n  let newErr;\n  if (params?.projectDefinitionCode === PROJECT_DEFINITION_CODE.NODE_EXPRESS) {\n    const {\n      value, error,\n    } = nodeExpressValidation(params);\n    newErr = error;\n    params = {\n      ...params,\n      value,\n    };\n  }\n  return {\n    typeValue: params,\n    typeError: newErr,\n  };\n};\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (applicationRepo, schemaRepo, projectRepo) => async (params) => {\n  try {\n    if (params.isOver) { params.isPublicConsent = params.isOver; }\n\n    const actualName = params.name;\n    if (params.name) {\n      let nameTemp = params.name;\n      nameTemp = nameTemp.replace(/-/g, '');\n      nameTemp = nameTemp.replace(/_/g, '');\n      params.name = nameTemp;\n      if (!(VALIDATION_RULES.APPLICATION.NAME.REGEX.test(nameTemp))) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: 'Start your application name with an alphanumeric with a minimum of 3 alphabets, and (_) are allowed after alphanumeric',\n        };\n      }\n      const appValidation = applicationCreationValidation(params);\n      if (appValidation?.error) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: appValidation?.error,\n        };\n      }\n      params = _.cloneDeep(appValidation.value);\n    } else {\n      const {\n        value, error,\n      } = applicationCreationValidation(params);\n      if (error) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: error,\n        };\n      }\n      params = _.cloneDeep(value);\n    }\n    params.name = actualName;\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const {\n      typeValue, typeError,\n    } = validateTypeRequest(params);\n    if (typeError) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: typeError,\n      };\n    }\n    params = typeValue;\n\n    // Default Project assign\n    if (!params?.projectId) {\n      params = await defaultProjectAssignOrCreate({ projectRepo })({ params });\n    }\n\n    const project = await projectRepo.get({\n      filter: { find: { _id: params.projectId } },\n      fields: ['isArchive', 'isDeleted'],\n    });\n    if (project?.isDeleted === true) {\n      return MESSAGE.APPLICATION_IS_DELETED;\n    }\n\n    if (params?.projectDefinitionCode && _.includes([\n      PROJECT_DEFINITION_CODE.NODE_EXPRESS], params.projectDefinitionCode)) {\n      if (!params?.configInput) {\n        params.configInput = {};\n      }\n      if (!params?.configInput.platform) {\n        params.configInput.platform = ['admin', 'device'];\n      }\n      if (!params?.configInput.types) {\n        params.configInput.types = ['User', 'Admin'];\n      }\n      if (!params?.configInput.loginAccess) {\n        params.configInput.loginAccess = {\n          User: [\n            'device',\n          ],\n          Admin: [\n            'admin',\n          ],\n        };\n      }\n    }\n\n    let created = await applicationRepo.create(params);\n    if (!created) {\n      return APPLICATION_FAILED_CREATE;\n    }\n\n    // UpdatedAt update\n    projectApplicationUpdate({ params });\n\n    if (params?.projectDefinitionCode && _.includes([PROJECT_DEFINITION_CODE.NODE_EXPRESS], params.projectDefinitionCode)) {\n      // create default user schema\n      const defaultSchema = DEFAULT_TABLE_NAME;\n\n      let schemaAddParam = {};\n      let staticFields = {};\n      if (created?.stepInput?.ormType && _.includes([ORM_TYPE.SEQUELIZE], created.stepInput.ormType)) {\n        schemaAddParam = {\n          applicationId: created.id,\n          name: defaultSchema,\n          schemaJson: {\n            username: { type: 'STRING' },\n            password: { type: 'STRING' },\n            email: { type: 'STRING' },\n            name: { type: 'STRING' },\n          },\n        };\n        if (created?.stepInput?.ormType === ORM_TYPE.ELOQUENT) {\n          schemaAddParam.schemaJson.email.unique = true;\n        }\n\n        // Get default fields.\n        staticFields = await getDefaultFieldsForSequelize({ ormType: created.stepInput.ormType });\n      } else {\n        schemaAddParam = {\n          applicationId: created.id,\n          name: defaultSchema,\n          schemaJson: {\n            username: { type: 'String' },\n            password: { type: 'String' },\n            email: { type: 'String' },\n            name: { type: 'String' },\n          },\n        };\n        // Get default fields.\n        staticFields = await getDefaultFieldsForMongoDB();\n      }\n\n      // Add default fields.\n      Object.keys(staticFields).forEach((field) => {\n        if (!schemaAddParam.schemaJson[field]) {\n          schemaAddParam.schemaJson[field] = staticFields[field];\n        }\n      });\n\n      const defaultSchemaData = await (schemaAddUseCase(schemaRepo, applicationRepo))(schemaAddParam);\n      // add default auth model in applicationConfig.\n      if (defaultSchemaData?.code && defaultSchemaData.code === OK.code) {\n        const defaultSchemaDetails = defaultSchemaData.data;\n        const appConfigParams = {\n          applicationId: created.id,\n          authModuleId: defaultSchemaDetails._id,\n          authModule: defaultSchemaDetails.name,\n        };\n\n        appConfigParams.loginWith = {\n          username: ['username', 'email'],\n          password: 'password',\n        };\n\n        const credentials = [];\n        if (created?.configInput?.types) {\n          const userTypes = _.cloneDeep(created.configInput.types);\n          _.map(userTypes, (type) => {\n            credentials.push({\n              type,\n              email: faker.internet.email(),\n              password: faker.internet.password(),\n            });\n          });\n        }\n        appConfigParams.authentication = { credentials };\n\n        await (applicationConfigCreateUseCase(applicationConfigRepo, applicationRepo))(appConfigParams);\n\n        // Create default Project-role-access-permissions\n        const rolePermissionName = ['Admin', 'User'];\n        for (let i = 0; i < rolePermissionName.length; i += 1) {\n          const roleName = rolePermissionName[i];\n          const roleInput = {\n            name: roleName,\n            applicationId: created._id.toString(),\n            customJson: [\n              {\n                modelId: defaultSchemaDetails._id,\n                actions: {\n                  C: true,\n                  R: true,\n                  U: true,\n                  D: true,\n                },\n              },\n            ],\n          };\n          // eslint-disable-next-line no-await-in-loop\n          await projectRoleAccessPermission(projectRoleAccessPermissionRepo)(roleInput);\n        }\n      }\n\n      // add default policy\n      if (!created.stepInput.ormType || (created?.stepInput?.ormType && created.stepInput.ormType !== ORM_TYPE.ELOQUENT)) {\n        const policyAddParam = {\n          applicationId: created.id,\n          fileName: DEFAULT_POLICY_NAME,\n          description: DEFAULT_POLICY_DESCRIPTION,\n          customJson: DEFAULT_POLICY,\n        };\n\n        await (projectPolicyAddUseCase(projectPolicyRepo, applicationRepo))(policyAddParam);\n      }\n\n      // add default constant\n      const constantAddParam = {\n        applicationId: created.id,\n        fileName: DEFAULT_CONSTANT_NAME,\n        groupName: DEFAULT_CONSTANT_NAME,\n        description: DEFAULT_CONSTANT_DESCRIPTION,\n        customJson: DEFAULT_CONSTANT,\n      };\n      await (projectConstantAddUseCase(projectConstantRepo, applicationRepo))(constantAddParam);\n    }\n\n    created = _.pick(created, APPLICATION_FIELDS);\n\n    // Get Project application list\n    const projectListResponse = await projectPaginateUseCase(projectRepo, applicationRepo)({ find: { _id: created?.projectId } });\n    created.projectList = projectListResponse?.data?.list;\n\n    return {\n      ...APPLICATION_CREATED,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/application/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteUseCase = require('./deleteDependency');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteUseCase(applicationRepo))({ find: { _id: params.id } }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/application/deleteDependency.js",
    "content": "/* global _ */\nconst SchemaRepo = require('../../repo/schema');\nconst ProjectConstantRepo = require('../../repo/projectConstant');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\nconst ProjectPolicyRepo = require('../../repo/projectPolicy');\nconst ApplicationRepo = require('../../repo/application');\n\nconst schemaRepo = new SchemaRepo();\nconst projectConstantRepo = new ProjectConstantRepo();\nconst projectRouteRepo = new ProjectRouteRepo();\nconst projectPolicyRepo = new ProjectPolicyRepo();\nconst applicationRepository = new ApplicationRepo();\n\nconst deleteSchemaDetailUseCase = require('../schema/deleteDependency')(schemaRepo, applicationRepository);\nconst deleteProjectConstantUseCase = require('../projectConstant/deleteDependency')(projectConstantRepo, applicationRepository);\nconst deleteProjectRouteUseCase = require('../projectRoute/deleteDependency')(projectRouteRepo, applicationRepository);\nconst deleteProjectPolicyUseCase = require('../projectPolicy/deleteDependency')(projectPolicyRepo, applicationRepository);\n\nconst {\n  INVALID_REQUEST_PARAMS, APPLICATION_DELETED, SERVER_ERROR, NOT_FOUND,\n} = require('../../constants/message').message;\n\n// { filter: { find: { applicationId: params.id } } }\nconst deleteMany = (applicationRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await applicationRepo.getDetails(filter);\n\n    if (!response.length) {\n      return NOT_FOUND;\n    }\n\n    if (response && response.length) {\n      if (isHardDelete) {\n        await applicationRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await applicationRepo.updateMany(updateData);\n      }\n\n      // delete dependency\n      await deleteSchemaDetailUseCase({ find: { applicationId: _.map(response, '_id') } });\n      await deleteProjectConstantUseCase({ find: { applicationId: _.map(response, '_id') } }, isHardDelete);\n      await deleteProjectRouteUseCase({ find: { applicationId: _.map(response, '_id') } }, isHardDelete);\n      await deleteProjectPolicyUseCase({ find: { applicationId: _.map(response, '_id') } }, isHardDelete);\n    }\n    return APPLICATION_DELETED;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/application/generate.js",
    "content": "/* global _,appRootPath */\nconst fs = require('fs');\nconst path = require('path');\nconst fsExtra = require('fs-extra');\nconst mongoose = require('mongoose');\nconst os = require('os');\nconst { getAllDirFilesCount } = require('../../util-service/common');\nconst { decrypt } = require('../../util-service/crypto');\nconst {\n  IN_QUEUE, IN_PROCESS, COMPLETED, FAILED,\n} = require('../../models/constants/application').IN_PROCESS_STATUS;\nconst {\n  GENERATOR_ORM_TYPE, GENERATOR_DATABASE_TYPE,\n} = require('../../models/constants/applicationConfig');\nconst {\n  ROUTE_GENERATE_TYPE, CONSTANT_GENERATE_TYPE, POLICY_GENERATE_TYPE,\n} = require('../../models/constants/project');\nconst SchemaDetailRepo = require('../../repo/schemaDetail');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\nconst QueryBuilderRepo = require('../../repo/queryBuilder');\nconst ProjectPolicyRepo = require('../../repo/projectPolicy');\nconst ProjectConstantRepo = require('../../repo/projectConstant');\nconst ApplicationConfigRepo = require('../../repo/applicationConfig');\nconst EnvVariablesRepo = require('../../repo/envVariables');\nconst ProjectRoleAccessPermissionsRepo = require('../../repo/projectRoleAccessPermissions');\nconst NestedQueryBuilderRepo = require('../../repo/nestedQueryBuilder');\n\nconst {\n  SCHEMA_IS_EMPTY, INVALID_REQUEST_PARAMS, BAD_REQUEST, GENERATOR_FAILED_CREATE, SERVER_ERROR, OK, PROJECT_GENERATED,\n} = require('../../constants/message').message;\nconst generator = require('./node-generator/generator');\n\nconst homedir = os.homedir();\n\nconst SchemaDetail = new SchemaDetailRepo();\nconst ProjectRoute = new ProjectRouteRepo();\nconst QueryBuilder = new QueryBuilderRepo();\nconst ProjectPolicy = new ProjectPolicyRepo();\nconst ProjectConstant = new ProjectConstantRepo();\nconst ApplicationConfig = new ApplicationConfigRepo();\nconst EnvVariables = new EnvVariablesRepo();\nconst ProjectRoleAccessPermissions = new ProjectRoleAccessPermissionsRepo();\nconst NestedQueryBuilder = new NestedQueryBuilderRepo();\n\nconst generateNodeCode = async (\n  input, applicationRepo, definition, generatedId, dirPath, projectName, applicationId, generatorRepo, isReBuild,\n) => {\n  try {\n    const updatedApp = await applicationRepo.update(applicationId, { 'inProcessStatus.build_app': IN_PROCESS });\n    await generatorRepo.update(generatedId, { 'inProcessStatus.build_app': IN_PROCESS });\n    await generator(input, isReBuild);\n    // eslint-disable-next-line max-len\n    const lastGeneratorRecord = await generatorRepo.getDetails({\n      find: {\n        applicationId,\n        isDeleted: false,\n        'inProcessStatus.build_app': COMPLETED,\n      },\n      sortBy: { _id: -1 },\n      skip: 4,\n    });\n    if (lastGeneratorRecord && lastGeneratorRecord.length) {\n      for (let i = 0; i < lastGeneratorRecord.length; i += 1) {\n        const deletePath = `${homedir}${definition.generatorPath}/${lastGeneratorRecord[i]._id}`;\n        // eslint-disable-next-line no-await-in-loop\n        await generatorRepo.update(lastGeneratorRecord[i]._id, { isDeleted: true });\n        if (fs.existsSync(deletePath)) {\n          fs.rmdirSync(deletePath, { recursive: true });\n        }\n      }\n    }\n\n    // update the application status if log file contain error status in data\n    const logPath = `${definition.generatorPath}/${generatedId}/log.json`;\n    let logData;\n    if (fs.existsSync(logPath)) logData = JSON.parse(fs.readFileSync(logPath, 'utf8'));\n\n    // if logData contain error then stop the process and send message as a that application and generatoe build failed\n    if (logData && _.find(logData.data, (val) => (val.status === 'error'))) {\n      await applicationRepo.update(applicationId, { 'inProcessStatus.build_app': FAILED });\n      await generatorRepo.update(generatedId, { 'inProcessStatus.build_app': FAILED });\n    } else {\n      let dirFilesCount;\n      let nextProcess = true;\n      try {\n        dirFilesCount = await getAllDirFilesCount(dirPath);\n      } catch (e) {\n        nextProcess = false;\n        await applicationRepo.update(applicationId, { 'inProcessStatus.build_app': FAILED });\n        await generatorRepo.update(generatedId, { 'inProcessStatus.build_app': FAILED });\n        // console.log(e);\n      }\n      if (nextProcess) {\n        const updateApplication = {\n          statics: { filesCount: dirFilesCount },\n          lastBuildAt: new Date(),\n          'inProcessStatus.build_app': COMPLETED,\n          generatedId: updatedApp.tempGeneratedId,\n          tempGeneratedId: null,\n        };\n        await applicationRepo.update(applicationId, updateApplication);\n        await generatorRepo.update(generatedId, { 'inProcessStatus.build_app': COMPLETED });\n      }\n    }\n    return true;\n  } catch (e) {\n    await applicationRepo.update(applicationId, { 'inProcessStatus.build_app': FAILED });\n    await generatorRepo.update(generatedId, { 'inProcessStatus.build_app': FAILED });\n    return false;\n  }\n};\n\nconst nodeExpressRequest = async (applicationId, project, schemaRepo) => {\n  let filter = { find: { applicationId } };\n  let models = await schemaRepo.getDetails(filter);\n\n  if (!models || !models.length) {\n    return SCHEMA_IS_EMPTY;\n  }\n  const modelsData = _.cloneDeep(models);\n  filter = { find: { schemaId: { $in: _.map(models, '_id') } } };\n  let additionalSchema = await SchemaDetail.getDetails(filter);\n\n  if (additionalSchema.length) {\n    additionalSchema = _.groupBy(additionalSchema, 'schemaId');\n  } else {\n    additionalSchema = {};\n  }\n  const modelsById = _.groupBy(models, '_id');\n  models = _.groupBy(models, 'name');\n  const modelConfig = {};\n  const newModelConfig = {};\n  const hooks = {};\n  const modelIndexes = {};\n  const modelEnum = {};\n  const modelPrivate = {};\n  const modelAdvanceOptions = {};\n\n  let customPlatForms = ['admin', 'device', 'client', 'desktop']; // Default platforms\n  if (project?.configInput?.platform) {\n    customPlatForms = _.cloneDeep(project.configInput.platform);\n  }\n\n  _.each(models, (d, dataKey) => {\n    if (d[0].hooks && d[0].hooks.length) {\n      hooks[dataKey] = _.groupBy(d[0].hooks, 'type');\n    }\n    if (additionalSchema[d[0]._id]) {\n      const additionalData = additionalSchema[d[0]._id.toString()][0];\n      if (additionalData.additionalJson && additionalData.additionalJson.additionalSetting) {\n        newModelConfig[dataKey] = additionalData.additionalJson.additionalSetting;\n      }\n      modelConfig[dataKey] = {};\n      _.each(additionalData.schemaJson, (val, key) => {\n        if (customPlatForms.includes(key)) {\n          modelConfig[dataKey][key] = [];\n          _.each(val, (flag) => {\n            if (flag) modelConfig[dataKey][key].push(flag);\n          });\n        }\n      });\n    }\n    if (d[0].modelIndexes) {\n      modelIndexes[dataKey] = d[0].modelIndexes;\n    }\n    if (d[0].customJson) {\n      if (d[0].customJson.additionalSetting) {\n        _.each(d[0].customJson.additionalSetting, (eV, eK) => {\n          if (eV.enum) {\n            if (!modelEnum[dataKey]) modelEnum[dataKey] = {};\n            modelEnum[dataKey][eK] = eV.enum;\n          } else {\n            _.each(eV, (sv, sk) => {\n              if (sv.enum) {\n                if (!modelEnum[dataKey]) modelEnum[dataKey] = {};\n                if (!modelEnum[dataKey][eK]) modelEnum[dataKey][eK] = {};\n                modelEnum[dataKey][eK][sk] = sv.enum;\n              }\n            });\n          }\n          if (eV.private) {\n            if (!modelPrivate[dataKey]) modelPrivate[dataKey] = {};\n            modelPrivate[dataKey][eK] = eV.private;\n          } else {\n            _.each(eV, (sv, sk) => {\n              if (sv.private) {\n                if (!modelPrivate[dataKey]) modelPrivate[dataKey] = {};\n                if (!modelPrivate[dataKey][eK]) modelPrivate[dataKey][eK] = {};\n                modelPrivate[dataKey][eK][sk] = sv.private;\n              }\n            });\n          }\n        });\n      }\n    }\n  });\n  _.each(models, (val, key) => {\n    models[key] = val[0].schemaJson;\n    if (val[0]?.tableName) {\n      modelAdvanceOptions[key] = { tableName: val[0]?.tableName };\n    }\n  });\n\n  // custom routes\n  let apis = await ProjectRoute.getDetails({\n    find: {\n      applicationId,\n      type: ROUTE_GENERATE_TYPE.MANUAL,\n    },\n  });\n\n  if (apis.length) {\n    let queries = await QueryBuilder.getDetails({ find: { applicationId } });\n    queries = _.groupBy(queries, 'referenceId');\n    _.each(queries, (qv, qk) => {\n      queries[qk] = _.map(qv, (d) => _.omit(d, ['applicationId', '_id', 'id', 'referenceId', 'requestModelId',\n        'addedBy', 'updatedBy', 'referenceType', 'modelId', 'filterJson', 'isActive', 'isDeleted', 'createdAt', 'updatedAt']));\n    });\n    apis = _.map(apis, (a) => {\n      const obj = {\n        model: a.groupName,\n        policies: a.policies,\n        method: a.method,\n        api: a.route,\n        controller: a.controller,\n        service: a.controller,\n        descriptions: a.description,\n        platform: a.platform,\n        functionName: a.action,\n        headers: a.headers ?? [],\n        queryBuilder: queries[a._id.toString()] ?? [],\n      };\n      if (a?.fileUpload && a?.fileUpload?.uploads && a?.fileUpload?.uploads[0]) {\n        obj.queryBuilder.unshift({\n          queryMode: 'fileUpload',\n          ...a?.fileUpload?.uploads[0],\n        });\n      }\n      return obj;\n    });\n  }\n\n  // custom policy\n  let policy = await ProjectPolicy.getDetails({\n    find: {\n      applicationId,\n      type: POLICY_GENERATE_TYPE.MANUAL,\n    },\n  });\n  if (policy.length) {\n    policy = _.groupBy(policy, 'fileName');\n  } else {\n    policy = {};\n  }\n  _.each(policy, (val, key) => {\n    policy[key] = {\n      functionName: val[0].fileName,\n      code: val[0].customJson,\n    };\n  });\n\n  // constant\n  let constants = await ProjectConstant.getDetails({\n    find: {\n      applicationId,\n      type: CONSTANT_GENERATE_TYPE.MANUAL,\n    },\n  });\n  if (constants.length) {\n    constants = _.groupBy(constants, 'fileName');\n    _.each(constants, (val, key) => {\n      constants[key] = val[0].customJson;\n    });\n  } else {\n    constants = {};\n  }\n\n  // ApplicationConfig\n  let applicationConfig = await ApplicationConfig.getDetails({ find: { applicationId } });\n  if (applicationConfig.length) {\n    [applicationConfig] = applicationConfig;\n  } else {\n    applicationConfig = {};\n  }\n  const { fileUpload } = applicationConfig;\n  if (applicationConfig && applicationConfig.socialPlatform && applicationConfig.socialPlatform.length) {\n    applicationConfig.socialPlatform = _.map(applicationConfig.socialPlatform, (data) => {\n      if (data.platform) data.platforms = data.platform;\n      return data;\n    });\n  }\n\n  // Get ENV-Variables details\n  const envVariablesFilter = {\n    find: { applicationId },\n    fields: ['customJson', 'environments'],\n  };\n  const envVariables = await EnvVariables.get(envVariablesFilter);\n  if (envVariables && envVariables.customJson) {\n    // Convert Encrypted values in Decrypted form.\n    _.each(envVariables.customJson, (val) => {\n      if (val && val.value) {\n        _.each(val.value, async (v, k) => {\n          let isDecrypt = true;\n          if ((val?.dataType) && _.indexOf(['string'], val.dataType.toLowerCase()) < 0) {\n            isDecrypt = false;\n          }\n          if (isDecrypt) {\n            const decryptedValue = await decrypt(v);\n            val.value[k] = decryptedValue;\n          }\n        });\n      }\n    });\n    delete envVariables._id;\n  }\n\n  const responseFormat = {};\n  if (applicationConfig?.responseFormatter?.length > 0) {\n    const responseFormatGroup = _.groupBy(applicationConfig.responseFormatter, 'modelId');\n    _.each(responseFormatGroup, (data, key) => {\n      if (key && !_.includes([undefined, 'undefined', null], key)) {\n        let modelDetails = _.map(modelsData, (mData) => {\n          if (mData._id.toString() === key) {\n            return mData;\n          }\n          return {};\n        });\n        modelDetails = _.reject(modelDetails, _.isEmpty);\n        if (modelDetails && modelDetails.length > 0) {\n          responseFormat[modelDetails[0].name] = _.cloneDeep(data);\n        }\n      } else {\n        responseFormat.allModels_data_format = _.cloneDeep(data);\n      }\n    });\n  }\n\n  applicationConfig = {\n    restrictNoOfDevice: applicationConfig.restrictNoOfDevice,\n    noOfDevice: applicationConfig.noOfDevice,\n    authModule: applicationConfig.authModule || null,\n    loginWith: applicationConfig.loginWith || {},\n    loginRetryLimit: applicationConfig.loginRetryLimit || {},\n    loginRateLimit: applicationConfig.loginRateLimit || {},\n    loginNextRetryTime: applicationConfig.loginNextRetryTime || null,\n    resetPassword: applicationConfig.resetPassword || {},\n    isSocialMediaAuth: applicationConfig.isSocialMediaAuth || null,\n    socialPlatform: applicationConfig.socialPlatform || [],\n    addDataFormate: responseFormat,\n  };\n\n  const roleAccessPermissions = await ProjectRoleAccessPermissions.getDetails({ find: { applicationId } });\n  const rolePermission = {};\n  _.each(roleAccessPermissions, (val) => {\n    if (val.customJson && val.customJson.length) {\n      _.each(val.customJson, (v) => {\n        if (v.modelId) {\n          if (modelsById[v.modelId]) {\n            _.each(v.actions, (flag, key) => {\n              if (flag) {\n                if (!rolePermission[modelsById[v.modelId][0].name]) {\n                  rolePermission[modelsById[v.modelId][0].name] = {};\n                }\n                if (rolePermission[modelsById[v.modelId][0].name][key]) {\n                  rolePermission[modelsById[v.modelId][0].name][key].push(val.name);\n                } else {\n                  rolePermission[modelsById[v.modelId][0].name][key] = [val.name];\n                }\n              }\n            });\n          }\n        }\n      });\n    }\n  });\n\n  let nestedCallData = await NestedQueryBuilder.getDetails({ find: { applicationId } });\n  const nestedCall = {};\n  if (nestedCallData.length) {\n    nestedCallData = _.groupBy(nestedCallData, 'model');\n    _.each(nestedCallData, (platformData, platform) => {\n      if (!nestedCall[platform]) nestedCall[platform] = {};\n      platformData = _.groupBy(platformData, 'platform');\n      _.each(platformData, (modelData, model) => {\n        if (!nestedCall[platform][model]) nestedCall[platform][model] = {};\n        modelData = _.groupBy(modelData, 'operation');\n        _.each(modelData, (operationData, operation) => {\n          operationData = _.groupBy(operationData, 'operationMode');\n          if (!nestedCall[platform][model][operation]) nestedCall[platform][model][operation] = {};\n          _.each(operationData, (operationModeData, mode) => {\n            nestedCall[platform][model][operation][mode] = _.map(operationModeData, (d) => ({\n              queryMode: d.queryMode,\n              existingVariable: d.existingVariable,\n              filter: d.filter,\n            }));\n          });\n        });\n      });\n    });\n  }\n  return {\n    models,\n    modelIndexes,\n    modelConfig,\n    newModelConfig,\n    modelEnum,\n    modelPrivate,\n    routes: { apis },\n    policy,\n    constants,\n    applicationConfig,\n    fileUpload: fileUpload || {},\n    environmentVariables: envVariables,\n    envVariables,\n    hooks,\n    rolePermission,\n    nestedCall,\n    modelAdvanceOptions,\n  };\n};\n\nconst getDirectoryAndFiles = (source) => {\n  const directory = [];\n  const files = [];\n  fs.readdirSync(source).forEach((file) => {\n    if (fs.lstatSync(path.resolve(source, file)).isDirectory()) {\n      directory.push(file);\n    } else {\n      files.push(file);\n    }\n  });\n  return {\n    directory,\n    files,\n  };\n};\n\nconst overwriteProject = async (generatedId, projectName) => {\n  await fsExtra.copy(`./output/${generatedId}/${projectName}_dhiwise_temp_app/.env`, `./output/${generatedId}/${projectName}/.env`);\n\n  const outputProjectDir = `./output/${generatedId}/${projectName}`;\n  // fsExtra.emptyDirSync(directory);\n\n  const {\n    directories, files,\n  } = await getDirectoryAndFiles(outputProjectDir);\n\n  _.forEach(directories, (dirName) => {\n    if (dirName !== 'node_modules') {\n      fsExtra.emptyDirSync(`${outputProjectDir}/${dirName}`);\n    }\n  });\n\n  _.forEach(files, (fileName) => {\n    fsExtra.remove(`${outputProjectDir}/${fileName}`);\n  });\n\n  await fsExtra.copy(`./output/${generatedId}/${projectName}_dhiwise_temp_app`, `./output/${generatedId}/${projectName}`); // copies file\n  await fsExtra.remove(`./output/${generatedId}/${projectName}_dhiwise_temp_app`);\n};\n\nconst generate = (applicationRepo, schemaRepo, generatorRepo) => async (params) => {\n  try {\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const filter = { id: params.applicationId };\n    let project = await applicationRepo.getById(filter);\n\n    if (!project) {\n      return {\n        ...BAD_REQUEST,\n        data: {},\n      };\n    }\n\n    if (project && project.inProcessStatus && (project.inProcessStatus.build_app === IN_QUEUE || project.inProcessStatus.build_app === IN_PROCESS)) {\n      return {\n        ...OK,\n        data: { applicationId: project.id },\n      };\n    }\n\n    let generated;\n    let isReBuild = false;\n\n    const definition = {\n      generatorPath: `${appRootPath}/output`,\n      inputPath: `${appRootPath}/input`,\n      code: 'NODE_EXPRESS',\n    };\n\n    const obj = {\n      config: definition,\n      applicationId: params.applicationId,\n      type: 1,\n      status: 2,\n      versionNumber: '1',\n      semanticVersionNumber: '1.0',\n    };\n\n    if (params.applicationId) {\n      const query = {\n        find: {\n          applicationId: params.applicationId,\n          isDeleted: false,\n          config: definition,\n          type: 1,\n          status: 2,\n        },\n        sortBy: { _id: -1 },\n      };\n\n      const generatedApps = await generatorRepo.getDetails(query);\n\n      if (generatedApps.length > 0) {\n        // eslint-disable-next-line prefer-destructuring\n        generated = generatedApps[0]; // latest App\n        generated.id = generated._id;\n        isReBuild = true;\n      } else {\n        obj.status = 1;\n        generated = await generatorRepo.create(obj);\n      }\n    }\n    if (!generated) {\n      return GENERATOR_FAILED_CREATE;\n    }\n\n    let requestData = {};\n    requestData = await nodeExpressRequest(params.applicationId, project, schemaRepo);\n    if (!project.configInput) {\n      project.configInput = {\n        databaseName: project.name || 'Demo',\n        port: 3000,\n        types: [\n          'Admin',\n          'User',\n        ],\n        loginAccess: {\n          Admin: [\n            'admin',\n            'device',\n            'desktop',\n            'client',\n          ],\n          User: [\n            'device',\n            'desktop',\n            'client',\n          ],\n        },\n        isAuthentication: true,\n        authModel: 'user',\n      };\n    }\n\n    // applicationConfig\n    const applicationConfig = await ApplicationConfig.getDetails({ find: { applicationId: project.id } });\n    let configSocialPlatform = [];\n    if (applicationConfig && applicationConfig.length && applicationConfig[0].socialPlatform && applicationConfig[0].socialPlatform.length) {\n      configSocialPlatform = applicationConfig[0].socialPlatform.filter((val) => {\n        if (val.credential && val.type) {\n          const key = Object.keys(val.credential);\n          if (val.credential[key]) {\n            return (val.credential && val.type);\n          }\n          return false;\n        }\n        return false;\n      });\n    }\n\n    const jsonData = {\n      logo: project.image || '',\n      config: {\n        projectName: project.name || 'Demo',\n        path: definition.generatorPath,\n        ...(project.configInput || {}),\n        ...(definition.staticConfigInputs || {}),\n        ...(definition.otherSetting || {}),\n      },\n      authentication: {\n        ...(project.configInput || {}),\n        ...(definition.staticConfigInputs || {}),\n        ...(definition.otherSetting || {}),\n        ...(requestData.applicationConfig || {}),\n      },\n      ...(project.stepInput || {}),\n      ...(requestData || {}),\n      authenticationConfig: { socialPlatform: configSocialPlatform },\n      screenTransitions: requestData.screenTransitions || [],\n    };\n\n    jsonData.id = generated.id;\n    jsonData.applicationId = project.id;\n\n    const inputFile = `${definition.inputPath}/${generated.id}.json`;\n\n    if (definition.code === 'NODE_EXPRESS') {\n      if (params.projectType === 'CC') {\n        jsonData.projectType = 'CC';\n      } else if (project.projectType) {\n        jsonData.projectType = project.projectType;\n      } else {\n        jsonData.projectType = 'MVC';\n      }\n      if (project.stepInput && project.stepInput.ormType && project.stepInput.databaseType) {\n        jsonData.ORM = GENERATOR_ORM_TYPE[project.stepInput.ormType] || '';\n        jsonData.adapter = GENERATOR_DATABASE_TYPE[project.stepInput.databaseType] || '';\n      }\n    }\n    fs.writeFileSync(inputFile, JSON.stringify(jsonData));\n    const dirPath = `${jsonData.config.path}/${generated.id}/${jsonData.config.projectName}`;\n\n    obj.projectPath = `${definition.generatorPath}/${generated.id}/${jsonData.config.projectName}`;\n    obj.status = 2;\n    generated = await generatorRepo.update(generated.id, obj);\n\n    const updateApplication = {\n      projectType: jsonData.projectType || 'MVC',\n      tempGeneratedId: generated.id,\n      'inProcessStatus.build_app': IN_QUEUE,\n    };\n\n    project = await applicationRepo.update(params.applicationId, updateApplication);\n    await generatorRepo.update(generated.id, { 'inProcessStatus.build_app': IN_QUEUE });\n\n    const status = await generateNodeCode(\n      inputFile, applicationRepo, definition, generated.id, dirPath, project.name, params.applicationId, generatorRepo, isReBuild,\n    );\n    if (status) {\n      if (isReBuild) {\n        await overwriteProject(generated.id, jsonData.config.projectName);\n      }\n      return {\n        ...PROJECT_GENERATED,\n        data: {\n          ...(_.pick(project, ['_id', 'name'])),\n          generatedId: project.tempGeneratedId,\n          path: `/output/${generated.id}/${jsonData.config.projectName}`,\n        },\n      };\n    }\n    return SERVER_ERROR;\n  } catch (err) {\n    console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = generate;\n"
  },
  {
    "path": "packages/server/usecase/application/get.js",
    "content": "const mongoose = require('mongoose');\n\nconst {\n  INVALID_REQUEST_PARAMS, APPLICATION_NOT_FOUND, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for get user.\n * @return json\n */\nconst get = (applicationRepo) => async (id) => {\n  try {\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    // Validate Unique Criteria\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return APPLICATION_NOT_FOUND;\n    }\n    const filter = {\n      filter: { find: { _id: id } },\n      fields: ['name', 'description', 'image', 'stepInput.packageName', 'stepInput.bundleId'],\n    };\n    const application = await applicationRepo.get(filter);\n\n    if (!application) {\n      return APPLICATION_NOT_FOUND;\n    }\n\n    return {\n      ...OK,\n      data: application,\n    };\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/application/getLastApplication.js",
    "content": "const {\n  APPLICATION_NOT_FOUND, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for get user.\n * @return json\n */\nconst get = (applicationRepo) => async () => {\n  try {\n    const filter = { _id: -1 };\n    const application = await applicationRepo.getAll(filter);\n\n    if (!application.length) {\n      return APPLICATION_NOT_FOUND;\n    }\n\n    return {\n      ...OK,\n      data: application[0],\n    };\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/codeGenerator.js",
    "content": "/* global  _ */\nconst path = require('path');\nconst fs = require('fs');\nconst {\n  PROJECT_TYPE, PROJECT_CREATION_STEP,\n} = require('./constants/constant');\nconst writeOperations = require('./writeOperations');\nconst { createModels } = require('./createApplication/composeModels');\nconst schemaValidation = require('./createApplication/schemaValidation');\nconst sequelizeSchemaValidation = require('./createApplication/sequelize/modelValiadation');\nconst status = require('./constants/constant');\nconst {\n  makeController, makeControllerIndex,\n} = require('./createApplication/createController');\nconst { makeRoutes } = require('./createApplication/createRoutes');\nconst {\n  makeAuth, isAuthenticationFromInput, makeAuthIndex, makeMiddlewareIndex,\n} = require('./createApplication/createAuthentication');\nconst common = require('./createApplication/utils/common');\nconst { makeIndividualPolicy } = require('./createApplication/makeCustomPolicy');\nconst {\n  makeCustomRoutes, makeControllerIndexForCustomRoutes, makeServiceForNonExistingService, makeCustomRoutesUsecase,\n} = require('./createApplication/createCustomRoutes');\nconst {\n  makeFileUploadFiles, makeFileUploadUsecase, makeFileUploadControllerIndex, makeFileUploadService,\n} = require('./createApplication/createFileUploadFiles/index');\nconst { startRenderingEJS } = require('./createApplication/render');\nconst { addSocialLogin } = require('./createApplication/thirdPartyIntegrations');\nconst { createEntities } = require('./createApplication/createEntities');\nconst {\n  generateStaticFilesForCC, generateStaticFilesForMVC, generateStaticFilesForCCSequelize, addRolePermissionService, generateStaticFilesForMVCSequelize,\n} = require('./createApplication/createStaticFiles');\nconst {\n  copyEslintrcFile, executeEslintFix,\n} = require('./createApplication/applyEslint');\nconst { generateDeleteDependencyService } = require('./createApplication/createDeleteDependencyService');\nconst generateService = require('./createApplication/service');\nconst projectSetting = require('./settings');\nconst InputParser = require('./createApplication/InputParser');\nconst sequelize = require('./createApplication/sequelize/typeConverter');\nconst createModelsSequelize = require('./createApplication/sequelize/composeModels');\nconst sequelizeService = require('./createApplication/sequelize/service');\nconst { configureMongoAuthTestCases } = require('./createApplication/createTestCases/mongooseTestCases');\nconst { configureSequelizeAuthTestCases } = require('./createApplication/createTestCases/sequelizeTestCases');\nconst { createDataAccessFiles } = require('./createApplication/createDataAccessFiles');\nconst {\n  createUseCaseFiles, createCommonUseCaseFiles,\n} = require('./createApplication/createUseCaseFiles');\n\nclass CodeGenerator {\n  constructor (projectType, databaseAdapter) {\n    this.projectType = projectType;\n    this.databaseAdapter = databaseAdapter;\n    const settingJson = projectSetting.setup(this.projectType, this.databaseAdapter);\n    this.setup = settingJson[this.projectType];\n  }\n\n  async createApp (params) {\n    const {\n      steps, templateFolderName, templateRegistry, userDirectoryStructure,\n    } = this.setup;\n    const jsonModels = _.cloneDeep(params.jsonData.models);\n    const { isReBuild } = params;\n    /*\n     * console.log('userDirectoryStructure ====== >', JSON.stringify(userDirectoryStructure));\n     * ? JSON PARSERS\n     */\n    if (_.includes(steps, PROJECT_CREATION_STEP.INPUT_PARSER)) {\n      // ? permanent parsers\n      if (!_.isEmpty(params.jsonData.config) && _.isEmpty(params.jsonData.config.port)) { params.jsonData.config.port = '5000'; }\n      params.jsonData = await InputParser.addingModelKeys(params.jsonData);\n      params.jsonData = await InputParser.fileUploadParser(params.jsonData);\n      params.jsonData = await InputParser.modelConfigParser(params.jsonData);\n      [params.jsonData.models, params.jsonData.virtualRelationship] = await InputParser.virtualRelationshipParser(params.jsonData.models);\n      params.jsonData = await InputParser.insertPassword(params.jsonData);\n      [params.jsonData.models, params.jsonData.sequenceGenerator] = InputParser.modelSequenceGeneratorParser(params.jsonData.models);\n      if (!_.isEmpty(params.jsonData.nestedCall)) params.jsonData.nestedCall = InputParser.parseNestedCallInput(params.jsonData.nestedCall, _.cloneDeep(params.jsonData.authentication.platform));\n      if (!_.isEmpty(params.jsonData.rolePermission) && params.jsonData.authentication.isAuthentication) {\n        params.jsonData = InputParser.parseRolePermissionNew(params.jsonData);\n        params.jsonData = InputParser.addRolePermissionMongoModels(params.jsonData);\n      }\n      params.jsonData = InputParser.replaceControllerNameInCustomRoutes(params.jsonData);\n      params.jsonData = InputParser.parseCustomRoute(params.jsonData);\n    }\n    if (_.includes(steps, PROJECT_CREATION_STEP.INPUT_PARSER_SEQUELIZE)) {\n      if (!_.isEmpty(params.jsonData.config) && _.isEmpty(params.jsonData.config.port)) { params.jsonData.config.port = '5000'; }\n      // ? permanent parsers\n      params.jsonData = await InputParser.addingModelKeysSequelize(params.jsonData);\n      params.jsonData = await InputParser.fileUploadParser(params.jsonData);\n      params.jsonData = await InputParser.modelConfigParser(params.jsonData);\n      [params.jsonData.models, params.jsonData.virtualRelationship] = await InputParser.virtualRelationshipParserForSequelize(params.jsonData.models);\n      params.jsonData = await InputParser.sequelizeInsertPassword(params.jsonData);\n      params.jsonData = await InputParser.sequelizeJSONParserForIDAndAutoIncrement(params.jsonData);\n      if (!_.isEmpty(params.jsonData.nestedCall)) params.jsonData.nestedCall = InputParser.parseNestedCallInput(params.jsonData.nestedCall, _.cloneDeep(params.jsonData.authentication.platform));\n      if (!_.isEmpty(params.jsonData.rolePermission) && params.jsonData.authentication.isAuthentication) {\n        params.jsonData = InputParser.parseRolePermissionNew(params.jsonData);\n        params.jsonData = InputParser.addRolePermissionSQLModels(params.jsonData);\n      }\n      params.jsonData = InputParser.replaceControllerNameInCustomRoutes(params.jsonData);\n      params.jsonData = InputParser.parseCustomRoute(params.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.QUERY_BUILDER_PARSE_SEQUELIZE)) {\n      params.jsonData.routes = InputParser.parseQueryBuildersForSequelize(_.cloneDeep(params.jsonData));\n    }\n    this.jsonData = _.cloneDeep(params.jsonData);\n    const copyOfJsonData = _.cloneDeep(params.jsonData);\n    let rootDirectory = params.directory;\n\n    // ? Create Project Dir\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_ROOT_DIRECTORY)) {\n      let tempDirName = params.projectName;\n      if (isReBuild) {\n        tempDirName = `${tempDirName}_dhiwise_temp_app`;\n      }\n\n      rootDirectory = await this.createProjectRootDirectory(params.directory, tempDirName);\n    }\n\n    // ? Mongoose Type Validation\n    if (_.includes(steps, PROJECT_CREATION_STEP.SCHEMA_VALIDATION)) {\n      this.forValidationModels = _.cloneDeep(this.jsonData.models);\n      this.jsonData.models = schemaValidation.validSchema(this.jsonData.models, `${rootDirectory}/logs`, this.jsonData.modelEnum);\n      this.postmanCollection = _.cloneDeep(this.jsonData);\n      const errorLogs = fs.existsSync(`${rootDirectory}/logs/errors.log`);\n      if (errorLogs) {\n        throw new Error('Request is not successfully executed');\n      }\n    }\n\n    // ? Mongoose Type Validation\n    if (_.includes(steps, PROJECT_CREATION_STEP.SEQUELIZE_SCHEMA_VALIDATION)) {\n      this.forValidationModels = _.cloneDeep(this.jsonData.models);\n      this.jsonData.models = sequelizeSchemaValidation.validSchema(this.jsonData.models, `${rootDirectory}/logs`);\n      const errorLogs = fs.existsSync(`${rootDirectory}/logs/errors.log`);\n      if (errorLogs) {\n        throw new Error('Request is not successfully executed');\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.SEQUELIZE_TYPE_VALIDATION)) {\n      this.postmanCollection = _.cloneDeep(this.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.SEQUELIZE_TYPE_CONVERSION)) {\n      let adapterType = false;\n      if (this.jsonData.adapter === 'mysql') {\n        adapterType = status.ADAPTER.MYSQL;\n      } else if (this.jsonData.adapter === 'mssql') {\n        adapterType = status.ADAPTER.MSSQL;\n      } else if (this.jsonData.adapter === 'postgres') {\n        adapterType = status.ADAPTER.POSTGRESQL;\n      }\n      this.jsonData.models = sequelize.setType(_.cloneDeep(this.jsonData.models), adapterType);\n    }\n\n    // ? generate blank folder structure.\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_MVC)) {\n      await generateService.createMVCBlankFolder(rootDirectory, userDirectoryStructure);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_CC)) {\n      await generateService.createCCBlankFolder(rootDirectory, userDirectoryStructure);\n    }\n\n    // ? make all dependency\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE)) {\n      this.pkg = await generateService.createPackageJson({\n        name: params.projectName,\n        packages: this.jsonData.packages,\n        mainJsFile: 'app.js',\n        sequenceGenerator: this.jsonData.sequenceGenerator,\n        jsonData: this.jsonData,\n      });\n      this.common = await generateService.commonServiceFile(`${this.setup.templateFolderName}${templateRegistry.utilsFolderPath}`, this.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE_SEQUELIZE)) {\n      const adapter = this.jsonData.adapter ? this.jsonData.adapter : null;\n      this.pkg = await generateService.createPackageJsonForSequelize({\n        name: params.projectName,\n        packages: this.jsonData.packages,\n        mainJsFile: 'app.js',\n        adapter,\n        jsonData: params.jsonData,\n      });\n      this.common = await generateService.commonServiceFile(`${this.setup.templateFolderName}${templateRegistry.utilsFolderPath}`, this.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_APP_FILE)) {\n      this.app = await generateService.setUpAppJS(this.setup.templateFolderName, this.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DB_CONNECTION_SEQUELIZE)) {\n      const dbFilePath = `${this.setup.templateFolderName}${templateRegistry.configFolderPath}`;\n      const dbConfig = await generateService.setDB(dbFilePath, this.jsonData.adapter);\n      this.db = dbConfig.db;\n      this.dbConnection = dbConfig.dbConnection;\n    }\n\n    // ? set input constants\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CONSTANT) && !_.isEmpty(this.jsonData.constants)) {\n      this.constants = this.jsonData.constants;\n    }\n\n    // ? identify Authentication form input\n    if (_.includes(steps, PROJECT_CREATION_STEP.IDENTIFY_AUTH)) {\n      this.auth = await isAuthenticationFromInput(this.jsonData);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DB_CONNECTION)) {\n      const dbFilePath = `${this.setup.templateFolderName}${templateRegistry.configFolderPath}`;\n      this.db = await generateService.setDB(dbFilePath);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.ADD_SEEDER_MONGOOSE)) {\n      if (this.auth.isAuth) {\n        [this.seeder, this.userLoginCredentials] = await generateService.addSeederMongoose(copyOfJsonData,\n          `${this.setup.templateFolderName}${templateRegistry.seedersPath}`, _.cloneDeep(this.auth), this.app);\n      } else if (this.app.locals.SHOULD_ADD_ROLE_PERMISSION) {\n        this.app.locals.SHOULD_ADD_ROLE_PERMISSION = false;\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.ADD_SEEDER_SEQUELIZE)) {\n      if (this.auth.isAuth) {\n        [this.seeder, this.userLoginCredentials] = await generateService.addSeederSequelize(copyOfJsonData,\n          `${this.setup.templateFolderName}${templateRegistry.seedersPath}`, _.cloneDeep(this.auth), this.app);\n      } else if (this.app.locals.SHOULD_ADD_ROLE_PERMISSION) {\n        this.app.locals.SHOULD_ADD_ROLE_PERMISSION = false;\n      }\n    }\n    // ? ENV File\n    if (_.includes(steps, PROJECT_CREATION_STEP.SETUP_ENV_FILE)) {\n      let env = this.jsonData.envVariables !== undefined ? this.jsonData.envVariables : {};\n      env = env ? await generateService.envParser(env) : {};\n      const {\n        envs, jsonData,\n      } = await generateService.createEnvFile(this.setup.templateFolderName, this.jsonData, {\n        database: this.jsonData.config.databaseName,\n        port: this.jsonData.config.port,\n      },\n      {\n        socialAuth: _.cloneDeep(this.auth.socialAuth),\n        env,\n      });\n      this.env = envs;\n      this.jsonData = jsonData;\n      this.postmanCollection.config = this.jsonData.config;\n    }\n\n    // ? ENV File\n    if (_.includes(steps, PROJECT_CREATION_STEP.SETUP_ENV_FILE_SEQUELIZE)) {\n      let env = this.jsonData.envVariables !== undefined ? this.jsonData.envVariables : {};\n      const shouldAddTestCaseVariables = _.includes(steps, PROJECT_CREATION_STEP.GENERATE_TEST_CASES_SEQUELIZE);\n      env = env ? await generateService.envParser(env) : {};\n      const {\n        envs, jsonData,\n      } = await generateService.createEnvFileSequelize(this.setup.templateFolderName,\n        this.jsonData, {\n          database: this.jsonData.config.databaseName,\n          port: this.jsonData.config.port,\n        },\n        {\n          socialAuth: this.auth.socialAuth,\n          env,\n          shouldAddTestCaseVariables,\n        });\n      this.env = envs;\n      this.jsonData = jsonData;\n      this.postmanCollection.config = this.jsonData.config;\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CONVERT_HOOK_NAMES)) {\n      if (!_.isEmpty(this.jsonData.hooks)) {\n        this.jsonData.hooks = InputParser.convertHookNames(this.jsonData.hooks);\n      }\n    }\n\n    // ? Create Models\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_MODELS)) {\n      let modelSetup = {};\n      if (this.auth.isAuth) {\n        modelSetup = await createModels(`${templateFolderName}${templateRegistry.modelFolderPath}`, this.jsonData, this.forValidationModels, this.auth);\n      } else {\n        modelSetup = await createModels(`${templateFolderName}${templateRegistry.modelFolderPath}`, this.jsonData, this.forValidationModels);\n      }\n      if (!_.isEmpty(modelSetup)) {\n        this.models = modelSetup.allEJSModel;\n        this.deleteDependency = modelSetup.deleteDependency;\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_SEQUELIZE_MODELS)) {\n      let modelSetup = {};\n      if (this.auth.isAuth) {\n        modelSetup = await createModelsSequelize.createModels(`${this.setup.templateFolderName}${templateRegistry.modelFolderPath}`, this.jsonData, this.forValidationModels, params.jsonData,\n          this.auth);\n      } else {\n        modelSetup = await createModelsSequelize.createModels(`${this.setup.templateFolderName}${templateRegistry.modelFolderPath}`, this.jsonData, this.forValidationModels, params.jsonData);\n      }\n      this.models = modelSetup.allEJSModel;\n      this.tableRelationships = modelSetup.tableRelationships;\n      if (!_.isEmpty(modelSetup)) {\n        this.models = modelSetup.allEJSModel;\n        this.deleteDependency = modelSetup.deleteDependency;\n      }\n    }\n\n    // Create Usecase for Custom routes\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_USECASE)) {\n      if (!_.isEmpty(this.jsonData?.routes?.apis)) {\n        const customRouteObj = {\n          customRoutes: this.jsonData.routes.apis,\n          models: this.jsonData.models,\n          userDirectoryStructure,\n          templateRegistry,\n          templateFolderName: this.setup.templateFolderName,\n        };\n        this.customRoutesUsecase = await makeCustomRoutesUsecase(customRouteObj);\n      }\n    }\n\n    // data-access files for cc\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DATA_ACCESS_FILES)) {\n      if (this.jsonData && this.jsonData.models) {\n        const templatePath = `${this.setup.templateFolderName}${templateRegistry.dataAccessFolderPath}`;\n        const { models } = this.jsonData;\n        this.dataAccessFiles = await createDataAccessFiles(templatePath, models);\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_DEPENDENCY_SERVICE) && this.deleteDependency) {\n      this.deleteDependent = await generateDeleteDependencyService(this.projectType, `${this.setup.templateFolderName}${templateRegistry.utilsFolderPath}`, this.deleteDependency);\n    }\n\n    // ? create Entity For Clean-code-architecture\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_ENTITY)) {\n      const entities = this.jsonData.models;\n      this.allEJSEntities = await createEntities(`${templateFolderName}${templateRegistry.entityFolderPath}`, entities);\n    }\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_SEQUELIZE_VALIDATION_FILE)) {\n      const validationFilePath = {\n        templateFolderName: this.setup.templateFolderName,\n        validationFolderPath: templateRegistry.validationFolderPath,\n      };\n      this.modelValidation = await generateService.createValidationFile(validationFilePath, this.forValidationModels, this.auth, this.jsonData.adapter, this.jsonData.modelEnum);\n    }\n    // ? Create Validation File\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_VALIDATION_FILE)) {\n      const validationFilePath = {\n        templateFolderName,\n        validationFolderPath: templateRegistry.validationFolderPath,\n      };\n      this.modelValidation = await generateService.createValidationFile(validationFilePath, this.forValidationModels, this.auth, '', this.jsonData.modelEnum);\n    }\n    // ? create controller Index If Project Type is CC\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CONTROLLER_INDEX)) {\n      const controllers = {\n        auth: this.auth,\n        jsonData: this.jsonData,\n        controllerFilePath: `${templateFolderName}${templateRegistry.controllerFolderPath}`,\n        deleteDependency: this.deleteDependency,\n      };\n      this.controllerIndex = await makeControllerIndex(controllers);\n    }\n\n    // ? Create Controllers\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CONTROLLERS)) {\n      const makeControllerObj = {\n        jsonData: this.jsonData,\n        deleteDependency: this.deleteDependency,\n        auth: this.auth,\n        controllerFilePath: `${templateFolderName}${templateRegistry.controllerFolderPath}`,\n        controllerGeneratedPath: `${userDirectoryStructure.generatedControllerPath}`,\n        jsonModels,\n      };\n      this.controller = await makeController(makeControllerObj);\n    }\n    // ? Create Routes\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_ROUTES)) {\n      const makeRouteObj = {\n        jsonData: this.jsonData,\n        auth: this.auth,\n        routeFilePath: `${templateFolderName}${templateRegistry.routesFolderPath}`,\n        customRoutesPath: `${templateFolderName}${templateRegistry.individualRoutesFolderPath}`,\n      };\n      const {\n        modelWiseRoutes, platformRoutes, indexRoute,\n      } = await makeRoutes(makeRouteObj);\n      this.modelWiseRoutes = modelWiseRoutes;\n      this.platformRoutes = platformRoutes;\n      if (indexRoute) this.indexRoute = indexRoute;\n      else {\n        this.indexRoute = writeOperations.loadTemplate(`${makeRouteObj.routeFilePath}/index.js`);\n        this.indexRoute.locals.PLATFORM = [];\n      }\n    }\n\n    // ? authentication  service , controller , policy , constant\n    if (!_.isEmpty(this.auth) && this.auth.isAuth) {\n      const makeAuthObj = {\n        auth: this.auth,\n        platformRoutes: this.platformRoutes,\n        configPath: `${templateFolderName}${templateRegistry.configFolderPath}`,\n        controllerPath: `${templateFolderName}${templateRegistry.controllerFolderPath}`,\n        routePath: `${templateFolderName}${templateRegistry.routesFolderPath}`,\n        servicePath: `${templateFolderName}${templateRegistry.serviceFolderPath}`,\n        middlewarePath: `${templateFolderName}${templateRegistry.middlewareFolderPath}`,\n        authControllerPath: `${userDirectoryStructure.authControllerPath}`,\n        customRoutes: this.jsonData.routes ? this.jsonData.routes : {},\n        platform: _.cloneDeep(this.auth.loginPlatform),\n        ORM: this.jsonData.ORM ? this.jsonData.ORM : status.ORM_PROVIDERS.MONGOOSE,\n        rolePermission: !_.isEmpty(this.jsonData.rolePermission),\n        projectType: this.projectType,\n        useCaseFolderPath: `${templateFolderName}${templateRegistry.useCaseFolderPath}`,\n      };\n      this.authModule = await makeAuth(makeAuthObj);\n    }\n\n    // ? Make AuthController Index For CC\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_AUTH_CONTROLLER_INDEX)) {\n      if (!_.isEmpty(this.auth) && this.auth.isAuth) {\n        const authObject = {\n          auth: this.auth,\n          controllerPath: `${templateFolderName}${templateRegistry.controllerFolderPath}`,\n          platforms: _.cloneDeep(this.jsonData.authentication.platform),\n          rolePermission: !_.isEmpty(this.jsonData.rolePermission),\n        };\n        this.authControllerIndex = await makeAuthIndex(authObject);\n      }\n    }\n\n    // ? custom policy\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CUSTOM_POLICY) && !_.isEmpty(this.jsonData.policy)) {\n      const middlewarePath = `${templateFolderName}${templateRegistry.middlewareFolderPath}`;\n      this.customPolicy = await makeIndividualPolicy(this.jsonData.policy, middlewarePath);\n    }\n\n    // ? custom routes\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES) && !_.isEmpty(this.jsonData.routes)) {\n      const makeCustomRouteObj = {\n        platform: _.cloneDeep(this.jsonData.authentication.platform),\n        routes: _.cloneDeep(this.jsonData.routes),\n        models: this.jsonData.models,\n        newModelConfig: this.jsonData.modelConfig,\n        customRoutesPath: `${templateFolderName}${templateRegistry.individualRoutesFolderPath}`,\n        generatedCustomRouteControllerPath: `${userDirectoryStructure.generatedCustomRouteControllerPath}`,\n        modelFolderPath: `${userDirectoryStructure.modelFolderPath}`,\n        validationFolderPath: `${userDirectoryStructure.validationFolderPath}`,\n        routeFolderPath: `${userDirectoryStructure.routesFolderPath}`,\n        destinationFolder: rootDirectory,\n      };\n      if (this.projectType === PROJECT_TYPE.CLEAN_CODE) {\n        makeCustomRouteObj.shouldCreateControllerIndex = true;\n      }\n      [this.customRoutes, this.shouldCopyQueryService, this.customRoutePackageDependencies, this.customRoutesWithPath, this.customRouteIndexes] = await makeCustomRoutes(makeCustomRouteObj);\n      if (this.projectType === PROJECT_TYPE.CLEAN_CODE || this.projectType === PROJECT_TYPE.CC_SEQUELIZE) {\n        this.customRoutes.shouldCreateFolderOfController = true;\n      }\n    }\n    // ? create controller index file if CC project\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_INDEX_FILES_OF_CONTROLLER_CUSTOM_ROUTES) && !_.isEmpty(this.jsonData.routes)) {\n      const makeCustomRouteObj = {\n        platform: _.cloneDeep(this.jsonData.authentication.platform),\n        routes: _.cloneDeep(this.jsonData.routes),\n        models: this.jsonData.models,\n        customRoutesPath: `${templateFolderName}${templateRegistry.individualRoutesFolderPath}`,\n        generatedCustomRouteControllerPath: `${userDirectoryStructure.generatedCustomRouteControllerPath}`,\n      };\n      this.controllerIndexForCustomRoute = await makeControllerIndexForCustomRoutes(makeCustomRouteObj, userDirectoryStructure);\n    }\n\n    // ? create controller index file if CC project\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_SERVICE) && !_.isEmpty(this.jsonData.routes)) {\n      const makeCustomRouteObj = {\n        platform: _.cloneDeep(this.jsonData.authentication.platform),\n        models: this.jsonData.models,\n        routes: _.cloneDeep(this.jsonData.routes),\n        customRoutesPath: `${this.setup.templateFolderName}${templateRegistry.individualRoutesFolderPath}`,\n      };\n      this.servicesOfCustomRoutes = await makeServiceForNonExistingService(makeCustomRouteObj);\n    }\n\n    // use-case files for cc modal wise\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_USECASE_FILES)) {\n      if (this.jsonData && this.jsonData.models) {\n        const { modelConfig } = this.jsonData;\n        const rootTemplatePath = `${this.setup.templateFolderName}${templateRegistry.useCaseFolderPath}`;\n        this.useCaseFiles = await createUseCaseFiles(rootTemplatePath, {\n          modelConfig,\n          deleteDependency: this.deleteDependency,\n          auth: this.auth,\n          defaultRole: this.jsonData.defaultRole || '',\n        });\n      }\n    }\n    // file upload service\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_SERVICE)) {\n      const templatePath = `${this.setup.templateFolderName}${templateRegistry.serviceFolderPath}`;\n      const fileUploadData = this.jsonData.fileUpload.uploads || [];\n\n      this.fileUploadService = await makeFileUploadService(templatePath, fileUploadData);\n    }\n\n    // common use-case files for cc\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_COMMON_USE_CASE_FILES)) {\n      if (this.auth.isAuth) {\n        const rootTemplatePath = `${this.setup.templateFolderName}${templateRegistry.useCaseFolderPath}`;\n        const { authService } = this.authModule;\n        this.commonUseCaseFiles = await createCommonUseCaseFiles(rootTemplatePath, authService);\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_MIDDLEWARE_INDEX)) {\n      const middlewareObj = {\n        platforms: _.cloneDeep(this.jsonData.authentication.platform),\n        projectType: this.projectType,\n        middlewarePath: `${templateFolderName}${templateRegistry.middlewareFolderPath}`,\n        userModel: this.auth.userModel,\n      };\n      this.middlewareIndex = await makeMiddlewareIndex(middlewareObj);\n    }\n    // ? create postman\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_POSTMAN)) {\n      [this.postmanCollectionJSONV20, this.postmanCollectionJSONV21, this.envPostman] = await generateService.createPostmanCollection(params.projectName, this.postmanCollection, this.auth);\n    }\n\n    // ? create postman sequelize\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_POSTMAN_SEQUELIZE)) {\n      [this.postmanCollectionJSONV20, this.postmanCollectionJSONV21, this.envPostman] = await sequelizeService.createPostmanCollection(params.projectName, this.postmanCollection, this.auth);\n    }\n\n    // ? create file-upload routes and controller\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_FILES)) {\n      if (!_.isEmpty(this.jsonData.fileUpload) && !_.isEmpty(this.jsonData.fileUpload.uploads)) {\n        const fileUploadObj = {\n          jsonData: this.jsonData.fileUpload.uploads,\n          templateFolder: templateFolderName,\n          auth: this.auth,\n          controllerPath: templateRegistry.controllerFolderPath,\n          routePath: templateRegistry.routesFolderPath,\n          fileUploadControllerPath: userDirectoryStructure.fileUploadControllerPath,\n        };\n        this.fileUpload = await makeFileUploadFiles(fileUploadObj);\n        this.fileUpload.isFolder = false;\n        if (this.projectType === PROJECT_TYPE.CLEAN_CODE || this.projectType === PROJECT_TYPE.CC_SEQUELIZE) {\n          this.fileUpload.isFolder = true;\n        }\n      }\n    }\n    // Create controller index file for file upload\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_FIE_UPLOAD_CONTROLLER_INDEX)) {\n      if (!_.isEmpty(this.jsonData.fileUpload) && !_.isEmpty(this.jsonData.fileUpload.uploads)) {\n        const templatePath = `${this.setup.templateFolderName}${templateRegistry.controllerFolderPath}`;\n        const platform = (this.jsonData.fileUpload.uploads).map((upload) => upload.platform);\n        this.fileUploadControllerIndex = await makeFileUploadControllerIndex(templatePath, platform, userDirectoryStructure);\n      }\n    }\n\n    // create Usecase file For file upload in cc\n    if (_.includes(steps, PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_USECASE)) {\n      if (!_.isEmpty(this.jsonData.fileUpload) && !_.isEmpty(this.jsonData.fileUpload.uploads)) {\n        const uploadsFunctions = this.jsonData.fileUpload.uploads;\n        const templatePath = `${this.setup.templateFolderName}${templateRegistry.useCaseFolderPath}`;\n        this.fileUploadUsecase = await makeFileUploadUsecase(templatePath, uploadsFunctions, this.jsonData.config.platform);\n      }\n    }\n    // ? add Social Login\n    if (_.includes(steps, PROJECT_CREATION_STEP.ADD_SOCIAL_LOGIN)) {\n      if (this.jsonData.authentication.isSocialMediaAuth && this.auth.isAuth) {\n        const socialObj = {\n          jsonData: this.jsonData,\n          userModel: this.auth.userModel,\n          socialAuth: this.auth.socialAuth,\n          noOfDeviceAllowed: this.auth.noOfDeviceAllowed,\n        };\n        this.socialData = await addSocialLogin(socialObj);\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_CC)) {\n      await generateStaticFilesForCC(templateFolderName, rootDirectory, userDirectoryStructure);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_MVC)) {\n      await generateStaticFilesForMVC(templateFolderName, rootDirectory, userDirectoryStructure);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_MVC_SEQUELIZE)) {\n      await generateStaticFilesForMVCSequelize(this.setup.templateFolderName, rootDirectory, userDirectoryStructure);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_CC_SEQUELIZE)) {\n      await generateStaticFilesForCCSequelize(this.setup.templateFolderName, rootDirectory, userDirectoryStructure);\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.ADD_ROLE_PERMISSION) && !_.isEmpty(this.jsonData.rolePermission)) {\n      if (this.auth.isAuth) {\n        this.rolePermissionService = await addRolePermissionService(`${this.setup.templateFolderName}${templateRegistry.middlewareFolderPath}`);\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_TEST_CASES)) {\n      if (this.auth.isAuth) {\n        const testCasesObject = {\n          jsonData: _.cloneDeep(this.jsonData),\n          authObj: _.cloneDeep(this.auth),\n          platforms: _.cloneDeep(this.jsonData.authentication.platform),\n          testCaseTemplateFolder: `${this.setup.templateFolderName}${templateRegistry.testCaseTemplatePath}`,\n          testCasePath: userDirectoryStructure.generatedTestCasePath,\n        };\n        this.testCases = configureMongoAuthTestCases(testCasesObject);\n      }\n    }\n\n    if (_.includes(steps, PROJECT_CREATION_STEP.GENERATE_TEST_CASES_SEQUELIZE)) {\n      if (this.auth.isAuth) {\n        const testCasesObject = {\n          jsonData: _.cloneDeep(copyOfJsonData),\n          authObj: _.cloneDeep(this.auth),\n          platforms: _.cloneDeep(this.jsonData.authentication.platform),\n          testCaseTemplateFolder: `${this.setup.templateFolderName}${templateRegistry.testCaseTemplatePath}`,\n          testCasePath: userDirectoryStructure.generatedTestCasePath,\n        };\n        this.testCases = configureSequelizeAuthTestCases(testCasesObject);\n      }\n    }\n    // ? if this.shouldCopyQueryService is false then again check for custom routes in Controller\n    if (!this.shouldCopyQueryService) {\n      this.shouldCopyQueryService = this.jsonData.routes && this.jsonData.routes.apis && this.jsonData.routes.apis.length ? common.shouldCopyQueryService(this.jsonData.routes.apis) : false;\n    }\n\n    // ? README file\n    const readmeObj = {\n      templateFolderName: this.setup.templateFolderName,\n      credentials: this.userLoginCredentials,\n      auth: this.auth,\n    };\n    this.readme = common.createReadMeFile(readmeObj);\n\n    // ? start to generate project\n    if (_.includes(steps, PROJECT_CREATION_STEP.RENDER_EJS)) {\n      const renderObject = {\n        type: this.projectType,\n        app: this.app,\n        appConfig: this.appConfig,\n        db: this.db,\n        models: this.models,\n        controllerDetails: this.controller,\n        modelWiseRoutes: this.modelWiseRoutes,\n        authModule: this.authModule,\n        authControllerIndex: this.authControllerIndex,\n        pkg: this.pkg,\n        services: this.services,\n        isSingleNotificationService: this.isSingleNotificationService,\n        emailService: this.emailService,\n        smsService: this.smsService,\n        webNotificationService: this.webNotificationService,\n        pushNotification: this.pushNotification,\n        indexRoute: this.indexRoute,\n        modelValidation: this.modelValidation,\n        constants: this.constants,\n        env: this.env,\n        seeder: this.seeder,\n        customPolicy: this.customPolicy,\n        shouldCopyQueryService: this.shouldCopyQueryService,\n        postmanCollectionJSONV20: this.postmanCollectionJSONV20,\n        postmanCollectionJSONV21: this.postmanCollectionJSONV21,\n        platformRoutes: this.platformRoutes,\n        customRoutes: this.customRoutes,\n        isAuth: this.auth.isAuth,\n        fileUpload: this.fileUpload,\n        socialData: this.socialData,\n        allEJSEntities: this.allEJSEntities,\n        controllerIndex: this.controllerIndex,\n        controllerIndexForCustomRoute: this.controllerIndexForCustomRoute,\n        isDeleteService: !!this.deleteDependency,\n        userDirectoryStructure,\n        templateRegistry,\n        deleteDependent: this.deleteDependent,\n        servicesOfCustomRoutes: this.servicesOfCustomRoutes,\n        tableRelationships: this.tableRelationships,\n        dbConnection: this.dbConnection,\n        customRoutePackageDependencies: this.customRoutePackageDependencies,\n        testCases: this.testCases,\n        commonService: this.common,\n        readme: this.readme ?? false,\n        envPostman: this.envPostman,\n        thirdPartySMSServices: this.thirdPartySMSServices,\n        thirdPartyEmailService: this.thirdPartyEmailService,\n        rolePermissionService: this.rolePermissionService,\n        customRoutesWithPath: this.customRoutesWithPath,\n        customRouteIndexes: this.customRouteIndexes,\n        dataAccessFiles: this.dataAccessFiles,\n        useCaseFiles: this.useCaseFiles,\n        commonUseCaseFiles: this.commonUseCaseFiles,\n        middlewareIndex: this.middlewareIndex,\n        customRoutesUsecase: this.customRoutesUsecase,\n        fileUploadService: this.fileUploadService,\n        fileUploadUsecase: this.fileUploadUsecase,\n        fileUploadControllerIndex: this.fileUploadControllerIndex,\n      };\n      await startRenderingEJS(rootDirectory, this.setup.templateFolderName, renderObject);\n    }\n\n    // ? fixing all eslint issue\n    if (_.includes(steps, PROJECT_CREATION_STEP.APPLY_ESLINT)) {\n      copyEslintrcFile(templateFolderName, rootDirectory);\n      executeEslintFix(rootDirectory);\n    }\n  }\n\n  // ? create root directory\n  async createProjectRootDirectory (directory, projectName) {\n    writeOperations.mkdir(directory, projectName);\n    writeOperations.mkdir(`${directory}${path.sep}${projectName}`, 'logs');\n    return `${directory}${path.sep}${projectName}`;\n  }\n}\nmodule.exports = CodeGenerator;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/config/mongooseInput.json",
    "content": "{\n    \"model\":{\n        \"key\":{\n            \"type\":[\"String\",\"Number\",\"Boolean\",\"Array\",\"JSON\",\"Mixed\",\"Date\",\"Buffer\",\"Map\",\"ObjectId\",\"Object\",\"Point\",\"Polygon\"],\n            \"ref\":\"string\",\n            \"index\":\"boolean\",\n            \"unique\":\"boolean\",\n            \"alias\":\"string\",\n            \"default\":[\"String\",\"Number\",\"Boolean\",\"Array\",\"JSON\",\"Mixed\",\"Date\",\"Buffer\"],\n            \"lowercase\": \"boolean\",\n            \"trim\":\"boolean\",\n            \"enum\":\"Array\",\n            \"required\":\"boolean\",\n            \"validate\":\"function\",\n            \"get\":\"function\",\n            \"set\":\"function\",\n            \"immutable\":\"boolean\",\n            \"sparse\":\"boolean\",\n            \"transform\":\"function\",\n            \"match\":\"Regex\",\n            \"minLength\":\"number\",\n            \"maxLength\":\"number\",\n            \"populate\":\"Object\",\n            \"min\":[\"number\",\"date\"],\n            \"max\":[\"number\",\"date\"],\n            \"of\":\"string\"\n        }\n    }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/config/possibleMissMatchType.js",
    "content": "const possibleTypesMissMatch = [\n  {\n    type: ['tpe', 'typ', 'tye', 'types', 'typs', 'Type'],\n    ref: ['rf', 'reff', 're', 'references', 'reference', 'ef', 'Ref'],\n    index: ['indx', 'inde', 'dex', 'ind', 'indexs', 'indexes', 'Index', 'Indexs', 'Indexes', 'Indexx', 'indexx', 'in', 'idex'],\n    unique: ['uniq', 'unquie', 'uniqs', 'uniques', 'Uniwue', 'Unique', 'uniqus', 'un', 'nique'],\n    alias: ['alas', 'alis', 'Alias', 'lias', 'slias', 'alas', 'alia'],\n    default: ['defult', 'defualt', 'efault', 'def', 'Default', 'deault', 'deflt', 'sefault',\n      'dealt', 'deful', 'defaul', 'defu', 'fefault', 'DEFAULT'],\n    lowercase: ['lower case', 'loercase', 'lowerCase', 'LowerCase', 'LOWERCASE', 'lowervase', 'loercase', 'lowecase',\n      'lorcase', 'lcase', 'Lower', 'lower'],\n    trim: ['trm', 'tri', 'rim', 'Trim', 'tirmmed', 'TRIM', 'trem', 'trum', 'tim', 'tr'],\n    enum: ['enm', 'Enum', 'enums', 'num', 'en', 'nums', 'ENUM'],\n    required: ['req', 'rewuired', 'requred', 'requrid', 'Required', 'REQUIRED', 'require', 'Require', 'requird', 'requrf', 'requrief'],\n    validate: ['Validate', 'VALIDATE', 'Val', 'val', 'lidate', 'vlidate', 'valid', 'Valid', 'VALID', 'vlid', 'valisate', 'valis', 'Valis', 'vldate'],\n    get: ['gets', 'gt', 'GET', 'Get', 'Fet', 'fet', 'det', 'gwt', 'Gwt', 'gett', 'ge', 'gte', 'geet'],\n    set: ['sets', 'st', 'SET', 'Set', 'Aet', 'aet', 'det', 'swt', 'Swt', 'sett', 'se', 'ste', 'seet'],\n    immutable: ['immtable', 'imutable', 'imtbl', 'imutble', 'immmutable', 'immutble', 'immuttablke', 'immutablke', 'Immutable', 'IMMUTABLE', 'imutbl'],\n    sparse: ['spars', 'sprde', 'sprse', 'Sparse', 'spres', 'sparde', 'Sparse', 'SPARSE', 'sprs', 'sparsee', 'sppase', 'spparse'],\n    transform: ['trans', 'trabnsfom', 'transfom', 'Transform', 'TRANSFORM', 'trnadorm', 'transorm', 'trsnsform', 'trensform'],\n    match: ['MAtch', 'matchh', 'atch', 'metch', 'mstch', 'Match', 'MATCH', 'matc', 'mAtch', 'mtch'],\n    minLength: ['minlenghts', 'minlength', 'min length', 'MInlenght', 'MinLength', 'MINLENGTH', 'mins length', 'mins', 'min-length',\n      'Min-Lenght', 'minlengtth', 'minlenght', 'lengthMin', 'legth', 'lenght'],\n    maxLength: ['maxlenghts', 'maxLenght', 'maxlength', 'max length', 'MAxlenght', 'MaxLength', 'MAXLENGTH', 'mazLength', 'maxz', 'max-length',\n      'Max-Lenght', 'maxlengtth', 'maxlength', 'lengthMax', 'legth', 'lenght'],\n    populate: ['pop', 'populte', 'Popouate', 'popuate', 'poluate', 'populyte', 'polate', 'poplate', 'polute', 'populates', 'PoPulate'],\n    min: ['mins', 'mi', 'nin', 'mun', 'mon', 'minn', 'MIn', 'MIN', 'Min'],\n    max: ['maxz', 'ma', 'maz', 'mxx', 'msx', 'maxx', 'MAx', 'MAX', 'Max'],\n    of: ['OF', 'Of', 'off', 'OFF', 'if', 'If', 'Ofs'],\n  },\n];\nmodule.exports = {\n  // eslint-disable-next-line consistent-return\n  getCorrectName (params) {\n    for (let index = 0; index < possibleTypesMissMatch.length; index += 1) {\n      const element = possibleTypesMissMatch[index];\n      const keywords = Object.keys(possibleTypesMissMatch[index]);\n      for (let j = 0; j < keywords.length; j += 1) {\n        const val = keywords[j];\n        if (element[val].includes(params)) {\n          return val;\n        }\n      }\n    }\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/config/sequelizeDataType.json",
    "content": "{\n    \"ObjectId\":\"DataTypes.INTEGER\",\n    \"SingleLine\":\"DataTypes.STRING\",\n    \"MultiLine\":\"DataTypes.TEXT\",\n    \"Email\":\"DataTypes.STRING\",\n    \"URL\":\"DataTypes.STRING\",\n    \"TEXT\": \"DataTypes.STRING\",\n    \"CHAR\": \"DataTypes.CHAR\",\n    \"BIGINT\": \"DataTypes.BIGINT\",\n    \"FLOAT\": \"DataTypes.FLOAT\",\n    \"REAL\": \"DataTypes.REAL\",\n    \"DOUBLE\": \"DataTypes.DOUBLE\",\n    \"DECIMAL\": \"DataTypes.DECIMAL\",\n    \"String\":{\n        \"length\":\"DataTypes.STRING\",\n        \"singleLength\":\"DataTypes.CHAR\",\n        \"noLength\":\"DataTypes.TEXT\"\n    },\n    \"STRING\":{\n        \"length\":\"DataTypes.STRING\",\n        \"singleLength\":\"DataTypes.CHAR\",\n        \"noLength\":\"DataTypes.TEXT\"\n    },\n    \"Number\":{\n        \"noOption\":\"DataTypes.INTEGER\",\n        \"autoIncrement\":[\"DataTypes.INTEGER\",\"DataTypes.BIGINT\"],\n        \"minMax\":\"DataTypes.RANGE\"\n    },\n    \"INTEGER\":{\n        \"noOption\":\"DataTypes.INTEGER\",\n        \"autoIncrement\":[\"DataTypes.INTEGER\",\"DataTypes.BIGINT\"],\n        \"minMax\":\"DataTypes.RANGE\"\n    },\n    \"Boolean\":\"DataTypes.BOOLEAN\",\n    \"BOOLEAN\":\"DataTypes.BOOLEAN\",\n    \"Date\":\"DataTypes.DATE\",\n    \"Object\":{\n        \"postgresql\":[\"DataTypes.HSTROE\",\"DataTypes.JSON\",\"DataTypes.JSONB\"],\n        \"mysql\":\"DataTypes.JSON\",\n        \"mssql\":\"DataTypes.TEXT\"\n    },\n    \"Map\":{\n        \"postgresql\":[\"DataTypes.HSTROE\",\"DataTypes.JSON\",\"DataTypes.JSONB\"],\n        \"mysql\":\"DataTypes.JSON\",\n        \"mssql\":\"DataTypes.TEXT\"\n    },\n    \"JSON\":{\n        \"postgres\":[\"DataTypes.HSTROE\",\"DataTypes.JSON\",\"DataTypes.JSONB\"],\n        \"mysql\":\"DataTypes.JSON\",\n        \"mssql\":\"DataTypes.TEXT\"\n    },\n    \"Array\":{\n        \"postgresql\":\"DataTypes.ARRAY\",\n        \"mysql\":\"DataTypes.JSON\",\n        \"mssql\":\"DataTypes.TEXT\"\n    },\n    \"Buffer\":\"DataTypes.BLOB\",\n    \"Decimal\":[\"DataTypes.FLOAT\",\"DataTypes.DOUBLE\",\"DataTypes.DECIMAL\"],\n    \"Percentage\":[\"DataTypes.FLOAT\",\"DataTypes.DOUBLE\",\"DataTypes.DECIMAL\"],\n    \"Currency\":[\"DataTypes.FLOAT\",\"DataTypes.DOUBLE\",\"DataTypes.DECIMAL\"],\n    \"SequelizeTypes\": [\"STRING\",\n        \"TEXT\",\n        \"CHAR\",\n        \"BOOLEAN\",\n        \"INTEGER\",\n        \"BIGINT\",\n        \"FLOAT\",\n        \"REAL\",\n        \"DOUBLE\",\n        \"DECIMAL\",\n        \"DATE\",\n        \"DATEONLY\",\n        \"UUID\",\n        \"UUIDV4\",\n        \"BLOB\",\n        \"ENUM\",\n        \"JSONB\",\n        \"JSON\",\n        \"ARARY\",\n        \"GEOMETRY\",\n        \"GEOGRAPHY\",\n        \"RANGE\",\n        \"NOTE\"],\n    \"attribute\":{\n        \"match\":\"is\",\n        \"ref\":\"reference\",\n        \"required\":\"allowNull\",\n        \"default\":\"defaultValue\",\n        \"isAutoIncrement\":\"autoIncrement\"\n    }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/config/sequelizeSupportType.json",
    "content": "{\n    \"type\": [\n        \"STRING\",\n        \"TEXT\",\n        \"CHAR\",\n        \"BOOLEAN\",\n        \"INTEGER\",\n        \"BIGINT\",\n        \"FLOAT\",\n        \"REAL\",\n        \"DOUBLE\",\n        \"DECIMAL\",\n        \"DATE\",\n        \"DATEONLY\",\n        \"UUID\",\n        \"UUIDV4\",\n        \"BLOB\",\n        \"ENUM\",\n        \"JSONB\",\n        \"JSON\",\n        \"ARRAY\",\n        \"GEOMETRY\",\n        \"VIRTUAL\",\n        \"GEOGRAPHY\"\n    ],\n    \"allowNull\":\"boolean\",\n    \"defaultValue\":[\n        \"STRING\",\n        \"TEXT\",\n        \"CHAR\",\n        \"BOOLEAN\",\n        \"INTEGER\",\n        \"BIGINT\",\n        \"FLOAT\",\n        \"REAL\",\n        \"DOUBLE\",\n        \"DECIMAL\",\n        \"DATE\",\n        \"DATEONLY\",\n        \"UUID\",\n        \"UUIDV4\",\n        \"BLOB\",\n        \"ENUM\",\n        \"JSONB\",\n        \"JSON\",\n        \"ARRAY\",\n        \"GEOMETRY\",\n        \"VIRTUAL\",\n        \"GEOGRAPHY\"\n    ],\n    \"unique\":[\"string\",\"boolean\"],\n    \"primaryKey\":\"boolean\",\n    \"autoIncrement\":\"boolean\",\n    \"field\":\"string\",\n    \"references\":{\n        \"model\":\"string\",\n        \"key\":\"string\"\n    },\n    \"comment\":\"string\",\n    \"is\":\"Regex\"\n\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/config/sequelizeTypeInput.json",
    "content": "{\n    \"model\": {\n        \"key\": {\n            \"type\": [\"STRING\", \"TEXT\", \"CHAR\", \"BOOLEAN\", \"INTEGER\", \"BIGINT\", \"FLOAT\", \"REAL\", \"DOUBLE\", \"DECIMAL\", \"DATE\", \"DATEONLY\", \"ENUM\", \"JSON\", \"GEOMETRY\", \"GEOGRAPHY\", \"TINYSTRING\", \"TINYINTEGER\"],\n            \"lowercase\": \"boolean\",\n            \"trim\": \"boolean\",\n            \"required\": \"boolean\",\n            \"unique\": \"boolean\",\n            \"match\": \"Regex\",\n            \"minLength\": \"number\",\n            \"maxLength\": \"number\",\n            \"min\": \"number\",\n            \"max\": \"number\",\n            \"enum\": \"Object\",\n            \"default\": \"number\",\n            \"isAutoIncrement\": \"boolean\",\n            \"tiny\": \"boolean\",\n            \"primary\": \"boolean\",\n            \"ref\": \"string\",\n            \"refAttribute\": \"string\",\n            \"innerDataType\": \"string\",\n            \"relType\": \"number\"\n        }\n    }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/constants/constant.js",
    "content": "module.exports = {\n  PROJECT_TYPE: {\n    CLEAN_CODE: 'CC',\n    MVC: 'MVC',\n    MVC_SEQUELIZE: 'MVC_SEQUELIZE',\n    CC_SEQUELIZE: 'CC_SEQUELIZE',\n  },\n  PROJECT_CREATION_STEP: {\n    CREATE_ROOT_DIRECTORY: 1,\n    SCHEMA_VALIDATION: 2,\n    CREATE_BLANK_DIRECTORY_CC: 3,\n    CREATE_BLANK_DIRECTORY_MVC: 4,\n    CREATE_DEPENDENT_FILE: 5,\n    CREATE_CONSTANT: 6,\n    IDENTIFY_AUTH: 7,\n    SETUP_ENV_FILE: 8,\n    CREATE_MODELS: 9,\n    CREATE_ROUTES: 10,\n    CREATE_CONTROLLER_INDEX: 11,\n    CREATE_CONTROLLERS: 12,\n    CREATE_CUSTOM_POLICY: 13,\n    CREATE_CUSTOM_ROUTES: 14,\n    CREATE_VALIDATION_FILE: 15,\n    CREATE_POSTMAN: 16,\n    CREATE_FILE_UPLOAD_FILES: 17,\n    ADD_SOCIAL_LOGIN: 18,\n    CREATE_ENTITY: 19,\n    GENERATE_STATIC_FILES_MVC: 20,\n    GENERATE_STATIC_FILES_CC: 21,\n    CREATE_AUTH_CONTROLLER_INDEX: 22,\n    CREATE_INDEX_FILES_OF_CONTROLLER_CUSTOM_ROUTES: 23,\n    INPUT_PARSER: 24,\n    PARSE_INPUT_JSON_FOR_VIRTUAL_RELATIONSHIP: 25,\n    CREATE_CUSTOM_ROUTES_SERVICE: 26,\n    CREATE_DEPENDENCY_SERVICE: 27,\n    SEQUELIZE_TYPE_CONVERSION: 28,\n    SEQUELIZE_TYPE_VALIDATION: 29,\n    CREATE_SEQUELIZE_MODELS: 30,\n    SEQUELIZE_DB_SERVICE: 31,\n    CREATE_DB_CONNECTION: 32,\n    CREATE_DB_CONNECTION_SEQUELIZE: 33,\n    CREATE_CONTROLLER_INDEX_SEQUELIZE: 34,\n    CREATE_CONTROLLERS_SEQUELIZE: 35,\n    GENERATE_STATIC_FILES_CC_SEQUELIZE: 36,\n    INPUT_PARSER_SEQUELIZE: 37,\n    CONVERT_HOOK_NAMES: 38,\n    QUERY_BUILDER_PARSE_SEQUELIZE: 39,\n    CREATE_SEQUELIZE_VALIDATION_FILE: 40,\n    CREATE_DEPENDENT_FILE_SEQUELIZE: 41,\n    ADD_ROLE_PERMISSION: 42,\n    GENERATE_TEST_CASES: 43,\n    ADD_ROLE_PERMISSION_SEQUELIZE: 44,\n    ADD_SEEDER_MONGOOSE: 45,\n    GENERATE_STATIC_FILES_MVC_SEQUELIZE: 46,\n    ADD_SEEDER_SEQUELIZE: 47,\n    CREATE_POSTMAN_SEQUELIZE: 48,\n    SETUP_ENV_FILE_SEQUELIZE: 49,\n    CREATE_APP_FILE: 50,\n    SEQUELIZE_SCHEMA_VALIDATION: 51,\n    GENERATE_TEST_CASES_SEQUELIZE: 52,\n    RENDER_EJS: 53,\n    APPLY_ESLINT: 54,\n    CREATE_DATA_ACCESS_FILES: 55,\n    CREATE_USECASE_FILES: 56,\n    CREATE_COMMON_USE_CASE_FILES: 57,\n    CREATE_MIDDLEWARE_INDEX: 58,\n    CREATE_CUSTOM_ROUTES_USECASE: 59,\n    CREATE_FIE_UPLOAD_CONTROLLER_INDEX: 60,\n    CREATE_FILE_UPLOAD_USECASE: 61,\n    CREATE_FILE_UPLOAD_SERVICE: 62,\n  },\n  SUPPORT_API: ['C', 'R', 'U', 'D', 'UP', 'HD', 'BC', 'BU'],\n  APIS: [\n    'create', 'createBulk', 'findAll', 'findById', 'count', 'update', 'bulkUpdate',\n    'partialUpdate', 'softDelete', 'delete', 'deleteMany', 'softDeleteMany',\n  ],\n  REMOVE_KEY_FROM_MONGOOSE_MODEL_FOR_SEQUELIZE_MODEL: [\n    'ref',\n    'index',\n    'alias',\n    'default',\n    'enum',\n    'required',\n    'set',\n    'get',\n    'sparse',\n    'immutable',\n    'match',\n    'transform',\n    'maxLength',\n    'minLength',\n    'populate',\n    'of',\n    'isAutoIncrement',\n    'primary',\n    'refAttribute',\n    'tiny',\n    'relType',\n  ],\n  REMOVE_KEY_FROM_MODEL_FOR_SEQUELIZE_MODEL: [\n    'ref',\n    'index',\n    'alias',\n    'default',\n    'enum',\n    'required',\n    'set',\n    'get',\n    'sparse',\n    'immutable',\n    'match',\n    'transform',\n    'maxLength',\n    'minLength',\n    'populate',\n    'of',\n    'isAutoIncrement',\n    'primary',\n    'refAttribute',\n    'default',\n    'relType',\n  ],\n  ADAPTER: {\n    MYSQL: 1,\n    MSSQL: 2,\n    POSTGRESQL: 3,\n  },\n  MODEL_CONFIG_FOR_ROLE_PERMISSION: {\n    role: {\n      create: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      createBulk: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findAll: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findById: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      partialUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      softDelete: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      update: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      count: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      bulkUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n    },\n    projectRoute: {\n      create: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      createBulk: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findAll: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findById: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      partialUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      softDelete: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      update: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      count: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      bulkUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n    },\n    routeRole: {\n      create: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      createBulk: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findAll: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findById: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      partialUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      update: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      softDelete: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      count: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      bulkUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n    },\n    userRole: {\n      create: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      createBulk: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findAll: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      findById: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      partialUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      update: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      softDelete: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      count: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n      bulkUpdate: {\n        selected: true,\n        policy: [],\n        isAuth: true,\n      },\n    },\n  },\n  MODEL_FOR_ROLE_PERMISSION: {\n    role: {\n      name: {\n        type: 'String',\n        required: true,\n      },\n      code: {\n        type: 'String',\n        required: true,\n      },\n      weight: {\n        type: 'Number',\n        required: true,\n      },\n      isActive: { type: 'Boolean' },\n      isDeleted: { type: 'Boolean' },\n    },\n    projectRoute: {\n      route_name: {\n        type: 'String',\n        required: true,\n      },\n      method: {\n        type: 'String',\n        required: true,\n      },\n      uri: {\n        type: 'String',\n        required: true,\n      },\n      isActive: { type: 'Boolean' },\n      isDeleted: { type: 'Boolean' },\n    },\n    routeRole: {\n      routeId: {\n        type: 'ObjectId',\n        ref: 'projectRoute',\n        required: true,\n      },\n      roleId: {\n        type: 'ObjectId',\n        ref: 'role',\n      },\n      isActive: { type: 'Boolean' },\n      isDeleted: { type: 'Boolean' },\n    },\n    userRole: {\n      userId: {\n        type: 'ObjectId',\n        ref: 'user',\n        required: true,\n      },\n      roleId: {\n        type: 'ObjectId',\n        ref: 'role',\n      },\n      isActive: { type: 'Boolean' },\n      isDeleted: { type: 'Boolean' },\n    },\n  },\n  MODEL_FOR_ROLE_PERMISSION_SEQUELIZE: {\n    role: {\n      name: {\n        type: 'STRING',\n        required: true,\n      },\n      code: {\n        type: 'STRING',\n        required: true,\n      },\n      weight: {\n        type: 'INTEGER',\n        required: true,\n      },\n      isActive: { type: 'BOOLEAN' },\n      isDeleted: { type: 'BOOLEAN' },\n      id: {\n        type: 'INTEGER',\n        primary: true,\n        isAutoIncrement: true,\n      },\n    },\n    projectRoute: {\n      route_name: {\n        type: 'STRING',\n        required: true,\n      },\n      method: {\n        type: 'STRING',\n        required: true,\n      },\n      uri: {\n        type: 'STRING',\n        required: true,\n      },\n      isActive: { type: 'BOOLEAN' },\n      isDeleted: { type: 'BOOLEAN' },\n      id: {\n        type: 'INTEGER',\n        primary: true,\n        isAutoIncrement: true,\n      },\n    },\n    routeRole: {\n      routeId: {\n        ref: 'projectRoute',\n        required: true,\n        type: 'INTEGER',\n        refAttribute: 'id',\n      },\n      roleId: {\n        ref: 'role',\n        type: 'INTEGER',\n        refAttribute: 'id',\n      },\n      isActive: { type: 'BOOLEAN' },\n      isDeleted: { type: 'BOOLEAN' },\n      id: {\n        type: 'INTEGER',\n        primary: true,\n        isAutoIncrement: true,\n      },\n    },\n    userRole: {\n      userId: {\n        ref: 'user',\n        required: true,\n        type: 'INTEGER',\n        refAttribute: 'id',\n      },\n      roleId: {\n        ref: 'role',\n        type: 'INTEGER',\n        required: true,\n        refAttribute: 'id',\n      },\n      isActive: { type: 'BOOLEAN' },\n      isDeleted: { type: 'BOOLEAN' },\n      id: {\n        type: 'INTEGER',\n        primary: true,\n        isAutoIncrement: true,\n      },\n    },\n  },\n  DEFAULT_ROLE: 'SYSTEM_USER',\n  DEFAULT_ADMIN_EMAIL: 'admin@gmail.com',\n  DEFAULT_ADMIN_USERNAME: 'admin@gmail.com',\n  SQL_PROVIDER: {\n    MSSQL: 'mssql',\n    MYSQL: 'mysql',\n    PGSQL: 'postgres',\n  },\n  mssql: {\n    bigint: 'Sequelize.BIGINT',\n    numeric: 'Sequelize.DECIMAL',\n    bit: 'Sequelize.BOOLEAN',\n    smallint: 'Sequelize.INTEGER',\n    decimal: 'Sequelize.DECIMAL',\n    smallmoney: 'Sequelize.DECIMAL(10,2)',\n    money: 'Sequelize.DECIMAL(10,2)',\n    int: 'Sequelize.INTEGER',\n    tinyint: 'Sequelize.INTEGER',\n    float: 'Sequelize.FLOAT',\n    real: 'Sequelize.REAL',\n    date: 'Sequelize.DATEONLY',\n    datetimeoffset: 'Sequelize.DATETIME',\n    datetime2: 'Sequelize.DATETIME',\n    datetime: 'Sequelize.DATETIME',\n    smalldatetime: 'Sequelize.DATETIME',\n    time: 'Sequelize.DATETIME',\n    char: 'Sequelize.CHAR',\n    varchar: 'Sequelize.STRING',\n    text: 'Sequelize.TEXT',\n    nchar: 'Sequelize.CHAR',\n    nvarchar: 'Sequelize.STRING',\n    binary: 'Sequelize.CHAR',\n    varbinary: 'Sequelize.STRING',\n    image: 'Sequelize.TEXT',\n    rowversion: 'Sequelize.INTEGER',\n    uniqueidentifier: 'Sequelize.UUID',\n    xml: 'Sequelize.TEXT',\n    spatialgeometrytypes: 'Sequelize.GEOMETRY',\n    spatialgeographytypes: 'Sequelize.GEOGRAPHY',\n  },\n  mysql: {\n    char: 'Sequelize.CHAR',\n    varchar: 'Sequelize.STRING',\n    tinytext: 'Sequelize.TEXT',\n    text: 'Sequelize.TEXT',\n    mediumtext: 'Sequelize.TEXT',\n    longtext: 'Sequelize.TEXT',\n    blob: 'Sequelize.BLOB',\n    mediumblob: 'Sequelize.BLOB',\n    longblob: 'Sequelize.BLOB',\n    tinyint: 'Sequelize.INTEGER',\n    bigint: 'Sequelize.BIGINT',\n    float: 'Sequelize.FLOAT',\n    double: 'Sequelize.DOUBLE',\n    decimal: 'Sequelize.DECIMAL',\n    date: 'Sequelize.DATEONLY',\n    datetime: 'Sequelize.DATE',\n    timestamp: 'Sequelize.DATE',\n    time: 'Sequelize.DATE',\n    enum: 'Sequelize.ENUM',\n    set: 'Sequelize.ARRAY',\n    boolean: 'Sequelize.BOOLEAN',\n    int: 'Sequelize.INTEGER',\n  },\n  postgres: {\n    smallint: 'Sequelize.INTEGER',\n    integer: 'Sequelize.INTEGER',\n    bigint: 'Sequelize.BIGINT',\n    decimal: 'Sequelize.DECIMAL',\n    numeric: 'Sequelize.DECIMAL',\n    real: 'Sequelize.REAL',\n    doubleprecision: 'Sequelize.DOUBLE',\n    smallserial: 'Sequelize.INTEGER',\n    serial: 'Sequelize.BIGINT',\n    money: 'Sequelize.DECIMAL',\n    varchar: 'Sequelize.STRING',\n    char: 'Sequelize.CHAR',\n    text: 'Sequelize.TEXT',\n    citext: 'Sequelize.CITEXT',\n    timestamp: 'Sequelize.DATE',\n    TIMESTAMPTXZ: 'Sequelize.DATE',\n    date: 'Sequelize.DATEONLY',\n    timewithouttimezone: 'Sequelize.DATE',\n    timewithtimezone: 'Sequelize.DATE',\n    interval: 'Sequelize.BIGINT',\n    boolean: 'Sequelize.BOOLEAN',\n    enum: 'Sequelize.ENUM',\n    point: 'Sequelize.GEOMETRY(\\'POINT\\')',\n    line: 'Sequelize.GEOMETRY(\\'LINE\\')',\n    lseg: 'Sequelize.GEOMETRY(\\'LSEG\\')',\n    box: 'Sequelize.GEOMETRY(\\'BOX\\')',\n    path: 'Sequelize.GEOMETRY(\\'PATH\\')',\n    polygon: 'Sequelize.GEOMETRY(\\'POLYGON\\')',\n    circle: 'Sequelize.GEOMETRY(\\'CIRCLE\\')',\n    uuid: 'Sequelize.UUID',\n    xml: 'Sequelize.TEXT',\n    array: 'Sequelize.ARRAY',\n    int4range: 'Sequelize.RANGE(Sequelize.INTEGER)',\n    int8range: 'Sequelize.RANGE(Sequelize.BIGINT)',\n    numrange: 'Sequelize.RANGE(Sequelize.DECIMAL)',\n    tsrange: 'Sequelize.RANGE(Sequelize.DATE)',\n    tstzrange: 'Sequelize.RANGE(Sequelize.DATE)',\n    daterange: 'Sequelize.RANGE(Sequelize.DATEONLY)',\n    cidr: 'Sequelize.CIDR',\n    inet: 'Sequelize.INET',\n    macaddr: 'Sequelize.MACADDR',\n  },\n\n  SEQUELIZE_INDEX_TYPE: {\n    UNIQUE: 'UNIQUE',\n    BTREE: 'BTREE',\n    GIN: 'GIN',\n    PARTIAL: 'PARTIAL',\n  },\n\n  DB_ADAPTER: {\n    MYSQL: 'mysql',\n    MSSQL: 'mssql',\n    POSTGRESQL: 'postgres',\n    MONGODB: 'mongodb',\n  },\n  REMOVE_FIELD_FOR_FAKE_DATA: ['isActive', 'isDeleted', 'createdAt', 'updatedAt', 'addedBy', 'modifiedBy', 'updatedBy'],\n  SEQUELIZE_DATATYPE_MAPPINGS: {\n    SEQUELIZE_STRING_TYPE: ['String', 'STRING', 'CHAR', 'TEXT'],\n    SEQUELIZE_NUMBER_TYPE: ['Number', 'NUMBER', 'INTEGER', 'BIGINT', 'REAL'],\n    SEQUELIZE_DECIMAL_TYPE: ['Double', 'FLOAT', 'REAL', 'DOUBLE', 'DECIMAL'],\n    SEQUELIZE_UUID_TYPE: ['UUID', 'UUIDV4'],\n    SEQUELIZE_DATE_TYPE: ['DATE', 'DATEONLY', 'Date', 'DATETIME'],\n    SEQUELIZE_BLOB_TYPE: ['BLOB', 'blob'],\n    SEQUELIZE_JSON_TYPE: ['JSONB', 'JSON', 'Json', 'Mixed'],\n    SEQUELIZE_ARRAY_TYPE: ['ARRAY'],\n    SEQUELIZE_GEOMETRY_TYPE: ['GEOMETRY', 'GEOGRAPHY'],\n    SEQUELIZE_RANGE_TYPE: ['RANGE'],\n    SEQUELIZE_BOOLEAN_TYPE: ['BOOLEAN', 'Boolean'],\n  },\n\n  ORM_PROVIDERS: {\n    SEQUELIZE: 'sequelize',\n    MONGOOSE: 'mongoose',\n  },\n\n  CHANGE_STRUCTURE_FIELD: {\n    config: 'configuration',\n    views: 'view',\n  },\n  SQL_RELATIONSHIP_TYPE: {\n    HAS_ONE: 1,\n    HAS_MANY: 2,\n  },\n  SEQUELIZE_DATATYPE_MAPPING_WITH_JAVASCRIPT: {\n    INTEGER: 'number',\n    STRING: 'string',\n    TEXT: 'string',\n    CHAR: 'string',\n    BOOLEAN: 'boolean',\n    BIGINT: 'number',\n    FLOAT: 'number',\n    REAL: 'number',\n    DOUBLE: 'number',\n    DECIMAL: 'number',\n    DATE: 'string',\n    DATEONLY: 'string',\n    ENUM: 'ENUM',\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/InputParser/customRoutesApi.js",
    "content": "/* global  _ */\nconst parseRoutesApiWithExistingFiles = (routes, modelObjs) => {\n  let models = [];\n  if (modelObjs) {\n    models = Object.keys(modelObjs);\n  }\n  const apis = routes.map((api) => {\n    if (api?.routeFileName && api?.controllerFileName && !_.isEmpty(models)) {\n      const routeModelName = api?.routeFileName.replace(/Routes$/, '');\n      const controllerModelName = api?.controllerFileName.replace(/Controller$/, '');\n      if (routeModelName === controllerModelName) {\n        if (models.includes(routeModelName)) {\n          api.model = routeModelName;\n          api.isUploadedCodeBlock = true;\n          api.controller = routeModelName;\n          api.service = routeModelName;\n          delete api.routeFileName;\n          delete api.controllerFileName;\n          delete api.controllerFilePath;\n          delete api.routeFilePath;\n        }\n      } else {\n        api.isUploadedCodeBlock = true;\n      }\n    }\n    return api;\n  });\n  return apis;\n};\n\nmodule.exports = { parseRoutesApiWithExistingFiles };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/InputParser/index.js",
    "content": "/* eslint-disable */\nconst { forEach, isEmpty, keys, isArray, assign, isObject, each, cloneDeep, find } = require('lodash');\nconst common = require('../utils/common');\nconst { MODEL_CONFIG_FOR_ROLE_PERMISSION, MODEL_FOR_ROLE_PERMISSION, SUPPORT_API, DEFAULT_ROLE, MODEL_FOR_ROLE_PERMISSION_SEQUELIZE, CHANGE_STRUCTURE_FIELD } = require('../../constants/constant')\nconst sortedObject = require('sorted-object');\n\nfunction getKeyWord(methods) {\n    if (methods === 'C') return 'create'\n    if (methods === 'BC') return 'createBulk'\n    if (methods === 'BU') return 'bulkUpdate'\n}\n\nconst generateModelConfigInput = async (input) => {\n    for (const platform of Object.keys(input)) {\n        for (const model of Object.keys(input[platform])) {\n            let newModel = {}\n            for (let [key, value] of Object.entries(input[platform][model])) {\n                if (key === 'R') {\n                    newModel.findAll = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                    newModel.findById = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                    newModel.count = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                }\n                else if (key === 'U') {\n                    newModel.update = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                    newModel.partialUpdate = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                } else if (key === 'HD') {\n                    newModel.delete = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                    newModel.deleteMany = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                }\n                else if (key === 'D') {\n                    newModel.softDelete = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                    newModel.softDeleteMany = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                }\n                else {\n                    keyWord = getKeyWord(key);\n                    newModel[keyWord] = {\n                        isAuth: value.isAuth || false,\n                        selected: true,\n                        policy: []\n                    }\n                }\n            }\n            input[platform][model] = newModel;\n        }\n    }\n    return input;\n}\n\nconst generateFieldSelection = async (jsonData) => {\n    let input = jsonData.newModelConfig;\n    let platform = common.identifyPlatformNew(input, cloneDeep(jsonData.authentication.platform));\n    let fieldSelection = {};\n    for (let p in platform) {\n        if (Object.keys(platform[p]).length === 0) {\n            delete platform[p]\n        }\n    }\n    for (const p of Object.keys(platform)) {\n        platformObj = {}\n        for (const model of Object.keys(platform[p])) {\n            let modelObj = {};\n            for (let [key, value] of Object.entries(platform[p][model])) {\n                if (value.attributes && value.attributes.length) {\n                    if (key === 'R') {\n                        modelObj.findAll = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                        modelObj.count = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                        modelObj.findById = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                    }\n                    else if (key === 'U') {\n                        modelObj.update = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                        modelObj.partialUpdate = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                    }\n                    else if (key === 'HD') {\n                        modelObj.delete = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                        modelObj.deleteMany = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                    }\n                    else if (key === 'D') {\n                        modelObj.softDelete = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                        modelObj.softDeleteMany = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                    }\n                    else {\n                        let keyWord = getKeyWord(key);\n                        modelObj[keyWord] = {\n                            selected: true,\n                            fields: value.attributes\n                        }\n                    }\n                }\n            }\n            platformObj[model] = modelObj\n        }\n        fieldSelection[p] = platformObj\n    }\n    if (fieldSelection) {\n        assign(jsonData, { fieldSelection });\n    }\n    return jsonData\n}\n\nconst removeAuthPolicy = async (input) => {\n    for (const platform of Object.keys(input)) {\n        for (const model of Object.keys(input[platform])) {\n            for (let [key, value] of Object.entries(input[platform][model])) {\n                if (value.policy.length && value.policy.includes('auth')) {\n                    value.policy = value.policy.filter(e => e != 'auth');\n                }\n            }\n        }\n    }\n    return input;\n}\n\nconst modelSequenceGeneratorParser = (models) => {\n    const sequenceGenerator = {}\n    forEach(models, (model, modelName) => {\n        const attrWithSeq = {};\n        forEach(keys(model), (attrName) => {\n            if (model[attrName].isAutoIncrement) {\n                attrWithSeq[attrName] = { isAutoIncrement: model[attrName].isAutoIncrement };\n            }\n            if (model[attrName].isAutoIncrement !== undefined)\n                delete model[attrName].isAutoIncrement;\n        });\n        models[modelName] = model\n        if (!isEmpty(attrWithSeq)) {\n            sequenceGenerator[modelName] = sortedObject(attrWithSeq);\n        }\n    })\n    return [models, sequenceGenerator]\n}\n\nconst modelConfigParser = async (jsonData) => {\n\n    // ? field Selection Object\n    if (!isEmpty(jsonData.newModelConfig)) {\n        jsonData = await generateFieldSelection(jsonData);\n    }\n\n    if (!isEmpty(jsonData.newModelConfig)) {\n        let platform = common.identifyPlatformNew(jsonData.newModelConfig, cloneDeep(jsonData.authentication.platform));\n        for (let p in platform) {\n            if (Object.keys(platform[p]).length === 0) {\n                delete platform[p]\n            }\n        }\n        jsonData.modelConfig = await generateModelConfigInput(platform);\n    }\n\n    if (!isEmpty(jsonData.modelConfig)) {\n        jsonData.modelConfig = await removeAuthPolicy(jsonData.modelConfig);\n    }\n    return jsonData;\n}\n\n// ? file upload parser\nconst fileUploadParser = async (jsonData) => {\n    if (jsonData.fileUpload !== undefined && !isEmpty(jsonData.fileUpload)) {\n        if (jsonData.fileUpload.uploads.length) {\n            forEach(jsonData.fileUpload.uploads, u => {\n                if (isEmpty(u.platform)) {\n                    u.platform = jsonData.authentication.platform;\n                }\n            })\n            const { uploads } = jsonData.fileUpload;\n            jsonData.fileUpload.uploads = [];\n            forEach(uploads, (u) => {\n                let obj;\n                forEach(u.platform, (p) => {\n                    obj = { ...u };\n                    obj.platform = p;\n                    jsonData.fileUpload.uploads.push(obj);\n                });\n            });\n        }\n    }\n    return jsonData;\n}\n\nconst insertPassword = async (jsonData) => {\n    if (!isEmpty(jsonData.authentication.authModel) && !isEmpty(jsonData.models[jsonData.authentication.authModel])) {\n        if (isEmpty(jsonData.authentication.loginWith)) {\n            jsonData.models[jsonData.authentication.authModel]['email'] = { type: 'String' }\n            jsonData.models[jsonData.authentication.authModel]['password'] = { type: 'String' }\n        }\n        else {\n            let modelKeys = Object.keys(jsonData.models[jsonData.authentication.authModel])\n            if (isEmpty(jsonData.authentication.loginWith.username)) {\n                jsonData.models[jsonData.authentication.authModel]['email'] = { type: 'String' }\n            }\n            else {\n                if (!modelKeys.includes(jsonData.authentication.loginWith.password)) {\n                    jsonData.models[jsonData.authentication.authModel][jsonData.authentication.loginWith.password] = { type: 'String' }\n                }\n            }\n            if (isEmpty(jsonData.authentication.loginWith.password)) {\n                jsonData.models[jsonData.authentication.authModel]['password'] = { type: 'String' }\n            }\n            else {\n                forEach(jsonData.authentication.loginWith.username, u => {\n                    if (!modelKeys.includes(u)) {\n                        jsonData.models[jsonData.authentication.authModel][u] = { type: 'String' }\n                    }\n                })\n            }\n        }\n    }\n    return jsonData;\n}\nconst sequelizeInsertPassword = async (jsonData) => {\n    if (!isEmpty(jsonData.authentication.authModel) && !isEmpty(jsonData.models[jsonData.authentication.authModel])) {\n        if (isEmpty(jsonData.authentication.loginWith)) {\n            jsonData.models[jsonData.authentication.authModel]['email'] = { type: 'STRING' }\n            jsonData.models[jsonData.authentication.authModel]['password'] = { type: 'STRING' }\n        }\n        else {\n            let modelKeys = Object.keys(jsonData.models[jsonData.authentication.authModel])\n            if (isEmpty(jsonData.authentication.loginWith.username)) {\n                jsonData.models[jsonData.authentication.authModel]['email'] = { type: 'STRING' }\n            }\n            else {\n                if (!modelKeys.includes(jsonData.authentication.loginWith.password)) {\n                    jsonData.models[jsonData.authentication.authModel][jsonData.authentication.loginWith.password] = { type: 'STRING' }\n                }\n            }\n            if (isEmpty(jsonData.authentication.loginWith.password)) {\n                jsonData.models[jsonData.authentication.authModel]['password'] = { type: 'STRING' }\n            }\n            else {\n                forEach(jsonData.authentication.loginWith.username, u => {\n                    if (!modelKeys.includes(u)) {\n                        jsonData.models[jsonData.authentication.authModel][u] = { type: 'STRING' }\n                    }\n                })\n            }\n        }\n    }\n    return jsonData;\n}\n\nconst virtualRelationshipParser = async (models) => {\n    const virtualRelationship = {};\n    forEach(models, (model, modelName) => {\n        virtualRelationship[modelName] = [];\n        forEach(model, (fieldValue, fieldName) => {\n            if (common.doesArrayContainSearchArray(keys(fieldValue), ['ref', 'foreignField', 'type']) && fieldValue?.type === \"virtualRelation\") {\n                delete fieldValue.type;\n                fieldValue.localField = fieldValue?.localField ?? \"_id\";\n                fieldValue.justOne = false;\n                virtualRelationship[modelName].push({ ...fieldValue, fieldName });\n                delete model[fieldName];\n            }\n        });\n        models[modelName] = model;\n    });\n    // remove empty arrays in virtual relationships object's keys\n    forEach(virtualRelationship, (vr, key) => {\n        if (vr.length === 0) {\n            delete virtualRelationship[key];\n        }\n    });\n    return [models, virtualRelationship];\n}\n\nconst virtualRelationshipParserForSequelize = async (models) => {\n    const virtualRelationship = {};\n    forEach(models, (model, modelName) => {\n        virtualRelationship[modelName] = [];\n        forEach(model, (fieldValue, fieldName) => {\n            if (common.doesArrayContainSearchArray(keys(fieldValue), ['ref', 'foreignField', 'localField', 'type'])) {\n                delete fieldValue.type;\n                fieldValue.justOne = false;\n                virtualRelationship[modelName].push({ ...fieldValue, fieldName });\n                delete model[fieldName];\n                assign(models[fieldValue.ref], {\n                    [fieldValue.foreignField]:\n                    {\n                        type: \"Number\"\n                    }\n                })\n\n            }\n        });\n        models[modelName] = model;\n    });\n    // remove empty arrays in virtual relationships object's keys\n    forEach(virtualRelationship, (vr, key) => {\n        if (vr.length === 0) {\n            delete virtualRelationship[key];\n        }\n    });\n    return [models, virtualRelationship];\n}\n\nconst addingModelKeys = async (jsonData) => {\n    if (isEmpty(jsonData.authentication.authModule)) {\n        jsonData.authentication.isAuthentication = false;\n        //jsonData.authentication.authModel = jsonData.models.User ? 'User' : 'user'\n    } else {\n        jsonData.authentication.isAuthentication = true;\n        jsonData.authentication.authModel = jsonData.authentication.authModule;\n    }\n    // jsonData.authentication.authModel = !isEmpty(jsonData.authentication.authModule) ? jsonData.authentication.authModule : 'user';\n    if (jsonData.authentication.isAuthentication && isEmpty(jsonData.models[jsonData.authentication.authModel])) {\n        jsonData.models[jsonData.authentication.authModel] = {\n            \"username\": {\n                \"type\": \"String\"\n            },\n            \"password\": {\n                \"type\": \"String\"\n            },\n            \"email\": {\n                \"type\": \"String\"\n            },\n            \"name\": {\n                \"type\": \"String\"\n            },\n            \"mobileNo\": {\n                \"type\": \"Number\"\n            }\n        }\n    }\n    if (jsonData.authentication.isAuthentication) {\n        jsonData.models = {\n            ...jsonData.models,\n            userTokens: {\n                userId: {\n                    type: 'ObjectId',\n                    ref: jsonData.authentication.authModel\n                },\n                token: {\n                    type: 'String'\n                },\n                tokenExpiredTime: {\n                    type: 'Date',\n                },\n                isTokenExpired: {\n                    type: 'Boolean',\n                    default: false,\n                }\n            }\n        }\n    }\n    return jsonData;\n}\n\nconst convertHookNames = (hooks) => {\n    forEach(hooks, h => {\n        if (h.pre?.length) {\n            each(h.pre, pre => pre.operation = `before${findName(pre.operation)}`)\n        }\n        if (h.post?.length) {\n            each(h.post, post => post.operation = `after${findName(post.operation)}`)\n        }\n    });\n    return hooks;\n}\n\nconst findName = (operation) => {\n    let hookName = '';\n    switch (operation) {\n        case 'save':\n            hookName = 'Create';\n            break;\n        case 'remove':\n            hookName = 'Destroy';\n            break;\n        case 'validate':\n            hookName = 'Validate';\n            break;\n        case 'find':\n            hookName = 'Find';\n            break;\n        case 'init':\n            hookName = 'Init';\n            break;\n        case 'updateOne':\n            hookName = 'Update';\n            break;\n    }\n    return hookName;\n}\n\n\nconst allOperatorKeys = {\n    $lt: '[Op.lt]',\n    $lte: '[Op.lte]',\n    $gt: '[Op.gt]',\n    $ne: '[Op.ne]',\n    $nin: '[Op.nin]',\n    $in: '[Op.in]',\n    $or: '[Op.or]',\n    $and: '[Op.and]',\n    $eq: '[Op.eq]',\n    $regex: '[Op.regex]',\n};\nconst replaceOperatorKeys = (obj) => {\n    Object.entries(obj).forEach(([key, value]) => {\n        if (isObject(value) && !isArray(value)) {\n            replaceOperatorKeys(value);\n        } else if (isArray(value)) {\n            value.forEach((v) => {\n                if (isObject(v) && !isArray(v)) {\n                    replaceOperatorKeys(v);\n                }\n            });\n        }\n        delete obj[key];\n        key = allOperatorKeys[key] ?? key;\n        obj[key] = value;\n    });\n    return obj;\n};\nconst parseFilterForSequelize = (filter) => {\n    let result = replaceOperatorKeys(filter);\n    result = JSON.stringify(result);\n    result.replace(/\\\\\"/g, '\\uFFFF');\n    result = result.replace(/\"([^\"]+)\":/g, '$1:').replace(/\\uFFFF/g, '\\\\\\\"');\n    // console.log('result :>> ', result);\n    return result;\n};\nconst parseQueryBuildersForSequelize = (jsonData) => {\n    let customRoutes = jsonData.routes && jsonData.routes.apis ? jsonData.routes : {}\n    if (customRoutes.apis && customRoutes.apis.length) {\n        for (let [index, crObj] of Object.entries(customRoutes.apis)) {\n            if (crObj?.queryBuilder) {\n                for (let [k, value] of Object.entries(crObj?.queryBuilder)) {\n                    if (value?.filter) {\n                        const temp = JSON.parse(value?.filter);\n                        value.filter = parseFilterForSequelize(temp)\n                        // console.log('value.filter :>> ', value.filter);\n                        // const temp = JSON.parse(value?.filter);\n                        // const result = recursion(temp, null)\n                        // value.filter = result\n                    }\n                }\n            }\n        }\n    }\n    return customRoutes\n}\n\nconst getMongoOperation = (val, modifier = null) => {\n    let retVal = null;\n    switch (val) {\n        case \"$lt\":\n            retVal = \"[Op.lt]\";\n            break;\n        case \"$lte\":\n            retVal = \"[Op.lte]\";\n            break;\n        case \"$gt\":\n            retVal = \"[Op.gt]\";\n            break;\n        case \"$gte\":\n            retVal = \"[Op.gte]\";\n            break;\n        case \"$ne\":\n            retVal = \"[Op.ne]\";\n            break;\n        case \"$nin\":\n            retVal = \"[Op.notIn]\";\n            break;\n        case \"$in\":\n            retVal = \"[Op.in]\";\n            break;\n        case \"$or\":\n            retVal = \"[Op.or]\";\n            break;\n        case \"$and\":\n            retVal = \"[Op.and]\";\n            break;\n        case \"$eq\":\n            retVal = \"[Op.eq]\";\n            break;\n        case \"$in\":\n            retVal = \"[Op.in]\";\n            break;\n        case '$nin':\n            retVal = \"[Op.notIn]\";\n            break;\n        case \"$regex\":\n            retVal = \"[Op.regex]\";\n            break;\n    }\n    // return retVal ? retVal.replace(/['\"]+/g, '') : retVal; \n    return retVal\n}\n\nfunction recursion(data, valueKey) {\n    let query;\n    let isNinArray = false\n    if (!isArray(data) && isObject(data) && data.in) {\n        data = data.in\n    }\n    if (!isArray(data) && isObject(data) && data.nin) {\n        data = data.nin\n        isNinArray = true\n    }\n    if (isArray(data)) {\n        query = [];\n        if (isNinArray) {\n            query = { $nin: [] };\n            each(data, (d) => {\n                query.$nin.push(d);\n            });\n        }\n        else if (typeof data[0] === 'string' && valueKey !== 'in') {\n            query = { $in: [] };\n            each(data, (d) => {\n                query.$in.push(d);\n            });\n        }\n        else {\n            each(data, (d) => {\n                query.push(recursion(d, valueKey));\n            });\n        }\n    }\n    else if (isObject(data)) {\n        query = {};\n        each(data, (v, k) => {\n            let operation\n            if (k && k == \"contains\") {\n                query[\"$regex\"] = getMongoOperation(\"like\", \"%\" + v + \"%\")\n                query[\"$options\"] = \"i\";\n            }\n            else {\n                operation = getMongoOperation(k);\n                if (!operation) valueKey = k;\n                query[operation || k] = recursion(v, valueKey);\n            }\n        });\n    }\n    else {\n        query = data\n    }\n    return query;\n}\n\n\nconst addingModelKeysSequelize = (jsonData) => {\n    if (isEmpty(jsonData.authentication.authModule)) {\n        jsonData.authentication.isAuthentication = false;\n        //jsonData.authentication.authModel = jsonData.models.User ? 'User' : 'user'\n    } else {\n        jsonData.authentication.isAuthentication = true;\n        jsonData.authentication.authModel = jsonData.authentication.authModule;\n    }\n    // jsonData.authentication.authModel = !isEmpty(jsonData.authentication.authModule) ? jsonData.authentication.authModule : 'user';\n    if (jsonData.authentication.isAuthentication && isEmpty(jsonData.models[jsonData.authentication.authModel])) {\n        jsonData.models[jsonData.authentication.authModel] = {\n            \"username\": {\n                \"type\": \"STRING\"\n            },\n            \"password\": {\n                \"type\": \"STRING\"\n            },\n            \"email\": {\n                \"type\": \"STRING\"\n            },\n            \"name\": {\n                \"type\": \"STRING\"\n            }\n        }\n    }\n    if (jsonData.authentication.isAuthentication) {\n        const userTokens = {\n            userId: {\n                type: \"INTEGER\",\n                ref: jsonData.authentication.authModel,\n                refAttribute: 'id'\n            },\n            token: {\n                type: 'STRING',\n            },\n            tokenExpiredTime: {\n                type: 'DATE',\n            },\n            isTokenExpired: {\n                type: 'BOOLEAN',\n                default: false,\n            },\n        };\n\n        const userAuthSettings = {\n            userId: {\n                type: \"INTEGER\",\n                ref: jsonData.authentication.authModel,\n                refAttribute: 'id'\n            },\n            loginOTP: {\n                type: 'STRING',\n            },\n            expiredTimeOfLoginOTP: {\n                type: 'DATE',\n            },\n            resetPasswordCode: {\n                type: 'STRING',\n            },\n            expiredTimeOfResetPasswordCode: {\n                type: 'DATE',\n            },\n            loginRetryLimit: {\n                type: 'INTEGER',\n                default: 0\n            },\n            loginReactiveTime: {\n                \"type\": \"DATE\",\n            }\n        };\n        Object.assign(jsonData.models, { userAuthSettings, userTokens });\n    }\n    forEach(jsonData.models, model => {\n        Object.assign(model, { isActive: { type: 'BOOLEAN' }, isDeleted: { type: 'BOOLEAN' } })\n    })\n    return jsonData;\n}\n\n// ? Parser for rolePermission\nconst parseRolePermission = (jsonData) => {\n    const modelsForRolePermission = MODEL_FOR_ROLE_PERMISSION\n    const modelConfigForRolePermission = MODEL_CONFIG_FOR_ROLE_PERMISSION\n    let platformWiseRolePermission;\n    // ? {model:{platform}} -> {platform:{model}}\n    if (!isEmpty(jsonData.rolePermission)) {\n        platformWiseRolePermission = common.identifyPlatform(jsonData.rolePermission);\n        for (let p in platformWiseRolePermission) {\n            if (Object.keys(platformWiseRolePermission[p]).length === 0) {\n                delete platformWiseRolePermission[p]\n            }\n        }\n        jsonData.rolePermission = platformWiseRolePermission;\n        forEach(platformWiseRolePermission, (platformObj, platformName) => {\n            forEach(platformObj, (modelObj, modelName) => {\n                let newObj = {}\n                forEach(modelObj, (roleArray, method) => {\n                    if (method === 'R') {\n                        assign(newObj, { 'findAll': roleArray })\n                        assign(newObj, { 'findById': roleArray })\n                        assign(newObj, { 'count': roleArray })\n                    } else if (method === 'U') {\n                        assign(newObj, { 'update': roleArray })\n                        assign(newObj, { 'partialUpdate': roleArray })\n                    } else {\n                        const keyword = getKeyWord(method)\n                        assign(newObj, { [keyword]: roleArray })\n                    }\n                });\n                platformObj[modelName] = newObj;\n            });\n        });\n        assign(jsonData.models, modelsForRolePermission)\n        assign(jsonData.modelConfig.admin, modelConfigForRolePermission)\n    }\n    return jsonData;\n}\n\nconst addSystemUserToRolePermission = (jsonData) => {\n    const insertedRolePermission = cloneDeep(jsonData.rolePermission)\n    const modelsInRolePermission = Object.keys(insertedRolePermission)\n    const insertedModels = Object.keys(jsonData?.models)\n    const supportedAPIs = SUPPORT_API\n    forEach(insertedModels, (model) => {\n        if (modelsInRolePermission.includes(model)) {\n            forEach(supportedAPIs, (api) => {\n                if (insertedRolePermission[model] && insertedRolePermission[model][api]) {\n                    insertedRolePermission[model][api].push(DEFAULT_ROLE)\n                } else {\n                    Object.assign(insertedRolePermission[model], { [api]: [DEFAULT_ROLE] })\n                }\n            })\n        } else {\n            Object.assign(insertedRolePermission, { [model]: {} })\n            forEach(supportedAPIs, (api) => {\n                Object.assign(insertedRolePermission[model], { [api]: [DEFAULT_ROLE] })\n            })\n        }\n    })\n    return insertedRolePermission;\n}\n\nconst parseRolePermissionNew = (jsonData) => {\n    let platformWiseRolePermission = {};\n    // ? {model:{platform}} -> {platform:{model}}\n    if (!isEmpty(jsonData.rolePermission)) {\n        jsonData.rolePermission = addSystemUserToRolePermission(jsonData)\n        const tempRolePermission = cloneDeep(jsonData.rolePermission)\n        const supportedPlatform = cloneDeep(jsonData.authentication.platform)\n        for (let i = 0; i < supportedPlatform.length; i++) {\n            Object.assign(platformWiseRolePermission, { [supportedPlatform[i]]: cloneDeep(tempRolePermission) })\n        }\n        jsonData.rolePermission = platformWiseRolePermission;\n        forEach(platformWiseRolePermission, (platformObj, platformName) => {\n            forEach(platformObj, (modelObj, modelName) => {\n                let newObj = {}\n                forEach(modelObj, (roleArray, method) => {\n                    if (method === 'R') {\n                        assign(newObj, { 'findAll': roleArray })\n                        assign(newObj, { 'findById': roleArray })\n                        assign(newObj, { 'count': roleArray })\n                    } else if (method === 'U') {\n                        assign(newObj, { 'update': roleArray })\n                        assign(newObj, { 'partialUpdate': roleArray })\n                    } else if (method === 'HD') {\n                        assign(newObj, { 'delete': roleArray })\n                        assign(newObj, { 'deleteMany': roleArray })\n                    }\n                    else if (method === 'D') {\n                        assign(newObj, { 'softDelete': roleArray })\n                        assign(newObj, { 'softDeleteMany': roleArray })\n                    } else {\n                        const keyword = getKeyWord(method)\n                        assign(newObj, { [keyword]: roleArray })\n                    }\n                });\n                platformObj[modelName] = newObj;\n            });\n        });\n    }\n    return jsonData;\n}\n\nconst addRolePermissionMongoModels = (jsonData) => {\n    assign(jsonData.models, MODEL_FOR_ROLE_PERMISSION)\n    jsonData.models.userRole.userId.ref = jsonData.authentication.authModel\n    if (!isEmpty(jsonData.authentication) && !isEmpty(jsonData.authentication.platform)) {\n        const platforms = jsonData.authentication.platform\n        if (platforms.includes('admin')) {\n            assign(jsonData.modelConfig.admin, MODEL_CONFIG_FOR_ROLE_PERMISSION)\n        } else {\n            forEach(platforms, (platform) => {\n                assign(jsonData.modelConfig[`${platform}`], MODEL_CONFIG_FOR_ROLE_PERMISSION)\n            })\n        }\n    }\n    return jsonData\n}\n\nconst addRolePermissionSQLModels = (jsonData) => {\n    assign(jsonData.models, MODEL_FOR_ROLE_PERMISSION_SEQUELIZE)\n    jsonData.models.userRole.userId.ref = jsonData.authentication.authModel\n    if (!isEmpty(jsonData.authentication) && !isEmpty(jsonData.authentication.platform)) {\n        const platforms = jsonData.authentication.platform\n        if (platforms.includes('admin')) {\n            assign(jsonData.modelConfig.admin, MODEL_CONFIG_FOR_ROLE_PERMISSION)\n        } else {\n            forEach(platforms, (platform) => {\n                assign(jsonData.modelConfig[`${platform}`], MODEL_CONFIG_FOR_ROLE_PERMISSION)\n            })\n        }\n    }\n    return jsonData\n}\n\nconst addPlatformsForThirdParty = (input, authentication) => {\n    let updated = [];\n    input.map(i => {\n        if (isEmpty(i.platforms)) {\n            i = {\n                ...i,\n                platforms: authentication.platform\n            }\n        }\n        updated.push(i);\n    })\n    return updated;\n}\n\nconst replaceControllerNameInCustomRoutes = (jsonData) => {\n    if (jsonData.models) {\n        const models = Object.keys(jsonData.models)\n        const lower_models = models.map(model => model.toLowerCase())\n        if (jsonData && jsonData.routes) {\n            const routes = jsonData.routes.apis && jsonData.routes.apis.length ? jsonData.routes.apis : []\n            if (routes && routes.length) {\n                Object.keys(routes).forEach(function (index) {\n                    if (!isEmpty(routes[index].controller)) {\n                        if (lower_models.includes((routes[index].controller).toLowerCase())) {\n                            const matchedModel = models.find((model) => model.toLowerCase() === (routes[index].controller).toLowerCase())\n                            if (!isEmpty(matchedModel)) {\n                                routes[index].controller = matchedModel\n                                routes[index].service = matchedModel\n                            }\n\n                        }\n                    }\n                })\n            }\n        }\n    }\n\n    return jsonData\n}\nconst parseCustomRoute = (jsonData) => {\n    if (jsonData && jsonData?.routes && jsonData?.models) {\n        const models = Object.keys(jsonData.models)\n        const routes = jsonData.routes.apis && jsonData.routes.apis.length ? jsonData.routes.apis : []\n        if (routes && routes.length) {\n            Object.keys(routes).forEach(function (index) {\n                if (isEmpty(routes[index].model)) {\n                    if (models.includes(routes[index].controller)) {\n                        routes[index].model = routes[index].controller\n                        routes[index].createNewFile = false\n                    } else {\n                        if (isEmpty(routes[index].controllerFilePath) && isEmpty(routes[index].controllerFileName)) {\n                            if (!isEmpty(routes[index].model)) {\n                                routes[index].createNewFile = false\n                            } else {\n                                routes[index].createNewFile = true\n                            }\n                        } else {\n                            routes[index].createNewFile = false\n                        }\n                    }\n                } else {\n                    routes[index].createNewFile = false\n                }\n            })\n        }\n    }\n    return jsonData\n}\n\n\nconst sequelizeJSONParserForIDAndAutoIncrement = (jsonData) => {\n    if (jsonData && jsonData?.models) {\n        const jsonModels = {};\n        forEach(jsonData?.models, (value, key) => {\n            if (!('id' in value)) {\n                value = {\n                    id: {\n                        type: 'INTEGER',\n                        autoIncrement: true,\n                        primaryKey: true,\n                    },\n                    ...value,\n                };\n            }\n            if ('id' in value) {\n                if (!('primaryKey' in value.id)) {\n                    value.id.primaryKey = true;\n                }\n                if (!('autoIncrement' in value.id)) {\n                    value.id.autoIncrement = true;\n                }\n            }\n            let isAutoIncrementInModel = false;\n            const incrementKeyArray = [];\n            const autoIncrementKeyArray = [\n                'INTEGER',\n                'FLOAT',\n                'DECIMAL',\n                'BIGINT',\n            ];\n            Object.keys(value).map((e) => {\n                if (value[e].autoIncrement) {\n                    if (!autoIncrementKeyArray.includes(value[e].type)) {\n                        delete value[e].autoIncrement;\n                    } else {\n                        isAutoIncrementInModel = true;\n                        incrementKeyArray.push(e);\n                    }\n                    if (incrementKeyArray.length > 1 && isAutoIncrementInModel) {\n                        delete value[e].autoIncrement;\n                    }\n                }\n            });\n            Object.assign(jsonModels, { [key]: value });\n        });\n        jsonData.models = jsonModels;\n        return jsonData;\n    }\n    return jsonData;\n}\n\n// ? Parser for NestedCall\nconst parseNestedCallInput = (nestedCalls, platforms) => {\n    let platformWiseNestedCalls;\n    // ? {model:{platform}} -> {platform:{model}}\n    if (!isEmpty(nestedCalls)) {\n        platformWiseNestedCalls = common.identifyPlatformNew(nestedCalls, platforms);\n        for (let p in platformWiseNestedCalls) {\n            if (Object.keys(platformWiseNestedCalls[p]).length === 0) {\n                delete platformWiseNestedCalls[p]\n            }\n        }\n    }\n    // make changes in C,R,U,D,HD,BU,BC\n    for (let [platform, model] of Object.entries(platformWiseNestedCalls)) {\n        for (let [modelName, nestedCallInMethod] of Object.entries(model)) {\n            let newNestedCall = {}\n            for (let [methodName, nestedCall] of Object.entries(nestedCallInMethod)) {\n\n                if (methodName === 'R') {\n                    Object.assign(newNestedCall, { 'findAll': parsePrePostOfNestedCall(nestedCall) })\n                } else if (methodName === 'U') {\n                    Object.assign(newNestedCall, { 'update': parsePrePostOfNestedCall(nestedCall) })\n                } else if (methodName === 'SR') {\n                    Object.assign(newNestedCall, { 'findById': parsePrePostOfNestedCall(nestedCall) })\n                }\n                else if (methodName === 'HD') {\n                    Object.assign(newNestedCall, { 'delete': parsePrePostOfNestedCall(nestedCall) })\n                }\n                else if (methodName === 'D') {\n                    Object.assign(newNestedCall, { 'softDelete': parsePrePostOfNestedCall(nestedCall) })\n                }\n                else if (methodName === \"count\") {\n                    Object.assign(newNestedCall, { [methodName]: parsePrePostOfNestedCall(nestedCall) })\n                } else {\n                    const keyword = getKeyWord(methodName)\n                    Object.assign(newNestedCall, { [keyword]: parsePrePostOfNestedCall(nestedCall) })\n                }\n            }\n            platformWiseNestedCalls[platform][modelName] = newNestedCall\n        }\n    }\n    return platformWiseNestedCalls\n}\n\n// ? Parser for PRE_POST of NestedCall\nconst parsePrePostOfNestedCall = (nestedCalls) => {\n    for (let [pre_post, nestedCall] of Object.entries(nestedCalls)) {\n        let newNestedCall = []\n        for (let i = 0; i < nestedCall.length; i++) {\n            if (nestedCall[i].method !== 'codeBlock' && nestedCall[i].method !== 'customQuery') {\n                if (nestedCall[i].method === 'U') {\n                    nestedCall[i].method = 'update'\n                } else if (nestedCall[i].method === 'R') {\n                    nestedCall[i].method = 'findAll'\n                }\n                else if (nestedCall[i].method === 'SR') {\n                    nestedCall[i].method = 'findById'\n                }\n                else if (nestedCall[i].method === 'HD') {\n                    nestedCall[i].method = 'delete'\n                }\n                else if (nestedCall[i].method === 'D') {\n                    nestedCall[i].method = 'softDelete'\n                }\n                else if (\"count\" === nestedCall[i].method) {\n                    nestedCall[i].method = \"count\"\n                } else {\n                    nestedCall[i].method = getKeyWord(nestedCall[i].method)\n                }\n            }\n            newNestedCall.push(nestedCall[i])\n        }\n        nestedCalls[pre_post] = newNestedCall\n    }\n    return nestedCalls\n}\nmodule.exports = {\n    modelSequenceGeneratorParser,\n    modelConfigParser,\n    fileUploadParser,\n    insertPassword,\n    virtualRelationshipParser,\n    addingModelKeys,\n    virtualRelationshipParserForSequelize,\n    convertHookNames,\n    parseQueryBuildersForSequelize,\n    addingModelKeysSequelize,\n    parseRolePermission,\n    parseRolePermissionNew,\n    addRolePermissionMongoModels,\n    addRolePermissionSQLModels,\n    parseCustomRoute,\n    sequelizeInsertPassword,\n    replaceControllerNameInCustomRoutes,\n    sequelizeJSONParserForIDAndAutoIncrement,\n    parseNestedCallInput\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/applyEslint.js",
    "content": "const { execSync } = require('child_process');\nconst fs = require('fs');\nconst writeOperations = require('../writeOperations');\n\nfunction copyEslintrcFile (templateFolderName, dir) {\n  if (!fs.existsSync(`${dir}/.eslintrc.js`)) {\n    writeOperations.copyTemplate(`${templateFolderName}/.eslintrc.js`, `${dir}/.eslintrc.js`);\n  }\n}\n\nfunction executeEslintFix (dir) {\n  try {\n    const command = `cd \"${dir}\" && eslint . --ext .js --fix`;\n    execSync(command);\n  } catch (error) {\n    // console.log(error);\n  }\n}\nmodule.exports = {\n  copyEslintrcFile,\n  executeEslintFix,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/composeModels.js",
    "content": "/* eslint-disable guard-for-in */\n/* eslint-disable no-restricted-syntax */\nconst {\n  isEmpty, forEach, lowerCase,\n} = require('lodash');\nconst { flatten } = require('flat');\nconst { getDeleteDependency } = require('./getDeleteDependency');\nconst writeOperations = require('../writeOperations');\n\nconst concatAttributes = (finalJSON, obj) => {\n  let array = [];\n  let internalObj = {};\n  const stringAttributeArray = [];\n  let formate;\n  let flag = false;\n  if (finalJSON) {\n    for (const index of finalJSON) {\n      switch (index.dataType) {\n      case 'string':\n        if (index.operator === 'space') {\n          formate = `object.${index.attribute[0]}.toString().concat(\" \",`;\n        } else {\n          formate = `object.${index.attribute[0]}.toString().concat(\"${index.operator}\",`;\n        }\n        if (index.attribute.length >= 1) {\n          formate += `object.${index.attribute[1]}.toString())`;\n        } else {\n          formate += ')';\n        }\n        stringAttributeArray.push(index.attribute[0]);\n        stringAttributeArray.push(index.attribute[1]);\n        internalObj[index.targetAttr] = formate;\n        break;\n\n      case 'boolean':\n        if (obj.boolKeys) {\n          for (const boolIndex of obj.boolKeys) {\n            const nestObj = {};\n            nestObj.true = index.attribute.true;\n            nestObj.false = index.attribute.false;\n            internalObj[boolIndex] = nestObj;\n          }\n        } else {\n          const nestObj = {};\n          nestObj.true = index.attribute.true;\n          nestObj.false = index.attribute.false;\n          internalObj[index.targetAttr] = nestObj;\n        }\n        break;\n\n      case 'date':\n        if (obj.dateKeys) {\n          for (const dateIndex of obj.dateKeys) {\n            internalObj[dateIndex] = `dayjs(object.${dateIndex}).format('${index.attribute}')`;\n          }\n        } else {\n          internalObj[index.targetAttr] = `dayjs(${internalObj[index.targetAttr]}).format('${index.attribute}')`;\n        }\n        flag = true;\n        break;\n      default:\n        break;\n      }\n      array.push(internalObj);\n      internalObj = {};\n    }\n  } else {\n    array = [];\n  }\n  return {\n    array,\n    stringAttributeArray,\n    flag,\n  };\n};\n\nconst getUnique = (obj) => {\n  let unique = false;\n  const data = Object.keys(obj);\n  for (let index = 0; index < data.length; index += 1) {\n    if (data[index] === 'unique' && obj[data[index]] === true) {\n      unique = true;\n      break;\n    } else if (typeof obj[data[index]] === 'object' && !unique) {\n      if (obj[data[index]] !== null && obj[data[index]] !== undefined) {\n        unique = getUnique(obj[data[index]]);\n      }\n    }\n  }\n  return unique;\n};\n\nconst createModels = async (dir, jsonData, forValidationModels, authObject = false) => {\n  let alreadyDoneUser = false;\n  const allEJSModel = {};\n  const deleteDependency = getDeleteDependency(jsonData.models);\n  const modelIndexes = jsonData.modelIndexes ? jsonData.modelIndexes : {};\n  forEach(jsonData.models, (value, key) => {\n    const model = writeOperations.loadTemplate(`${dir}/model.js`);\n    {\n      const unique = getUnique(value);\n      if (authObject) {\n        if (authObject.userModel !== '' && authObject.isAuth && !alreadyDoneUser && key === authObject.userModel) {\n          model.locals.IS_AUTH = authObject.isAuth;\n          model.locals.USER = true;\n          model.locals.PASSWORD = authObject.userLoginWith?.password || 'password';\n\n          // add key role and resetPassword in model\n          value.role = {\n            type: 'Number',\n            enum: 'convertObjectToEnum(USER_ROLE)',\n            required: true,\n          };\n          value.resetPasswordLink = {\n            code: 'String',\n            expireTime: 'Date',\n          };\n\n          // add key role and resetPassword in validation\n          forValidationModels[key].role = {\n            type: 'Number',\n            enum: '...convertObjectToEnum(USER_ROLE)',\n          };\n          forValidationModels[key].resetPasswordLink = {\n            code: 'String',\n            expireTime: 'Date',\n          };\n\n          // add key loginRetry limit in model and validation\n          if (!isEmpty(authObject.userLoginRetryLimit) && authObject.userLoginRetryLimit.key) {\n            value[authObject.userLoginRetryLimit.key] = {\n              type: 'Number',\n              default: 0,\n            };\n            value.loginReactiveTime = { type: 'Date' };\n          }\n\n          if (authObject.socialAuth !== undefined && authObject.socialAuth.required) {\n            const ssoAuthKeys = { sso_auth: {} };\n            for (let i = 0; i < authObject.socialAuth.platforms.length; i += 1) {\n              Object.assign(ssoAuthKeys.sso_auth, { [`${authObject.socialAuth.platforms[i].type.toLowerCase()}Id`]: { type: 'String' } });\n            }\n            const entries = Object.entries(value);\n            for (let i = 0; i < entries.length; i += 1) {\n              const [k] = entries[i];\n              if (k.includes('SSO'.toLowerCase())) {\n                delete value[k];\n              }\n            }\n            Object.assign(value, ssoAuthKeys);\n          }\n          alreadyDoneUser = true;\n        } else {\n          model.locals.IS_AUTH = false;\n          model.locals.USER = false;\n        }\n\n        // add key addedBy in model and validation\n        if (!isEmpty(jsonData.filterByLoggedInUser)) {\n          if (jsonData.filterByLoggedInUser.models[key]) {\n            const addedKey = jsonData.filterByLoggedInUser.models[key].addedByKey;\n            if (!addedKey) {\n              value.addedBy = {\n                type: 'Schema.Types.ObjectId',\n                ref: `@@${authObject.userModel}@@`,\n              };\n            } else if (!Object.keys(value).includes(addedKey)) {\n              value[addedKey] = {\n                type: 'Schema.Types.ObjectId',\n                ref: `@@${authObject.userModel}@@`,\n              };\n            }\n          } else {\n            value.addedBy = {\n              type: 'Schema.Types.ObjectId',\n              ref: `@@${authObject.userModel}@@`,\n            };\n          }\n        } else {\n          value.addedBy = {\n            type: 'Schema.Types.ObjectId',\n            ref: `@@${authObject.userModel}@@`,\n          };\n        }\n      }\n      let virtualRelationships = null;\n      if (!isEmpty(jsonData.virtualRelationship)) {\n        if (!isEmpty(jsonData.virtualRelationship[key])) {\n          virtualRelationships = jsonData.virtualRelationship[key];\n        } else {\n          virtualRelationships = null;\n        }\n      }\n\n      model.locals.VIRTUAL_RELATION = virtualRelationships;\n\n      if (jsonData.modelEnum) {\n        const modelKeys = Object.keys(value);\n        forEach(jsonData.modelEnum[key], (enumValue, enumKey) => {\n          if (modelKeys.includes(enumKey)) {\n            forEach(enumValue, (nestEnumValue, nestEnumKey) => {\n              if (Array.isArray(value[enumKey])) {\n                forEach(value[enumKey], (arrayValue) => {\n                  if (nestEnumValue.default) {\n                    arrayValue[nestEnumKey].default += `${nestEnumValue.default}`;\n                  }\n                });\n              } else if (typeof value[enumKey] === 'object') {\n                if (nestEnumKey in value[enumKey]) {\n                  forEach(value[enumKey], (objectValue) => {\n                    if (nestEnumValue.default) {\n                      objectValue.default = `${nestEnumValue.enumFile}Enum`;\n                      objectValue.default += `.${nestEnumValue.enumAttribute}`;\n                      objectValue.default += `.${nestEnumValue.default}`;\n                    }\n                  });\n                } else if (enumValue.default) {\n                  value[enumKey].default = `${enumValue.enumFile}Enum`;\n                  value[enumKey].default += `.${enumValue.enumAttribute}`;\n                  value[enumKey].default += `.${enumValue.default}`;\n                }\n              }\n            });\n          }\n        });\n      }\n\n      model.locals.DB_MODEL = key;\n      model.locals.DB_SCHEMA = value;\n      // managing auto-sequence in models\n      model.locals.ATTRS_WITH_SEQ = jsonData.sequenceGenerator[key] ? jsonData.sequenceGenerator[key] : null;\n      model.locals.DB_UNIQUE = unique;\n      let deleteModels = [];\n      // eslint-disable-next-line no-restricted-syntax\n      for (const k in deleteDependency) {\n        if (k === key) {\n          deleteModels = deleteDependency[k];\n          break;\n        } else {\n          deleteModels = [];\n        }\n      }\n      if (deleteModels.length) {\n        model.locals.DELETE_DEPENDENT_MODEL = deleteModels;\n      } else {\n        model.locals.DELETE_DEPENDENT_MODEL = false;\n      }\n\n      if (!isEmpty(jsonData.modelComment) && !isEmpty(jsonData.modelComment[key])) {\n        model.locals.COMMENT = jsonData.modelComment[key];\n      } else {\n        model.locals.COMMENT = false;\n      }\n      if (!isEmpty(jsonData.hooks) && !isEmpty(jsonData.hooks[key])) {\n        model.locals.HOOKS = jsonData.hooks[key];\n      } else {\n        model.locals.HOOKS = false;\n      }\n      if (!isEmpty(jsonData.modelEnum) && !isEmpty(jsonData.modelEnum[key])) {\n        model.locals.MODEL_ENUM = jsonData.modelEnum[key];\n      } else {\n        model.locals.MODEL_ENUM = false;\n      }\n      if (!isEmpty(jsonData.modelVariables) && !isEmpty(jsonData.modelVariables[key])) {\n        model.locals.VARIABLES = jsonData.modelVariables[key];\n      }\n\n      const modelIndex = modelIndexes ? modelIndexes[key] : [];\n      model.locals.INDEXES = modelIndex;\n      let privateAttributeArray;\n      const modelPrivateArray = [];\n      if (!isEmpty(jsonData.modelPrivate)) {\n        // ? model private attribute\n        if (!isEmpty(jsonData.modelPrivate[key])) {\n          privateAttributeArray = flatten(jsonData.modelPrivate[key]);\n          if (!isEmpty(privateAttributeArray) && Object.keys(privateAttributeArray).length) {\n            const privateAttributeObject = {};\n            // eslint-disable-next-line array-callback-return\n            Object.keys(privateAttributeArray).map((m) => {\n              if (privateAttributeArray[m]) {\n                Object.assign(privateAttributeObject, { [m.split('.private').join('')]: true });\n              }\n            });\n            forEach(jsonData.models[key], (val, k) => {\n              Object.keys(privateAttributeObject).forEach((d) => {\n                if (d.includes(k)) {\n                  if (Array.isArray(val)) {\n                    modelPrivateArray.push(d);\n                    delete privateAttributeObject[d];\n                  }\n                }\n              });\n            });\n            model.locals.IS_PRIVATE_ATTR = true;\n            model.locals.PRIVATE_ATTRS = privateAttributeObject;\n            const arrayPrivatePropertyObj = {};\n            if (modelPrivateArray.length) {\n              forEach(jsonData.models[key], (val, k) => {\n                for (let j = 0; j < modelPrivateArray.length; j += 1) {\n                  const firstElement = modelPrivateArray[j].split('.')[0];\n                  if (firstElement !== undefined && firstElement !== null) {\n                    if (k === firstElement) {\n                      const privateInputArray = jsonData.modelPrivate[key][k];\n                      if (privateInputArray) {\n                        Object.keys(privateInputArray).forEach((pi) => {\n                          Object.assign(arrayPrivatePropertyObj, { [k]: pi });\n                        });\n                      } else {\n                        model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n                      }\n                    } else {\n                      model.locals.IS_PRIVATE_ARRAY_PROPERTY = true;\n                    }\n                  } else {\n                    model.locals.IS_PRIVATE_ARRAY_PROPERTY = true;\n                  }\n                }\n              });\n              if (Object.keys(arrayPrivatePropertyObj).length) {\n                model.locals.ARRAY_PRIVATE_PROPERTY = arrayPrivatePropertyObj;\n                model.locals.IS_PRIVATE_ARRAY_PROPERTY = true;\n              } else {\n                model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n              }\n            } else {\n              model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n            }\n          } else {\n            model.locals.IS_PRIVATE_ATTR = false;\n            model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n          }\n        } else {\n          model.locals.IS_PRIVATE_ATTR = false;\n          model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n        }\n      } else {\n        model.locals.IS_PRIVATE_ATTR = false;\n        model.locals.IS_PRIVATE_ARRAY_PROPERTY = false;\n      }\n      allEJSModel[key] = model;\n      if (!isEmpty(jsonData.authentication.addDataFormate)) {\n        jsonData.addDataFormate = jsonData.authentication.addDataFormate;\n        let boolKeys = []; let dateKeys = [];\n        // if (jsonData.addDataFormate.allModels_data_format) {\n        for (const index in value) {\n          if (lowerCase(value[index].type) === 'boolean') {\n            boolKeys.push(index);\n          } if (lowerCase(value[index].type) === 'date') {\n            dateKeys.push(index);\n          }\n        }\n        if (jsonData.addDataFormate[key]) {\n          Array.prototype.push.apply(jsonData.addDataFormate[key], jsonData.addDataFormate.allModels_data_format);\n        } else {\n          jsonData.addDataFormate[key] = jsonData.addDataFormate.allModels_data_format;\n        }\n        // }\n        let formateArray = [];\n        formateArray = concatAttributes(jsonData.addDataFormate[key], {\n          boolKeys,\n          dateKeys,\n        });\n        model.locals.CONCAT_HOOK = formateArray.array;\n        model.locals.STRING_ATT = formateArray.stringAttributeArray;\n        model.locals.FLAG = formateArray.flag;\n        boolKeys = [];\n        dateKeys = [];\n      } else {\n        model.locals.CONCAT_HOOK = false;\n      }\n    }\n  });\n  return {\n    deleteDependency,\n    allEJSModel,\n  };\n};\n\nmodule.exports = {\n  createModels,\n  concatAttributes,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createAuthentication/index.js",
    "content": "const {\n  isEmpty, each, forEach, cloneDeep, snakeCase,\n} = require('lodash');\nconst {\n  getTemplateByName, getPlatformWiseAPIOfCustomRoutes,\n} = require('../utils/common');\nconst writeOperations = require('../../writeOperations');\nconst { PROJECT_TYPE } = require('../../constants/constant');\n\nasync function setPackagesForAuth ({\n  userLoginRateLimit, socialAuth,\n}) {\n  const pkg = { dependencies: {} };\n  pkg.dependencies.bcrypt = '5.0.0';\n  pkg.dependencies.jsonwebtoken = '~8.5.1';\n  pkg.dependencies.passport = '~0.4.1';\n  pkg.dependencies['passport-jwt'] = '~4.0.0';\n  pkg.dependencies.dayjs = '~1.10.7';\n  pkg.dependencies.uuid = '~8.3.2';\n  if (userLoginRateLimit && !isEmpty(userLoginRateLimit)) {\n    pkg.dependencies['express-rate-limit'] = '~5.2.6';\n  }\n  if (!isEmpty(socialAuth) && socialAuth.required) {\n    pkg.dependencies['express-session'] = '~1.17.1';\n  }\n  return pkg;\n}\nasync function getAuthorizeRoutes (PLATFORM, loginAccessPlatform) {\n  const obj = {};\n  forEach(loginAccessPlatform, (element, key) => {\n    obj[key] = [];\n    element.forEach((e) => {\n      if (PLATFORM.includes(e)) {\n        obj[key].push(`getAllBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`getBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`getCountBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`createBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`addBulkBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`updateBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`updateBulkBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`partialUpdateBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`deleteBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`softDeleteBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`fileUploadBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`logoutBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`softDeleteManyBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`deleteManyBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`changePasswordBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n        obj[key].push(`updateProfileBy${key}In${e.charAt(0).toUpperCase() + e.slice(1)}Platform`);\n      }\n    });\n  });\n  const keysOfObj = Object.keys(obj);\n  const values = Object.values(obj);\n  const keyObj = [];\n  for (let i = 0; i < keysOfObj.length; i += 1) {\n    const arr = [];\n    arr.push(keysOfObj[i]);\n    keyObj.push(arr);\n  }\n\n  const valObj = [];\n  for (let i = 0; i < values.length; i += 1) {\n    valObj.push(values[i]);\n  }\n  return {\n    valObj,\n    keyObj,\n  };\n}\n\nasync function generateAuthConstant (PLATFORM, auth, {\n  keyObj, valObj,\n}, configPath, customRoutes = {}) {\n  const {\n    userRoles, loginAccessPlatform, userLoginRetryLimit, forgotPassword, userTokenExpireTime, noOfDeviceAllowed,\n  } = auth;\n  const constant = writeOperations.loadTemplate(`${configPath}/constant.js`);\n  constant.locals.CUSTOM_ROUTES = customRoutes;\n  constant.locals.PLATFORM = PLATFORM;\n  constant.locals.USER_ROLE = userRoles;\n  constant.locals.AUTHORIZE_ROUTE_KEY = keyObj;\n  constant.locals.AUTHORIZE_ROUTE_VALUE = valObj;\n  constant.locals.LOGIN_ACCESS = loginAccessPlatform;\n  constant.locals.TOKEN_EXPIRE_TIME = userTokenExpireTime;\n  constant.locals.DEVICE_ALLOWED_REQUIRED = noOfDeviceAllowed.required;\n  constant.locals.NO_OF_DEVICE = noOfDeviceAllowed.no;\n  if (!isEmpty(userLoginRetryLimit)) {\n    constant.locals.LOGIN_RETRY_LIMIT = userLoginRetryLimit;\n  } else {\n    constant.locals.LOGIN_RETRY_LIMIT = false;\n  }\n  if (!isEmpty(forgotPassword)) {\n    const fpObj = {};\n    const sendToConstant = cloneDeep(forgotPassword);\n    const key = !isEmpty(sendToConstant.link) ? 'link' : 'otp';\n    if (sendToConstant[key]?.emailTemplate) {\n      delete sendToConstant[key].emailTemplate;\n    }\n    if (sendToConstant[key]?.smsTemplate) {\n      delete sendToConstant[key].smsTemplate;\n    }\n    if (sendToConstant[key]?.smsTemplateId) {\n      delete sendToConstant[key].smsTemplateId;\n    }\n    if (sendToConstant[key]?.emailTemplateId) {\n      delete sendToConstant[key].emailTemplateId;\n    }\n    const entries = Object.entries(sendToConstant);\n    for (let i = 0; i < entries.length; i += 1) {\n      const [k, v] = entries[i];\n      fpObj[snakeCase(k).toUpperCase()] = v;\n    }\n    let finalStr = '';\n    finalStr = JSON.stringify(fpObj, undefined, 2).toString().replace(/\"/g, '');\n    constant.locals.RESET_PASSWORD = finalStr;\n  } else {\n    constant.locals.RESET_PASSWORD = false;\n  }\n  return constant;\n}\n\nasync function generateAuthUsecase (useCaseFolderPath, {\n  userModel,\n  passwordField,\n  notificationType,\n  emailFieldName,\n  mobileFieldName,\n  userLoginRetryLimit,\n  rolePermission,\n}) {\n  const authUsecase = {};\n  authUsecase.register = {};\n  // For Register\n  const registerUseCase = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/register.js`);\n  registerUseCase.locals.FILE_NAME = 'register';\n  registerUseCase.locals.USER_MODEL = userModel;\n  registerUseCase.locals.PASSWORD_FIELD = passwordField;\n  registerUseCase.locals.NOTIFICATION_TYPE = notificationType;\n  registerUseCase.locals.EMAIL_FIELD = emailFieldName;\n  registerUseCase.locals.MOBILE_FIELD = mobileFieldName;\n  registerUseCase.locals.ROLE_DB = 'roleDb';\n  registerUseCase.locals.USER_ROLE_DB = 'userRoleDb';\n  authUsecase.register = registerUseCase;\n\n  // For ForgotPassword\n  const forgotPasswordUseCase = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/forgotPassword.js`);\n  forgotPasswordUseCase.locals.FILE_NAME = 'forgotPassword';\n  forgotPasswordUseCase.locals.USER_MODEL = userModel;\n  forgotPasswordUseCase.locals.EMAIL_FIELD = emailFieldName;\n  authUsecase.forgotPassword = forgotPasswordUseCase;\n\n  // For Reset password\n\n  const resetPasswordUseCase = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/resetPassword.js`);\n  resetPasswordUseCase.locals.FILE_NAME = 'resetPassword';\n  resetPasswordUseCase.locals.USER_MODEL = userModel;\n  resetPasswordUseCase.locals.PASSWORD_FIELD = passwordField;\n  resetPasswordUseCase.locals.EMAIL_FIELD = emailFieldName;\n  resetPasswordUseCase.locals.LOGIN_RETRY_LIMIT = userLoginRetryLimit || null;\n  authUsecase.resetPassword = resetPasswordUseCase;\n\n  // For ValidateResetPasswordOtp\n  const validateResetPasswordOtpUseCase = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/validateResetPasswordOtp.js`);\n  validateResetPasswordOtpUseCase.locals.FILE_NAME = 'validateResetPasswordOtp';\n  validateResetPasswordOtpUseCase.locals.USER_MODEL = userModel;\n  authUsecase.validateResetPasswordOtp = validateResetPasswordOtpUseCase;\n\n  // For Logout\n  const logoutUseCase = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/logout.js`);\n  logoutUseCase.locals.FILE_NAME = 'logout';\n  authUsecase.logout = logoutUseCase;\n\n  const authentication = writeOperations.loadTemplate(`${useCaseFolderPath}/authentication/authentication.js`);\n  authentication.locals.FILE_NAME = 'authentication';\n  authentication.locals.USER_MODEL = userModel;\n  authentication.locals.ROLE_PERMISSION = rolePermission;\n  authUsecase.loginWithOTP = authentication;\n\n  return authUsecase;\n}\n\nasync function authenticationSetup (platformStrategy, {\n  auth, configPath, controllerPath, routePath, authControllerPath, templates, rolePermission, projectType, useCaseFolderPath, middlewarePath,\n}) {\n  const socialPlatforms = [];\n  if (auth.socialAuth.platforms.length) {\n    each(auth.socialAuth.platforms, (p) => {\n      if (p.platforms.includes(platformStrategy)) {\n        socialPlatforms.push(p.type);\n      }\n    });\n  }\n  const or = [];\n  const {\n    userModel, userLoginWith, noOfDeviceAllowed, registerAuth, loginAccessPlatform, emailField, mobileField, userLoginRetryLimit,\n  } = auth;\n  userLoginWith.username.forEach((item) => {\n    const query = {};\n    query[item] = 'params.username';\n    or.push(query);\n  });\n  let orObj = {};\n  if (projectType === PROJECT_TYPE.MVC_SEQUELIZE) {\n    orObj['[Op.or]'] = or;\n  } else {\n    orObj.$or = or;\n  }\n  orObj = JSON.stringify(orObj);\n  orObj = orObj.toString().replace(/\"/g, '');\n\n  // PASSPORT\n  let passport;\n  if (projectType === PROJECT_TYPE.MVC || projectType === PROJECT_TYPE.MVC_SEQUELIZE) {\n    passport = writeOperations.loadTemplate(`${configPath}/passport.js`);\n    passport.locals.MODEL = userModel;\n    passport.locals.STRATEGY = platformStrategy;\n    passport.locals.LOGIN_WITH = userLoginWith.username;\n    passport.locals.MAX_DEVICE_ALLOWED = noOfDeviceAllowed.required;\n  } else {\n    passport = writeOperations.loadTemplate(`${middlewarePath}/passport.js`);\n    passport.locals.STRATEGY = platformStrategy;\n  }\n  const authController = writeOperations.loadTemplate(`${controllerPath}/authController.js`);\n  authController.locals.LOGIN_WITH = userLoginWith.username;\n  authController.locals.PLATFORM = platformStrategy;\n  authController.locals.MULTIPLE_LOGIN = orObj;\n  authController.locals.USER_MODEL = userModel;\n  authController.locals.EMAIL_FIELD = emailField || 'email';\n  authController.locals.MOBILE_FIELD = mobileField || 'mobileNo';\n  authController.locals.ROLE_PERMISSION = !!rolePermission;\n  // ? adding templates for sending email or sms\n  if (!isEmpty(registerAuth) && !isEmpty(templates)) {\n    if (!isEmpty(registerAuth.smsTemplate)) {\n      authController.locals.NOTIFICATION_TYPE = 'SMS';\n      authController.locals.REGISTER_TEMPLATE_NAME = registerAuth.smsTemplate;\n      const temps = getTemplateByName(templates, registerAuth.smsTemplate);\n      if (!isEmpty(temps) && !isEmpty(temps.attribute)) {\n        authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = temps.attribute;\n      } else {\n        authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = false;\n      }\n    } else if (!isEmpty(registerAuth.emailTemplate) && !isEmpty(templates)) {\n      const temps = getTemplateByName(templates, registerAuth.emailTemplate);\n      authController.locals.NOTIFICATION_TYPE = 'EMAIL';\n      authController.locals.REGISTER_TEMPLATE_NAME = registerAuth.emailTemplate;\n      if (!isEmpty(temps) && !isEmpty(temps.attribute)) {\n        authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = temps.attribute;\n      } else {\n        authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = false;\n      }\n    } else {\n      authController.locals.NOTIFICATION_TYPE = false;\n      authController.locals.REGISTER_TEMPLATE_NAME = false;\n      authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = false;\n    }\n  } else {\n    authController.locals.NOTIFICATION_TYPE = false;\n    authController.locals.REGISTER_TEMPLATE_NAME = false;\n    authController.locals.REGISTER_TEMPLATE_ATTRIBUTE = false;\n  }\n  authController.locals.PATH = authControllerPath;\n  const authRoutes = writeOperations.loadTemplate(`${routePath}/auth.js`);\n  authRoutes.locals.PLATFORM = platformStrategy;\n  authRoutes.locals.SOCIAL_PLATFORMS = socialPlatforms;\n  authRoutes.locals.LOGIN_ACCESS_PLATFORM = loginAccessPlatform;\n  authRoutes.locals.MODULE = platformStrategy;\n\n  let authUsecase;\n\n  if (projectType === PROJECT_TYPE.CLEAN_CODE || projectType === PROJECT_TYPE.CC_SEQUELIZE) {\n    const passwordField = userLoginWith.password || 'password';\n    const notificationType = authController.locals.NOTIFICATION_TYPE || false;\n    const emailFieldName = emailField;\n    const mobileFieldName = mobileField;\n    const pushNotification = authController.locals.PUSH_NOTIFICATION;\n\n    authUsecase = await generateAuthUsecase(useCaseFolderPath, {\n      userModel,\n      passwordField,\n      notificationType,\n      emailFieldName,\n      mobileFieldName,\n      userLoginRetryLimit,\n      rolePermission,\n      userLoginWith,\n      orObj,\n      pushNotification,\n    });\n  }\n\n  return {\n    passport,\n    authController,\n    authRoutes,\n    authUsecase,\n  };\n}\nasync function generateAuthMiddleware (PLATFORM, middlewarePath, platformWiseCustomRoutes, noOfDeviceAllowed) {\n  const middleware = writeOperations.loadTemplate(`${middlewarePath}/auth.js`);\n  middleware.locals.CUSTOM_ROUTES = platformWiseCustomRoutes;\n  middleware.locals.PLATFORM = PLATFORM;\n  middleware.locals.MAX_DEVICE_ALLOWED = noOfDeviceAllowed.required;\n  const authUser = writeOperations.loadTemplate(`${middlewarePath}/loginUser.js`);\n  authUser.locals.PLATFORM = PLATFORM;\n  return {\n    middleware,\n    authUser,\n  };\n}\nasync function generateAuthService (platforms, {\n  auth, servicePath, templates, rolePermission, projectType,\n}) {\n  const {\n    userModel, userLoginWith,\n    userLoginRetryLimit, forgotPassword, noOfDeviceAllowed, emailField, mobileField,\n  } = auth;\n  const or = [];\n  userLoginWith.username.forEach((item) => {\n    const query = {};\n    query[item] = 'username';\n    or.push(query);\n  });\n  let orObj = {};\n  if (projectType === PROJECT_TYPE.MVC_SEQUELIZE) {\n    orObj['[Op.or]'] = or;\n  } else {\n    orObj.$or = or;\n  }\n  orObj = JSON.stringify(orObj);\n  orObj = orObj.toString().replace(/\"/g, '');\n\n  const authService = writeOperations.loadTemplate(`${servicePath}/auth.js`);\n  authService.locals.PLATFORMS = platforms;\n  authService.locals.MODEL = userModel;\n  authService.locals.LOGIN_WITH = userLoginWith.username;\n  authService.locals.MULTIPLE_LOGIN = orObj;\n  authService.locals.MAX_DEVICE_ALLOWED = noOfDeviceAllowed.required;\n  authService.locals.MOBILE_FIELD = mobileField || 'mobileNo';\n  authService.locals.EMAIL_FIELD = emailField || 'email';\n  authService.locals.PASSWORD = userLoginWith.password;\n  authService.locals.ROLE_PERMISSION = rolePermission;\n\n  if (!isEmpty(userLoginRetryLimit)) {\n    authService.locals.LOGIN_RETRY_LIMIT = userLoginRetryLimit;\n  } else {\n    authService.locals.LOGIN_RETRY_LIMIT = false;\n  }\n  if (!isEmpty(forgotPassword)) {\n    if (!isEmpty(forgotPassword.otp)) {\n      authService.locals.RESET_PASSWORD = true;\n      authService.locals.FORGOT_WITH_OTP = true;\n      authService.locals.FORGOT_WITH_LINK = false;\n    } else if (!isEmpty(forgotPassword.link)) {\n      authService.locals.RESET_PASSWORD = true;\n      authService.locals.FORGOT_WITH_LINK = true;\n      authService.locals.FORGOT_WITH_OTP = false;\n    } else {\n      authService.locals.RESET_PASSWORD = false;\n      authService.locals.FORGOT_WITH_OTP = false;\n      authService.locals.FORGOT_WITH_LINK = false;\n    }\n  } else {\n    authService.locals.RESET_PASSWORD = false;\n    authService.locals.FORGOT_WITH_OTP = false;\n    authService.locals.FORGOT_WITH_LINK = false;\n  }\n\n  if (!isEmpty(forgotPassword) && !isEmpty(templates)) {\n    const key = forgotPassword.link ? 'link' : 'otp';\n    if (!isEmpty(forgotPassword[key].smsTemplate) && !isEmpty(templates)) {\n      authService.locals.RESET_PASSWORD_NOTIFICATION_TYPE = 'SMS';\n      authService.locals.RESET_PASSWORD_TEMPLATE_NAME = forgotPassword[key].smsTemplate;\n      const tmp = getTemplateByName(templates, forgotPassword[key].smsTemplate);\n      if (!isEmpty(tmp) && !isEmpty(tmp.attribute)) {\n        authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = tmp.attribute;\n      } else {\n        authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = false;\n      }\n    } else if (!isEmpty(forgotPassword[key].emailTemplate) && !isEmpty(templates)) {\n      authService.locals.RESET_PASSWORD_NOTIFICATION_TYPE = 'EMAIL';\n      authService.locals.RESET_PASSWORD_TEMPLATE_NAME = forgotPassword[key].emailTemplate;\n      const tmp = getTemplateByName(templates, forgotPassword[key].emailTemplate);\n      if (!isEmpty(tmp) && !isEmpty(tmp.attribute)) {\n        authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = tmp.attribute;\n      } else {\n        authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = false;\n      }\n    } else {\n      authService.locals.RESET_PASSWORD_NOTIFICATION_TYPE = false;\n      authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = false;\n      authService.locals.RESET_PASSWORD_TEMPLATE_NAME = false;\n    }\n  } else {\n    authService.locals.RESET_PASSWORD_NOTIFICATION_TYPE = false;\n    authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = false;\n    authService.locals.RESET_PASSWORD_TEMPLATE_NAME = false;\n  }\n  return authService;\n}\nasync function makeAuth (makeAuthObj) {\n  const app = { locals: {} };\n  const PLATFORM = makeAuthObj.platform;\n  const platformForAuth = makeAuthObj.platform;\n  app.locals.PLATFORM = platformForAuth;\n  app.locals.IS_AUTH = makeAuthObj.auth.isAuth;\n\n  const packageDependency = await setPackagesForAuth({\n    userLoginRateLimit: makeAuthObj.auth.userLoginRateLimit,\n    socialAuth: makeAuthObj.auth.socialAuth,\n  });\n\n  const {\n    valObj, keyObj,\n  } = await getAuthorizeRoutes(PLATFORM, makeAuthObj.auth.loginAccessPlatform);\n  let platformWiseCustomRoutes = {};\n  if (makeAuthObj.customRoutes && makeAuthObj.customRoutes.apis && makeAuthObj.customRoutes.apis.length) {\n    platformWiseCustomRoutes = getPlatformWiseAPIOfCustomRoutes(cloneDeep(makeAuthObj.customRoutes.apis));\n  }\n  const constant = await generateAuthConstant(PLATFORM, makeAuthObj.auth, {\n    keyObj,\n    valObj,\n  }, makeAuthObj.configPath, platformWiseCustomRoutes);\n\n  const authSetup = {};\n  forEach(platformForAuth, async (platformName) => {\n    authSetup[platformName] = await authenticationSetup(platformName, makeAuthObj);\n  });\n\n  const authService = await generateAuthService(PLATFORM, makeAuthObj);\n\n  const policy = await generateAuthMiddleware(PLATFORM, makeAuthObj.middlewarePath, platformWiseCustomRoutes, makeAuthObj.auth.noOfDeviceAllowed);\n\n  let isForgotPasswordTemplate = false;\n  const key = makeAuthObj.auth.forgotPassword.link ? 'link' : 'otp';\n  if (!isEmpty(makeAuthObj.auth.forgotPassword[key]) && !isEmpty(makeAuthObj.templates)) {\n    if (!isEmpty(makeAuthObj.auth.forgotPassword[key].emailTemplate) || !isEmpty(makeAuthObj.auth.forgotPassword[key].smsTemplate)) {\n      isForgotPasswordTemplate = true;\n    }\n  }\n  return {\n    app,\n    authSetup,\n    authService,\n    constant,\n    packageDependency,\n    policy,\n    isForgotPasswordTemplate,\n    forgotPassword: makeAuthObj.auth.forgotPassword,\n  };\n}\nasync function isAuthenticationFromInput (jsonData) {\n  let isAuth = false;\n  let registerAuth = {};\n  let userRoles = [];\n  let loginAccessPlatform = {};\n  let userModel = '';\n  let userTokenExpireTime = 10000;\n  let emailField = 'email';\n  let mobileField = 'mobileNo';\n\n  let userLoginWith = {\n    username: ['email'],\n    password: 'password',\n  };\n  let forgotPassword = {\n    link: {\n      email: true,\n      sms: false,\n    },\n    expireTime: 20,\n  };\n  let userLoginRateLimit = false;\n  const userLoginRetryLimit = {\n    max: 3,\n    reActiveTime: 20,\n    key: 'loginRetryLimit',\n  };\n  const socialAuth = {\n    required: false,\n    platforms: [],\n  };\n  const noOfDeviceAllowed = {\n    required: false,\n    no: 1,\n  };\n  if (jsonData.authentication.isAuthentication !== undefined && jsonData.authentication.loginAccess !== undefined && jsonData.authentication.types !== undefined) {\n    const {\n      isAuthentication, loginAccess, types, authModel, loginWith, resetPassword, loginRateLimit, loginRetryLimit, tokenExpireTime,\n      registerUser,\n    } = jsonData.authentication;\n    isAuth = isAuthentication === true;\n    userRoles = types.length > 0 ? types : [];\n    loginAccessPlatform = loginAccess;\n    if (!isEmpty(loginWith)) {\n      if (!isEmpty(loginWith.username)) {\n        if (loginWith.username.includes('password')) {\n          loginWith.username = loginWith.username.filter((e) => e !== 'password');\n        }\n        userLoginWith = loginWith;\n      }\n      if (!isEmpty(loginWith.password)) {\n        userLoginWith.password = loginWith.password;\n      }\n    }\n    if (!isEmpty(registerUser)) {\n      registerAuth = registerUser;\n    }\n    if (!isEmpty(loginRetryLimit)) {\n      if (loginRetryLimit.max && loginRetryLimit.max !== '') {\n        userLoginRetryLimit.max = loginRetryLimit.max;\n      }\n      if (loginRetryLimit.reActiveTime && loginRetryLimit.reActiveTime !== '') {\n        userLoginRetryLimit.reActiveTime = loginRetryLimit.reActiveTime;\n      }\n    }\n\n    userModel = authModel || 'user';\n    if (!isEmpty(resetPassword)) {\n      if (!isEmpty(resetPassword.otp)) {\n        delete resetPassword.otp.masterIds;\n        if (!resetPassword.otp.email) {\n          resetPassword.otp.email = false;\n        }\n        if (!resetPassword.otp.sms) {\n          resetPassword.otp.sms = false;\n        }\n        forgotPassword = resetPassword;\n      } else if (!isEmpty(resetPassword.link)) {\n        delete resetPassword.link.masterIds;\n        if (!resetPassword.link.email) {\n          resetPassword.link.email = false;\n        }\n        if (!resetPassword.link.sms) {\n          resetPassword.link.sms = false;\n        }\n        forgotPassword = resetPassword;\n      }\n    }\n    userLoginRateLimit = isEmpty(loginRateLimit) ? userLoginRateLimit : loginRateLimit;\n    userTokenExpireTime = tokenExpireTime !== undefined ? tokenExpireTime : userTokenExpireTime;\n  }\n  if (jsonData.authentication.isSocialMediaAuth !== undefined && jsonData.authentication.isSocialMediaAuth && isAuth) {\n    if (!isEmpty(jsonData.authentication.socialPlatform) && jsonData.authentication.socialPlatform.length) {\n      socialAuth.required = true;\n      for (let i = 0; i < jsonData.authentication.socialPlatform.length; i += 1) {\n        if (jsonData.authentication.socialPlatform[i].isChecked) {\n          socialAuth.platforms.push(jsonData.authentication.socialPlatform[i]);\n        }\n      }\n      for (let i = 0; i < socialAuth.platforms.length; i += 1) {\n        if (isEmpty(socialAuth.platforms[i].platforms) || socialAuth.platforms[i].platforms.length === 0) {\n          socialAuth.platforms[i].platforms = jsonData.authentication.platform;\n        }\n      }\n    }\n  }\n  if (jsonData.authentication.restrictNoOfDevice !== undefined && jsonData.authentication.restrictNoOfDevice && isAuth) {\n    noOfDeviceAllowed.required = true;\n    noOfDeviceAllowed.no = jsonData.authentication.noOfDevice;\n  }\n  if (!isEmpty(jsonData.authentication.emailField)) {\n    emailField = jsonData.authentication.emailField;\n  }\n  if (!isEmpty(jsonData.authentication.mobileField)) {\n    mobileField = jsonData.authentication.mobileField;\n  }\n\n  const loginPlatform = [];\n  Object.keys(loginAccessPlatform).forEach((e) => {\n    loginAccessPlatform[e].forEach((l) => {\n      if (!loginPlatform.includes(l)) {\n        loginPlatform.push(l);\n      }\n    });\n  });\n\n  return {\n    isAuth,\n    userRoles,\n    loginAccessPlatform,\n    userModel,\n    userLoginWith,\n    userLoginRateLimit,\n    userLoginRetryLimit,\n    forgotPassword,\n    socialAuth,\n    userTokenExpireTime,\n    noOfDeviceAllowed,\n    registerAuth,\n    emailField,\n    mobileField,\n    loginPlatform,\n  };\n}\n\nasync function makeAuthIndex (authObject) {\n  const { platforms } = authObject;\n  const authSetup = {};\n  forEach(platforms, async (platformName) => {\n    const authControllerIndex = writeOperations.loadTemplate(`${authObject.controllerPath}/authControllerIndex.js`);\n    authControllerIndex.locals.MODEL = authObject.auth.userModel;\n    authControllerIndex.locals.ROLE_PERMISSION = authObject.rolePermission;\n    if (!isEmpty(authObject.auth.registerAuth)) {\n      if (!isEmpty(authObject.auth.registerAuth.smsTemplate)) {\n        authControllerIndex.locals.REGISTER_NOTIFICATION_TYPE = 'SMS';\n      } else if (!isEmpty(authObject.auth.registerAuth.emailTemplate)) {\n        authControllerIndex.locals.REGISTER_NOTIFICATION_TYPE = 'EMAIL';\n      } else {\n        authControllerIndex.locals.REGISTER_NOTIFICATION_TYPE = false;\n      }\n    } else {\n      authControllerIndex.locals.REGISTER_NOTIFICATION_TYPE = false;\n    }\n    authSetup[platformName] = authControllerIndex;\n  });\n  return authSetup;\n}\n\nasync function makeMiddlewareIndex (middlewareObj) {\n  const {\n    platforms, projectType, middlewarePath, userModel,\n  } = middlewareObj;\n  /*\n   * console.log(projectType, middlewareObj.userModel); process.exit(1);\n   * middleware index.js\n   */\n  let indexOfMiddleware;\n  if (projectType === PROJECT_TYPE.CLEAN_CODE || projectType === PROJECT_TYPE.CC_SEQUELIZE) {\n    indexOfMiddleware = writeOperations.loadTemplate(`${middlewarePath}/index.js`);\n    indexOfMiddleware.locals.PLATFORMS = platforms;\n    indexOfMiddleware.locals.USER_MODEL = userModel;\n  }\n  return indexOfMiddleware;\n}\n\nmodule.exports = {\n  makeAuth,\n  isAuthenticationFromInput,\n  makeAuthIndex,\n  makeMiddlewareIndex,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createCommonRoutes/index.js",
    "content": "/* global MODE_0666 */\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\n\nasync function createCommonRoutes (dir, templateFolder, platforms, toPath) {\n  const commonIndex = writeOperations.loadTemplate(`${templateFolder}/commonIndexRoutes.js`);\n  commonIndex.locals.PLATFORM = platforms;\n  writeOperations.write(path.join(dir, `${toPath}/common/index.js`), commonIndex.render(), MODE_0666);\n}\n\nmodule.exports = { createCommonRoutes };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createController/index.js",
    "content": "/* eslint-disable linebreak-style */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-restricted-syntax */\nconst {\n  isEmpty, cloneDeep, forEach, groupBy, uniq,\n} = require('lodash');\nconst writeOperations = require('../../writeOperations');\nconst commonService = require('../utils/common');\nconst {\n  APIS, ORM_PROVIDERS,\n} = require('../../constants/constant');\nconst { getSQLRelationshipDependencies } = require('../getDeleteDependency');\n\nasync function getFieldSelection (model, platform, fieldSelectionObj) {\n  let fieldSelection = false;\n  if (!isEmpty(fieldSelectionObj) && !isEmpty(fieldSelectionObj[platform]) && !isEmpty(fieldSelectionObj[platform][model])) {\n    forEach(fieldSelectionObj[platform][model], (value, key) => {\n      if (APIS.includes(key) && value.selected) {\n        fieldSelection = fieldSelectionObj[platform][model];\n      }\n    });\n  }\n  return fieldSelection;\n}\nasync function getNotification (model, modelNotifications) {\n  let notificationObj = false;\n  if (!isEmpty(modelNotifications) && !isEmpty(modelNotifications[model])) {\n    forEach(modelNotifications[model], (value, key) => {\n      if (APIS.includes(key) && value.selected) {\n        notificationObj = modelNotifications[model];\n      }\n    });\n  }\n  return notificationObj;\n}\n\nasync function individualNotification (notificationObj) {\n  const notification = {};\n  let email = []; let sms = []; let webNotification = [];\n  forEach(notificationObj, (val) => {\n    email.push(val.post ? val.post.email === true : val.pre.email === true);\n    sms.push(val.post ? val.post.sms === true : val.pre.sms === true);\n    webNotification.push(val.post ? val.post.webNotification === true : val.pre.webNotification === true);\n  });\n  email = email.filter((e) => e === true);\n  sms = sms.filter((e) => e === true);\n  webNotification = webNotification.filter((e) => e === true);\n  if (email.length) Object.assign(notification, { email: true });\n  if (sms.length) Object.assign(notification, { sms: true });\n  if (webNotification.length) Object.assign(notification, { webNotification: true });\n  return notification;\n}\n\nasync function getDeleteDependentModel (model, deleteDependency) {\n  let deleteModels = [];\n  // eslint-disable-next-line no-restricted-syntax\n  for (const k in deleteDependency) {\n    if (k === model) {\n      deleteModels = deleteDependency[k];\n      break;\n    } else {\n      deleteModels = [];\n    }\n  }\n  return deleteModels;\n}\n\nconst getRandomInt = (max) => Math.floor(Math.random() * max);\n\nconst transformRouteWithQueryBuilder = async (routes) => {\n  forEach(routes, async (route) => {\n    if (route.method === 'customQuery') {\n      if (Object.prototype.hasOwnProperty.call(route, 'select')) {\n        route.select = (route.select).join(' ');\n      }\n      if (!route.outputVariable || route.outputVariable === '') {\n        route.outputVariable = `outputVar_${getRandomInt(100000)}`;\n      }\n      route.queryVarName = `query_${getRandomInt(100000)}`;\n      if (Object.prototype.hasOwnProperty.call(route, 'populate')) {\n        route.populate = commonService.transformSelect(route.populate);\n      }\n    }\n  });\n  return { routes };\n};\n\nasync function findAndTransformQueryBuilderInNestedCall (nestedCall) {\n  forEach(nestedCall, async (nestedCallArray, preAndPost) => {\n    const temp = await transformRouteWithQueryBuilder(nestedCallArray);\n    nestedCall[preAndPost] = temp.routes;\n  });\n  return nestedCall;\n}\n\nasync function generateController (apis, platformName, controllers, ormProvider, models) {\n  const returnController = {};\n  const packageDependencies = { dependencies: {} };\n  const customRoutes = (controllers?.jsonData?.routes?.apis?.length) ? controllers.jsonData.routes.apis : [];\n  const customRoutesOfPlatform = groupBy(customRoutes, 'platform')[platformName];\n\n  for (const [model, element] of Object.entries(apis)) {\n    if (!isEmpty(element)) {\n      const isFieldSelection = await getFieldSelection(model, platformName, controllers.jsonData.fieldSelection);\n      const deleteDependency = await getDeleteDependentModel(model, controllers.deleteDependency);\n      const controllerName = model;\n      const customRoutesOfModel = groupBy(customRoutesOfPlatform, 'controller')[controllerName];\n      const api = writeOperations.loadTemplate(`${controllers.controllerFilePath}/controller.js`);\n      api.locals.path = controllers.controllerGeneratedPath;\n      if (controllers.auth.isAuth && controllers.auth.userModel === model) {\n        api.locals.USER_MODEL = true;\n      }\n      api.locals.VIRTUAL = controllers.jsonData.virtualRelationship?.[model];\n      api.locals.SUPPORT_API = [];\n      if (controllers.auth.isAuth && controllers.auth.userModel === model) {\n        api.locals.IS_AUTH = true;\n      } else {\n        api.locals.IS_AUTH = false;\n      }\n      api.locals.DB_MODEL = model;\n      api.locals.DB_MODEL_FC = model.charAt(0).toUpperCase() + model.slice(1);\n      api.locals.DELETE_DEPENDENT_MODEL = deleteDependency.length ? deleteDependency : false;\n\n      for (const [key, value] of Object.entries(element)) {\n        if (APIS.includes(key) && value.selected) {\n          const apiObject = {\n            method: key,\n            isAuth: value.isAuth,\n\n          };\n          let associatedSqlModels = {};\n          if (key === 'findAll' && ormProvider === ORM_PROVIDERS.SEQUELIZE) {\n            // ? find sql relationships\n            associatedSqlModels = getSQLRelationshipDependencies(models);\n          }\n          let associatedModelsArray = [];\n          if (Object.keys(associatedSqlModels).length > 0) {\n            Object.keys(associatedSqlModels).forEach((m) => {\n              associatedModelsArray.push(m);\n            });\n          }\n\n          if (associatedModelsArray.length > 0) {\n            associatedModelsArray = associatedModelsArray.filter((d) => d !== model);\n            api.locals.ASSOCIATED_MODELS = associatedModelsArray;\n          }\n\n          // ? for field selection\n          if (isFieldSelection && Object.keys(isFieldSelection).includes(key)) {\n            Object.assign(apiObject, {\n              fieldSelection: true,\n              fields: isFieldSelection[key].fields,\n            });\n          } else {\n            Object.assign(apiObject, { fieldSelection: false });\n          }\n\n          // ? filter By LoggedInUser\n          Object.assign(apiObject, {\n            isLogin: value.isAuth && controllers.auth.isAuth,\n            addedBy: 'addedBy',\n            updatedBy: 'updatedBy',\n            login: controllers.auth.userModel,\n          });\n\n          // ? nested calls for particular API\n          if (controllers.jsonData.nestedCall && controllers.jsonData.nestedCall[platformName] && (controllers.jsonData.nestedCall[platformName][model])) {\n            if ((controllers.jsonData.nestedCall[platformName])[model][key]) {\n              const nestedCallOfMethod = await findAndTransformQueryBuilderInNestedCall(cloneDeep(controllers.jsonData.nestedCall[platformName])[model][key]);\n              Object.assign(apiObject, {\n                IS_NESTED_CALL: true,\n                NESTED_CALLS: nestedCallOfMethod,\n              });\n            } else {\n              Object.assign(apiObject, { IS_NESTED_CALL: false });\n            }\n          } else {\n            Object.assign(apiObject, { IS_NESTED_CALL: false });\n          }\n\n          // ? add variable to EJS\n          api.locals.SUPPORT_API.push(apiObject);\n        }\n      }\n\n      // ? custom route\n      let uniqueTaskModels = [];\n      let uniqueRequireValidationModels = [];\n      api.locals.MODULE = platformName;\n\n      // ? if Controller of any route is same as model name then it will add method in same controller\n      if (customRoutesOfModel) {\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode(customRoutesOfModel, 'queryBuilder');\n        const transformedControllerDetail = commonService.transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        api.locals.CUSTOM_ROUTES = transformedControllerDetail.routes;\n        const servicesToImport = (transformedControllerDetail.routes).map(((obj) => obj.service));\n        api.locals.SERVICES_TO_IMPORT = uniq(servicesToImport);\n        [uniqueTaskModels, uniqueRequireValidationModels] = commonService.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n        [api.locals.UNIQ_TASK_MODELS, api.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [uniqueTaskModels, uniqueRequireValidationModels];\n        api.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n      } else {\n        api.locals.CUSTOM_ROUTES = null;\n        api.locals.IS_CQ = false;\n        api.locals.UNIQ_TASK_MODELS = undefined;\n        api.locals.UNIQ_REQUIRE_VALIDATION_MODELS = undefined;\n        api.locals.SERVICES_TO_IMPORT = undefined;\n      }\n      let modelsToImport = [];\n      // ? for finding models which need to be imported in controller\n      const uniqModels = [];\n      if (uniqModels && uniqModels.length) {\n        modelsToImport = modelsToImport.concat(uniqModels);\n      }\n      if (uniqueTaskModels && uniqueTaskModels.length) {\n        modelsToImport = modelsToImport.concat(uniqueTaskModels);\n      }\n      modelsToImport = uniq(modelsToImport.filter(Boolean));\n      api.locals.UNIQ_TASK_MODELS = modelsToImport;\n      returnController[model] = api;\n    } else {\n      const controllerName = model;\n      const customRoutesOfModel = groupBy(customRoutesOfPlatform, 'controller')[controllerName];\n      if (customRoutesOfModel) {\n        const api = writeOperations.loadTemplate(`${controllers.controllerFilePath}/controller.js`);\n        api.locals.path = controllers.controllerGeneratedPath;\n        api.locals.DB_MODEL = model;\n        api.locals.DB_MODEL_FC = model.charAt(0).toUpperCase() + model.slice(1);\n        api.locals.SUPPORT_API = [];\n        api.locals.DELETE_DEPENDENT_MODEL = false;\n        api.locals.MODULE = platformName;\n        if (controllers.auth.isAuth && controllers.auth.userModel === model) {\n          api.locals.IS_AUTH = true;\n        } else {\n          api.locals.IS_AUTH = false;\n        }\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode(customRoutesOfModel, 'queryBuilder');\n        const transformedControllerDetail = commonService.transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        api.locals.CUSTOM_ROUTES = transformedControllerDetail.routes;\n        const servicesToImport = (transformedControllerDetail.routes).map(((obj) => obj.service));\n        api.locals.SERVICES_TO_IMPORT = uniq(servicesToImport);\n        const [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS] = commonService.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n        [api.locals.UNIQ_TASK_MODELS, api.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS];\n        api.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n        returnController[model] = api;\n      }\n    }\n  }\n\n  return {\n    returnController,\n    packageDependencies,\n  };\n}\nasync function generateControllerIndex (platform, platformName, controllers) {\n  const controllerIndexFiles = [];\n  const customRoutes = (controllers.jsonData.routes?.apis && controllers.jsonData.routes?.apis.length) ? controllers.jsonData.routes?.apis : [];\n  const customRoutesOfPlatform = groupBy(customRoutes, 'platform')[platformName];\n\n  for (const [model, element] of Object.entries(platform)) {\n    if (!isEmpty(element)) {\n      const controllerName = model;\n      const customRoutesOfModel = groupBy(customRoutesOfPlatform, 'controller')[controllerName];\n      const platformIndexController = writeOperations.loadTemplate(`${controllers.controllerFilePath}/controllerIndex.js`);\n      platformIndexController.locals.DB_MODEL = model;\n      platformIndexController.locals.DB_MODEL_FC = model.charAt(0).toUpperCase() + model.slice(1);\n      platformIndexController.locals.NOTIFICATION = false;\n      platformIndexController.locals.EMAIL = false;\n      platformIndexController.locals.SMS = false;\n      platformIndexController.locals.WEB = false;\n      platformIndexController.locals.IS_AUTH = false;\n      platformIndexController.locals.CONTROLLER_METHODS = element;\n      platformIndexController.locals.USER_MODEL = controllers.auth.isAuth && controllers.auth.userModel === model;\n      if (controllers.auth.isAuth && controllers.auth.userModel === model) {\n        platformIndexController.locals.IS_AUTH = controllers.auth.isAuth;\n      }\n\n      const deleteDependency = await getDeleteDependentModel(model, controllers.deleteDependency);\n      platformIndexController.locals.DELETE_DEPENDENT_MODEL = deleteDependency.length ? deleteDependency : false;\n\n      let dbDependencyInjection = [model];\n      if (deleteDependency.length) {\n        if (!isEmpty(deleteDependency)) {\n          forEach(deleteDependency, (value) => {\n            dbDependencyInjection.push(value.model);\n          });\n        }\n        dbDependencyInjection = uniq(dbDependencyInjection);\n      }\n      platformIndexController.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n\n      const notificationObj = await getNotification(model, controllers.jsonData.modelNotifications);\n      if (notificationObj) {\n        platformIndexController.locals.NOTIFICATION = true;\n        const {\n          email, sms, webNotification,\n        } = await individualNotification(notificationObj);\n        platformIndexController.locals.EMAIL = email;\n        platformIndexController.locals.SMS = sms;\n        platformIndexController.locals.WEB = webNotification;\n      }\n      // ? for finding models which need to be imported in controller\n      const uniqModels = [];\n      let uniqueTaskModels = [];\n      let uniqueRequireValidationModels = [];\n      if (customRoutesOfModel) {\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode(customRoutesOfModel, 'queryBuilder');\n        const transformedControllerDetail = commonService.transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        platformIndexController.locals.CUSTOM_ROUTES = transformedControllerDetail.routes;\n        platformIndexController.locals.PLATFORM = platformName;\n        const servicesToImport = (transformedControllerDetail.routes).map(((obj) => obj.service));\n        platformIndexController.locals.SERVICES_TO_IMPORT = uniq(servicesToImport);\n        [uniqueTaskModels, uniqueRequireValidationModels] = commonService.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n        [platformIndexController.locals.UNIQ_TASK_MODELS, platformIndexController.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [uniqueTaskModels, uniqueRequireValidationModels];\n        platformIndexController.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n      } else {\n        platformIndexController.locals.CUSTOM_ROUTES = null;\n        platformIndexController.locals.PLATFORM = platformName;\n        platformIndexController.locals.IS_CQ = false;\n        platformIndexController.locals.UNIQ_TASK_MODELS = undefined;\n        platformIndexController.locals.UNIQ_REQUIRE_VALIDATION_MODELS = undefined;\n        platformIndexController.locals.SERVICES_TO_IMPORT = undefined;\n      }\n      let modelsToImport = [];\n      if (uniqModels && uniqModels.length) {\n        modelsToImport = modelsToImport.concat(uniqModels);\n      }\n      if (uniqueTaskModels && uniqueTaskModels.length) {\n        modelsToImport = modelsToImport.concat(uniqueTaskModels);\n      }\n      modelsToImport = uniq(modelsToImport.filter(Boolean));\n      platformIndexController.locals.UNIQ_TASK_MODELS = modelsToImport;\n\n      controllerIndexFiles.push({ [model]: platformIndexController });\n    }\n  }\n  return controllerIndexFiles;\n}\nasync function makeControllerIndex (controllers) {\n  const platform = controllers.jsonData.modelConfig;\n  // const platform = cloneDeep(controllers.jsonData.authentication.platform);\n  const controllerIndex = {};\n  if (!isEmpty(platform)) {\n    for (const [module, element] of Object.entries(platform)) {\n      /*\n       * * module = admin , device , desktop , client\n       * * element = {user:{\"create:{\"selected\":true,\"policy\":[],\"isAuth\":true}\"}}\n       */\n      if (!isEmpty(element)) {\n        const controller = await generateControllerIndex(element, module, controllers);\n        controllerIndex[module] = controller;\n      }\n    }\n  }\n  return controllerIndex;\n}\n\nasync function makeController (controllers) {\n  const platform = controllers.jsonData.modelConfig;\n  const platformWiseController = {};\n  const packageDependencies = {};\n  const ormProvider = controllers.jsonData.ORM;\n  const { jsonModels } = controllers;\n  if (!isEmpty(platform)) {\n    for (const [module, element] of Object.entries(platform)) {\n      /*\n       * * module = admin , device , desktop , client\n       * * element = {user:{\"create:{\"selected\":true,\"policy\":[],\"isAuth\":true}\"}}\n       */\n      if (!isEmpty(element)) {\n        const modelController = await generateController(element, module, controllers, ormProvider, jsonModels);\n        platformWiseController[module] = modelController.returnController;\n        if (!isEmpty(modelController.packageDependencies.dependencies) && packageDependencies !== modelController.packageDependencies) {\n          Object.assign(packageDependencies, modelController.packageDependencies);\n        }\n      }\n    }\n  }\n  return {\n    platformWiseController,\n    packageDependencies,\n  };\n}\n\nmodule.exports = {\n  makeController,\n  makeControllerIndex,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createCustomRoutes/index.js",
    "content": "/* global  _ */\nconst {\n  forEach, isEmpty, has,\n} = require('lodash');\nconst replace = require('key-value-replace');\nconst writeOperations = require('../../writeOperations');\nconst common = require('../utils/common');\n\nconst getRandomInt = (max) => Math.floor(Math.random() * max);\n\nconst transformControllerDetailsWithQueryBuilder = (routes) => {\n  let isQueryBuilderAvailable = false;\n  // eslint-disable-next-line no-restricted-syntax\n  for (const route of routes) {\n    if (Object.prototype.hasOwnProperty.call(route, 'queryBuilder')) {\n      if (route.queryBuilder.length) {\n        isQueryBuilderAvailable = true;\n        const modelGroup = [...new Set(route.queryBuilder.map((item) => item.model))];\n        route.cq_model = modelGroup.filter(Boolean);\n        // eslint-disable-next-line no-restricted-syntax\n        for (const qb of route.queryBuilder) {\n          if (qb.queryMode === 'find') {\n            if (Object.prototype.hasOwnProperty.call(qb, 'select')) {\n              qb.select = (qb.select).join(' ');\n            }\n            if (Object.prototype.hasOwnProperty.call(qb, 'populate')) {\n              qb.populate = common.transformSelect(qb.populate);\n            }\n          }\n          if (!qb.outputVariable || qb.outputVariable === '') {\n            qb.outputVariable = `outputVar_${getRandomInt(10000)}`;\n          }\n          qb.queryVarName = `query_${getRandomInt(10000)}`;\n        }\n      }\n    }\n  }\n  return {\n    routes,\n    isQueryBuilderAvailable,\n  };\n};\n\nfunction doesConContainsPath (con, path) {\n  const conPaths = Object.values(con);\n  if (conPaths.includes(path)) return true;\n  return false;\n}\n\nconst makeCustomRoutes = async (makeCustomRouteObj) => {\n  let shouldCopyQueryService = false;\n  const packageDependencies = { dependencies: {} };\n  // const PLATFORM = Object.keys(makeCustomRouteObj.platform);\n  const PLATFORM = makeCustomRouteObj.platform;\n  const {\n    customRoutesPath, modelFolderPath, validationFolderPath,\n  } = makeCustomRouteObj;\n  const {\n    routes, newModelConfig,\n  } = makeCustomRouteObj;\n  const finalCustomRoutes = {\n    new: {},\n    old: {},\n  };\n  const { models } = makeCustomRouteObj;\n  const modelKey = Object.keys(models);\n  const inputModel = Object.keys(models);\n\n  // separate routes\n  let routesWithModelAndPlatform = routes.apis.filter((route) => {\n    if (!_.isEmpty(route.platform) && _.isEmpty(route.controllerFilePath) && _.isEmpty(route.routeFilePath)) {\n      return true;\n    }\n    return false;\n  });\n\n  let routesWithCustomFilePath = routes.apis.filter((route) => {\n    if (!_.isEmpty(route.controllerFilePath) && !_.isEmpty(route.routeFilePath) && !_.isEmpty(route.platform)) {\n      return true;\n    }\n    return false;\n  });\n  routesWithCustomFilePath = routesWithCustomFilePath.filter(Boolean);\n\n  routesWithModelAndPlatform = routesWithModelAndPlatform.filter(Boolean);\n  routesWithModelAndPlatform = routesWithModelAndPlatform.filter((route) => {\n    const modelConfigOfPlatform = newModelConfig[route.platform];\n    const isModelConfigAvailable = has(modelConfigOfPlatform, route.model);\n    if (!PLATFORM.includes(route.platform) || !modelKey.includes(route.controller) || !isModelConfigAvailable) {\n      return true;\n    }\n    return false;\n  });\n\n  /*\n   * const routesWithoutModel = routes.apis.filter((route) => {\n   *   if (_.isEmpty(route.model)) {\n   *     return true;\n   *   }\n   *   return false;\n   * });\n   * come here\n   */\n\n  /*\n   * routes.apis = routes.apis.filter(Boolean);\n   * api.route->map(\"controller\")\n   */\n  const NEW_PLATFORM = [];\n  if (!_.isEmpty(routesWithModelAndPlatform)) {\n    const folderWise = _.groupBy(routesWithModelAndPlatform, 'platform');\n\n    finalCustomRoutes.new.controllerNServiceNRoutes = {};\n    finalCustomRoutes.new.routeIndex = {};\n    finalCustomRoutes.old.controllerNServiceNRoutes = {};\n    finalCustomRoutes.old.routeIndex = {};\n    _.map(folderWise, (platformDetails, platform) => {\n      if (!PLATFORM.includes(platform)) {\n        finalCustomRoutes.new.controllerNServiceNRoutes[platform] = {};\n        if (!NEW_PLATFORM.includes(platform)) {\n          NEW_PLATFORM.push(platform);\n        }\n        const controllerGroup = _.groupBy(platformDetails, 'controller');\n        const controllerPerPlatform = [];\n        _.map(controllerGroup, (controllerDetails, controllerName) => {\n          if (!controllerPerPlatform.includes(controllerName)) {\n            controllerPerPlatform.push(controllerName);\n          }\n          const controller = writeOperations.loadTemplate(`${customRoutesPath}/controller.js`);\n          const service = writeOperations.loadTemplate(`${customRoutesPath}/service.js`);\n          const routesWithQueryMode = common.removeQueryBuilderWithoutQueryMode(controllerDetails, 'queryBuilder');\n          const transformedControllerDetail = transformControllerDetailsWithQueryBuilder(_.cloneDeep(routesWithQueryMode));\n          controller.locals.ROUTES = transformedControllerDetail.routes;\n          const [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS] = common.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n          [controller.locals.UNIQ_TASK_MODELS, controller.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS];\n          controller.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n          controller.locals.platform = platform;\n          controller.locals.path = makeCustomRouteObj.generatedCustomRouteControllerPath;\n          if (transformedControllerDetail.isQueryBuilderAvailable) shouldCopyQueryService = true;\n          controller.locals.SERVICES = _.uniqBy(transformedControllerDetail.routes, 'service');\n          controller.locals.SERVICE_NAME_FC = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\n          service.locals.ROUTES = transformedControllerDetail.routes;\n          finalCustomRoutes.new.controllerNServiceNRoutes[platform] = {};\n          finalCustomRoutes.new.controllerNServiceNRoutes[platform][controllerName] = {\n            controller,\n            service,\n          };\n          const routeWithoutModel = controllerDetails.filter((cr) => {\n            if (!_.isEmpty(cr.model)) {\n              if (!inputModel.includes(cr.model)) {\n                return true;\n              }\n              return false;\n            }\n            return false;\n          });\n\n          if (!_.isEmpty(routeWithoutModel)) {\n            const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n            route.locals.POLICIES = common.getPolicyForCustomRoutes(routeWithoutModel);\n            route.locals.PLATFORM = platform;\n            route.locals.ROUTES = transformedControllerDetail.routes;\n            route.locals.IMPORT = transformedControllerDetail.routes;\n            route.locals.SERVICE_NAME = controllerName;\n            finalCustomRoutes.new.controllerNServiceNRoutes[platform][controllerName] = {\n              ...finalCustomRoutes.new.controllerNServiceNRoutes[platform][controllerName],\n              route,\n            };\n          }\n        });\n\n        const indexRoute = writeOperations.loadTemplate(`${customRoutesPath}/platformIndexRoutes.js`);\n        indexRoute.locals.CONTROLLERS = controllerPerPlatform;\n        indexRoute.locals.PLATFORM = platform.toLowerCase();\n        finalCustomRoutes.new.routeIndex[platform] = { indexRoute };\n      } else {\n        finalCustomRoutes.old.controllerNServiceNRoutes[platform] = {};\n        const controllerGroup = _.groupBy(platformDetails, 'controller');\n        const controllerPerPlatform = [];\n        _.map(controllerGroup, (controllerDetails, controllerName) => {\n          if (!controllerPerPlatform.includes(controllerName)) {\n            controllerPerPlatform.push(controllerName);\n          }\n          const controller = writeOperations.loadTemplate(`${customRoutesPath}/controller.js`);\n          const service = writeOperations.loadTemplate(`${customRoutesPath}/service.js`);\n          // const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n          const routesWithQueryMode = common.removeQueryBuilderWithoutQueryMode(controllerDetails, 'queryBuilder');\n          const transformedControllerDetail = transformControllerDetailsWithQueryBuilder(_.cloneDeep(routesWithQueryMode));\n          controller.locals.ROUTES = transformedControllerDetail.routes;\n          const [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS] = common.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n          [controller.locals.UNIQ_TASK_MODELS, controller.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS];\n          controller.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n          controller.locals.platform = platform;\n          controller.locals.path = makeCustomRouteObj.generatedCustomRouteControllerPath;\n          if (transformedControllerDetail.isQueryBuilderAvailable) shouldCopyQueryService = true;\n          controller.locals.SERVICES = _.uniqBy(transformedControllerDetail.routes, 'service');\n          controller.locals.SERVICE_NAME_FC = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\n          service.locals.ROUTES = transformedControllerDetail.routes;\n          if (isEmpty(finalCustomRoutes.old.controllerNServiceNRoutes[platform])) {\n            finalCustomRoutes.old.controllerNServiceNRoutes[platform] = {};\n          }\n          // finalCustomRoutes.new.controllerNServiceNRoutes[platform] = {};\n          Object.assign(finalCustomRoutes.old.controllerNServiceNRoutes[platform], {\n            [controllerName]: {\n              controller,\n              service,\n            },\n          });\n          // finalCustomRoutes.new.controllerNServiceNRoutes[platform][controllerName] = { controller, service };\n          const routeWithoutModel = controllerDetails.filter((cr) => {\n            if (!_.isEmpty(cr.model)) {\n              if (!inputModel.includes(cr.model)) {\n                return true;\n              }\n              return false;\n            }\n            return true;\n          });\n          if (!_.isEmpty(routeWithoutModel)) {\n            const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n            route.locals.POLICIES = common.getPolicyForCustomRoutes(routeWithoutModel);\n            route.locals.PLATFORM = platform;\n            route.locals.ROUTES = transformedControllerDetail.routes;\n            route.locals.IMPORT = transformedControllerDetail.routes;\n            route.locals.SERVICE_NAME = controllerName;\n            finalCustomRoutes.old.controllerNServiceNRoutes[platform][controllerName] = {\n              ...finalCustomRoutes.old.controllerNServiceNRoutes[platform][controllerName],\n              route,\n            };\n          }\n        });\n\n        finalCustomRoutes.old.routeIndex[platform] = { platformExistIndexRoutes: _.uniqBy(platformDetails, 'controller') };\n      }\n    });\n  }\n\n  // handling custom routes having custom file path\n  const customRoutesWithPath = {};\n  if (!_.isEmpty(routesWithCustomFilePath)) {\n    // controller\n    const controllers = {};\n    const groupByControllerPath = _.groupBy(routesWithCustomFilePath, 'controllerFilePath');\n    forEach(groupByControllerPath, (routes2, controllerFilePath) => {\n      const groupByControllerFile = _.groupBy(routes2, 'controllerFileName');\n      let controllerFiles = [];\n      forEach(groupByControllerFile, (route3, controllerFile) => {\n        const controller = writeOperations.loadTemplate(`${customRoutesPath}/controller.js`);\n        const routesWithQueryMode = common.removeQueryBuilderWithoutQueryMode(route3, 'queryBuilder');\n        const transformedControllerDetail = transformControllerDetailsWithQueryBuilder(_.cloneDeep(routesWithQueryMode));\n        controller.locals.ROUTES = transformedControllerDetail.routes;\n        const [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS] = common.getUniqModelsFromTasks(transformedControllerDetail.routes, 'queryBuilder');\n        const MODEL_PATHS = common.getRelativePaths(UNIQ_TASK_MODELS, `${modelFolderPath}`, `${controllerFilePath}/${controllerFile}.js`, makeCustomRouteObj.destinationFolder);\n        const VALIDATION_PATHS = common.getRelativePaths(UNIQ_REQUIRE_VALIDATION_MODELS, `${validationFolderPath}`, `${controllerFilePath}/${controllerFile}.js`, makeCustomRouteObj.destinationFolder);\n        controller.locals.MODEL_PATHS = MODEL_PATHS;\n        controller.locals.VALIDATION_PATH = VALIDATION_PATHS;\n        controller.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n        controller.locals.path = controllerFilePath;\n        controller.locals.name = controllerFile;\n        if (transformedControllerDetail.isQueryBuilderAvailable) shouldCopyQueryService = true;\n        controllerFiles.push(controller);\n      });\n      Object.assign(controllers, { [controllerFilePath]: controllerFiles });\n      controllerFiles = [];\n    });\n    customRoutesWithPath.controllers = controllers;\n\n    // routes\n    const routesC = {};\n    const customRoutesInIndex = [];\n    const groupByRoutePath = _.groupBy(routesWithCustomFilePath, 'routeFilePath');\n    forEach(groupByRoutePath, (r, routeFilePath) => {\n      // const routePath = `${routeFilePath}`;\n      const groupByRouteFileName = _.groupBy(r, 'routeFileName');\n      const routeFileNames = [...new Set(Object.keys(groupByRouteFileName))];\n      for (let i = 0; i < routeFileNames.length; i += 1) {\n        const p2 = `${routeFilePath}/${routeFileNames[i]}`;\n        const p = common.createRelativePathFromAbsolutePath(`${makeCustomRouteObj.destinationFolder}${makeCustomRouteObj.routeFolderPath}/index.js`, `${makeCustomRouteObj.destinationFolder}${p2}`);\n        customRoutesInIndex.push(p);\n      }\n      let routeFiles = [];\n\n      forEach(groupByRouteFileName, (r2, routeFile) => {\n        const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n        route.locals.POLICIES = common.getPolicyForCustomRoutes(r2);\n        const con = {};\n        // const allImportPaths=[]\n        forEach(r2, (r1) => {\n          const currentFile = `${makeCustomRouteObj.destinationFolder}${r1.controllerFilePath}/${r1.controllerFileName}.js`;\n          const destinationFile = `${makeCustomRouteObj.destinationFolder}${r1.routeFilePath}/${r1.routeFileName}.js`;\n          const path = common.createRelativePathFromAbsolutePath(destinationFile, currentFile);\n          // allImportPaths.push(path)\n          let obj = { [r1.controllerFileName]: path };\n          if (`${r1.controllerFileName}` in con && !doesConContainsPath(con, path)) {\n            // const originalControllerFileName=r1.controllerFileName\n            r1.controllerFileName = `${r1.controllerFileName}${common.getRandomIntByMax(1000)}`;\n            obj = { [r1.controllerFileName]: path };\n          }\n          Object.assign(con, obj);\n        });\n        route.locals.ROUTES = r2;\n        route.locals.CONTROLLER_IMPORTS = con;\n        route.locals.name = routeFile;\n        routeFiles.push(route);\n      });\n      Object.assign(routesC, { [routeFilePath]: routeFiles });\n      routeFiles = [];\n    });\n    customRoutesWithPath.routes = routesC;\n    customRoutesWithPath.mainIndexRoute = customRoutesInIndex;\n  }\n\n  if (NEW_PLATFORM.length) {\n    finalCustomRoutes.new.platform = NEW_PLATFORM;\n  }\n\n  // route index where model was not there\n  const customRouteIndex = routes.apis.filter((route) => route.createNewFile);\n  const customRouteByPlatform = _.groupBy(customRouteIndex, 'platform');\n  return [finalCustomRoutes, shouldCopyQueryService, packageDependencies, customRoutesWithPath, customRouteByPlatform];\n};\n\nconst makeControllerIndexForCustomRoutes = (makeCustomRouteObj, userDirectoryStructure) => {\n  const PLATFORM = makeCustomRouteObj.platform;\n  const { customRoutesPath } = makeCustomRouteObj;\n  const { routes } = makeCustomRouteObj;\n  const { models } = makeCustomRouteObj;\n  const modelKey = Object.keys(models);\n  routes.apis = routes.apis.map((route) => {\n    if (!PLATFORM.includes(route.platform) || !modelKey.includes(route.controller)) {\n      return route;\n    }\n    return undefined;\n  });\n  routes.apis = routes.apis.filter(Boolean);\n  const folderWise = _.groupBy(routes.apis, 'platform');\n  const controllerIndexes = [];\n  let controllerPath = '';\n  _.map(folderWise, (platformDetails, platform) => {\n    const controllerGroup = _.groupBy(platformDetails, 'controller');\n    _.map(controllerGroup, (controllerDetails, controllerName) => {\n      const controllerIndex = writeOperations.loadTemplate(`${customRoutesPath}/controllerIndex.js`);\n      const routesWithQueryMode = common.removeQueryBuilderWithoutQueryMode(controllerDetails, 'queryBuilder');\n      const transformedControllerDetail = common.transformControllerDetailsWithQueryBuilder(_.cloneDeep(routesWithQueryMode));\n      const [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS] = common.getUniqModelsFromTasks(_.cloneDeep(transformedControllerDetail.routes), 'queryBuilder');\n      [controllerIndex.locals.UNIQ_TASK_MODELS, controllerIndex.locals.UNIQ_REQUIRE_VALIDATION_MODELS] = [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS];\n      controllerIndex.locals.SERVICE_NAME = controllerName;\n      controllerIndex.locals.SERVICE_NAME_FC = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\n      controllerIndex.locals.PLATFORM = platform;\n      controllerIndex.locals.CONTROLLER = controllerName;\n      controllerIndex.locals.IS_CQ = transformedControllerDetail.isQueryBuilderAvailable;\n      controllerIndex.locals.ROUTES = transformedControllerDetail.routes;\n      controllerPath = userDirectoryStructure.generatedCustomRouteControllerPath;\n      controllerPath = replace(controllerPath, {\n        platform,\n        controller: controllerName,\n      });\n      const controllerFolderPath = controllerPath.substring(0, controllerPath.lastIndexOf('/'));\n      const controllerIndexFilePath = `${controllerFolderPath}/index.js`;\n      controllerIndex.locals.indexPath = controllerIndexFilePath;\n      controllerIndex.locals.controllerFolder = controllerFolderPath;\n\n      controllerIndex.locals.DATA_ACCESS_PATH = common.getImportPath(controllerFolderPath, userDirectoryStructure.dataAccessFolderPath);\n      controllerIndex.locals.VALIDATION_PATH = common.getImportPath(controllerFolderPath, userDirectoryStructure.validationFolderPath);\n      controllerIndex.locals.USECASE_PATH = common.getImportPath(controllerFolderPath, userDirectoryStructure.useCaseFolderPath);\n      controllerIndexes.push(controllerIndex);\n    });\n  });\n  return controllerIndexes;\n};\n\nconst makeServiceForNonExistingService = async (makeCustomRouteObj) => {\n  const { customRoutesPath } = makeCustomRouteObj;\n  const { routes } = makeCustomRouteObj;\n  const { models } = makeCustomRouteObj;\n  const modelKey = Object.keys(models);\n  routes.apis = routes.apis.map((route) => {\n    if (modelKey.includes(route.controller)) {\n      return route;\n    }\n    return undefined;\n  });\n  routes.apis = routes.apis.filter(Boolean);\n  const folderWise = _.groupBy(routes.apis, 'platform');\n  const services = [];\n  _.map(folderWise, (platformDetails, platform) => {\n    const controllerGroup = _.groupBy(platformDetails, 'controller');\n    _.map(controllerGroup, (controllerDetails, controllerName) => {\n      const service = writeOperations.loadTemplate(`${customRoutesPath}/service.js`);\n      const routesWithQueryMode = common.removeQueryBuilderWithoutQueryMode(controllerDetails, 'queryBuilder');\n      service.locals.ROUTES = routesWithQueryMode;\n      service.locals.SERVICE_NAME = controllerName;\n      service.locals.SERVICE_NAME_FC = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\n      service.locals.PLATFORM = platform;\n      service.locals.CONTROLLER = controllerName;\n      services.push(service);\n    });\n  });\n  return services;\n};\n\nconst makeCustomRoutesUsecase = async (customRouteObj) => {\n  const {\n    customRoutes, models, userDirectoryStructure, templateRegistry, templateFolderName,\n  } = customRouteObj;\n  let modelNames = [];\n  const useCaseForCustomRoutes = [];\n  if (!_.isEmpty(models)) {\n    modelNames = Object.keys(models);\n  }\n  let useCaseFolderPath = '';\n  let useCaseFilePath = '';\n  let modelName = '';\n  _.forEach(customRoutes, (customRoute) => {\n    if (!_.isEmpty(customRoute.model) && modelNames.includes(customRoute.model)) {\n      modelName = customRoute.model;\n      useCaseFilePath = replace(userDirectoryStructure.useCaseFilePath, {\n        model: customRoute.model,\n        fileName: customRoute.functionName,\n      });\n      useCaseFolderPath = (useCaseFilePath).substring(0, (useCaseFilePath).lastIndexOf('/'));\n    } else {\n      modelName = '';\n      useCaseFilePath = replace(userDirectoryStructure.useCaseFilePath, {\n        model: 'customRoutes',\n        fileName: customRoute.functionName,\n      });\n      useCaseFolderPath = (useCaseFilePath).substring(0, (useCaseFilePath).lastIndexOf('/'));\n    }\n    const useCase = writeOperations.loadTemplate(`${templateFolderName}${templateRegistry.useCaseFolderPath}/customRouteOfModel.js`);\n    useCase.locals.FUNCTION_NAME = customRoute.functionName;\n    useCase.locals.MODEL_NAME = modelName;\n    useCase.locals.path = useCaseFilePath;\n    useCase.locals.folderPath = useCaseFolderPath;\n    const queryBuilderForModel = customRoute.queryBuilder?.length ? customRoute.queryBuilder.filter((q) => q.queryMode === 'find') : [];\n    useCase.locals.MODELS = [...new Set(queryBuilderForModel.map((q) => `${q.model}Db`))];\n    useCase.locals.QUERY = queryBuilderForModel;\n    useCaseForCustomRoutes.push(useCase);\n  });\n  return useCaseForCustomRoutes;\n};\n\nmodule.exports = {\n  makeCustomRoutes,\n  makeControllerIndexForCustomRoutes,\n  makeServiceForNonExistingService,\n  makeCustomRoutesUsecase,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createDataAccessFiles/index.js",
    "content": "const { forEach } = require('lodash');\nconst writeOperations = require('../../writeOperations');\n\nconst createDataAccessFiles = (templatePath, models) => {\n  const allDataAccessFiles = {};\n  forEach(models, (value, key) => {\n    const dbFileTemplate = writeOperations.loadTemplate(`${templatePath}/dbFile.js`);\n    dbFileTemplate.locals.MODEL_NAME_FC = key.charAt(0).toUpperCase() + key.slice(1);\n    dbFileTemplate.locals.MODEL_NAME = key;\n    allDataAccessFiles[key] = dbFileTemplate;\n  });\n  return allDataAccessFiles;\n};\n\nmodule.exports = { createDataAccessFiles };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createDeleteDependencyService.js",
    "content": "const {\n  forEach, isEmpty, uniq,\n} = require('lodash');\nconst writeOperations = require('../writeOperations');\nconst { PROJECT_TYPE } = require('../constants/constant');\n\nconst generateDeleteDependencyService = async (projectType, templateFolderName, deleteDependency) => {\n  const deleteService = [];\n  if (projectType === PROJECT_TYPE.MVC_SEQUELIZE || projectType === PROJECT_TYPE.MVC) {\n    const commonDeleteService = writeOperations.loadTemplate(`${templateFolderName}/deleteDependentService1.js`);\n    commonDeleteService.locals.DELETE_DEPENDENCY = deleteDependency;\n    commonDeleteService.locals.PROJECT_TYPE = projectType;\n    deleteService.push(commonDeleteService);\n    if (!isEmpty(deleteDependency)) { deleteService.push(commonDeleteService); }\n  } else {\n    forEach(deleteDependency, (dependency, modelName) => {\n      const modelDeleteDependency = writeOperations.loadTemplate(`${templateFolderName}/deleteDependentService1.js`);\n      modelDeleteDependency.locals.MODEL_NAME = modelName;\n      modelDeleteDependency.locals.MODEL_FC = (modelName).charAt(0).toUpperCase() + (modelName).slice(1);\n      modelDeleteDependency.locals.DELETE_DEPENDENCY = dependency;\n\n      let dbDependencyInjection = [modelName];\n      if (!isEmpty(dependency)) {\n        forEach(dependency, (value) => {\n          dbDependencyInjection.push(value.model);\n        });\n      }\n      dbDependencyInjection = uniq(dbDependencyInjection);\n      modelDeleteDependency.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n      if (!isEmpty(dependency)) { deleteService.push(modelDeleteDependency); }\n    });\n  }\n  return deleteService;\n};\n\nmodule.exports = { generateDeleteDependencyService };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createEntities.js",
    "content": "const {\n  keys, forEach,\n} = require('lodash');\nconst writeOperations = require('../writeOperations');\n\nasync function createEntities (entityFolderPath, entities) {\n  const allEJSEntities = {};\n  forEach(entities, (value, key) => {\n    const entityTemplate = writeOperations.loadTemplate(`${entityFolderPath}/entity.js`);\n    entityTemplate.locals.ENTITY_NAME_FC = key.charAt(0).toUpperCase() + key.slice(1);\n    entityTemplate.locals.ENTITY_NAME = key;\n    entityTemplate.locals.ENTITY_KEYS = keys(entities[key]);\n    allEJSEntities[key] = entityTemplate;\n  });\n  return allEJSEntities;\n}\n\nmodule.exports = { createEntities };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createFileUploadFiles/index.js",
    "content": "const {\n  forEach, isEmpty, find,\n} = require('lodash');\nconst writeOperations = require('../../writeOperations');\nconst { getImportPath } = require('../utils/common');\n\nasync function makeFileUploadFiles (fileUploadObj) {\n  const { jsonData } = fileUploadObj;\n  const { templateFolder } = fileUploadObj;\n  const { auth } = fileUploadObj;\n  const returnObj = {\n    controllers: [],\n    routes: [],\n    packageDependencies: { dependencies: {} },\n  };\n  const controller = writeOperations.loadTemplate(`${templateFolder}${fileUploadObj.controllerPath}/fileUploadController.js`);\n  forEach(jsonData, (obj) => {\n    const FileUpload = [];\n    if (obj.storage !== undefined && (obj.storage.toLowerCase() === 's3' || obj.storage.toLowerCase() === 's3_private')) {\n      returnObj.packageDependencies.dependencies['aws-sdk'] = '~2.901.0';\n    }\n    if (obj.storage !== undefined && obj.storage.toLowerCase() === 's3_private') {\n      returnObj.packageDependencies.dependencies['amazon-s3-uri'] = '~0.1.1';\n    }\n    // main Route\n    const uploadRoutes = writeOperations.loadTemplate(`${templateFolder}${fileUploadObj.routePath}/uploadRoutes.js`);\n    uploadRoutes.locals.IS_AUTH = obj.authentication && auth.isAuth;\n    uploadRoutes.locals.FILE_UPLOAD = FileUpload;\n    uploadRoutes.locals.PLATFORM = obj.platform;\n    if (obj.platform === 'admin') {\n      uploadRoutes.locals.PLATFORM_PREFIX = `${obj.platform.toLowerCase()}`;\n    } else {\n      uploadRoutes.locals.PLATFORM_PREFIX = `${obj.platform.toLowerCase()}/api/v1`;\n    }\n    uploadRoutes.locals.S3_UPLOAD_PRIVATE = !!(obj.storage !== undefined && obj.storage.toLowerCase() === 's3_private');\n    returnObj.routes.push({\n      platform: obj.platform,\n      mainRoute: uploadRoutes,\n    });\n    controller.locals.S3_UPLOAD = !!(obj.storage !== undefined && (obj.storage.toLowerCase() === 's3' || obj.storage.toLowerCase() === 's3_private'));\n    controller.locals.S3_UPLOAD_PRIVATE = !!(obj.storage !== undefined && obj.storage.toLowerCase() === 's3_private');\n    controller.locals.MAX_SIZE = obj.maxSize;\n    controller.locals.VALIDATION_TYPES = obj.validationType ? obj.validationType : [];\n    controller.locals.PATH = fileUploadObj.fileUploadControllerPath;\n    returnObj.controllers.push({\n      platform: obj.platform,\n      controller,\n    });\n  });\n  returnObj.packageDependencies.dependencies.formidable = '~2.0.1';\n  returnObj.packageDependencies.dependencies['valid-url'] = '~1.0.9';\n  return returnObj;\n}\nasync function makeFileUploadService (templatePath, fileUploadData) {\n  const fileUploadService = writeOperations.loadTemplate(`${templatePath}/fileUpload.js`);\n  const s3Upload = find(fileUploadData, (fileUpload) => fileUpload.storage.toLowerCase() === 's3' || fileUpload.storage.toLowerCase() === 's3_private');\n  const s3Private = find(fileUploadData, (fileUpload) => fileUpload.storage.toLowerCase() === 's3_private');\n  const local = find(fileUploadData, (fileUpload) => fileUpload.storage.toLowerCase() === 'local');\n\n  fileUploadService.locals.LOCAL_UPLOAD = !!local;\n  fileUploadService.locals.S3_UPLOAD = !!s3Upload;\n  fileUploadService.locals.S3_UPLOAD_PRIVATE = !!s3Private;\n  return fileUploadService;\n}\n\nasync function makeFileUploadUsecase (templatePath, uploadsFunctions) {\n  const fileUploadUsecase = [];\n  if (!isEmpty(uploadsFunctions)) {\n    forEach(uploadsFunctions, (uploadsFunctionDetails) => {\n      // console.log(uploadsFunctionDetails); process.exit(1);\n      const uploadsFunction = writeOperations.loadTemplate(`${templatePath}/fileUpload.js`);\n      uploadsFunction.locals.LOCAL_UPLOAD = uploadsFunctionDetails.storage === 'local';\n\n      uploadsFunction.locals.S3_UPLOAD = !!((uploadsFunctionDetails.storage.toLowerCase() === 's3' || uploadsFunctionDetails.storage.toLowerCase() === 's3_private'));\n\n      uploadsFunction.locals.S3_UPLOAD_PRIVATE = (uploadsFunctionDetails.storage.toLowerCase() === 's3_private');\n\n      uploadsFunction.locals.ALLOWED_TYPE = uploadsFunctionDetails.validationType || null;\n      uploadsFunction.locals.MAX_SIZE = uploadsFunctionDetails.maxSize || null;\n\n      fileUploadUsecase.push(uploadsFunction);\n    });\n  }\n\n  return fileUploadUsecase;\n}\n\nconst makeFileUploadControllerIndex = async (templatePath, platforms, userDirectoryStructure) => {\n  const fileUploadControllerIndex = [];\n  forEach(platforms, (platform) => {\n    const fileUploadCtrlInd = writeOperations.loadTemplate(`${templatePath}/fileUploadControllerIndex.js`);\n    fileUploadCtrlInd.locals.PLATFORM = platform;\n    fileUploadCtrlInd.locals.USECASE_PATH = getImportPath(userDirectoryStructure.fileUploadControllerPath, userDirectoryStructure.useCaseFolderPath);\n    fileUploadControllerIndex.push(fileUploadCtrlInd);\n    fileUploadControllerIndex.push(fileUploadCtrlInd);\n  });\n  return fileUploadControllerIndex;\n};\n\nmodule.exports = {\n  makeFileUploadFiles,\n  makeFileUploadService,\n  makeFileUploadUsecase,\n  makeFileUploadControllerIndex,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createRoutes/index.js",
    "content": "/* eslint-disable no-await-in-loop */\n/* eslint-disable no-restricted-syntax */\nconst {\n  isEmpty, forEach, groupBy, cloneDeep, flatten, uniq, has, each,\n} = require('lodash');\nconst writeOperations = require('../../writeOperations');\nconst commonService = require('../utils/common');\nconst { APIS } = require('../../constants/constant');\n\nconst getRandomInt = (max) => Math.floor(Math.random() * max);\nconst transformControllerDetailsWithQueryBuilder = (routes) => {\n  let isQueryBuilderAvailable = false;\n  // eslint-disable-next-line no-restricted-syntax\n  for (const route of routes) {\n    if (Object.prototype.hasOwnProperty.call(route, 'queryBuilder')) {\n      if (route.queryBuilder.length) {\n        isQueryBuilderAvailable = true;\n        const modelGroup = [...new Set(route.queryBuilder.map((item) => item.model))];\n        route.cq_model = modelGroup.filter(Boolean);\n        // eslint-disable-next-line no-restricted-syntax\n        for (const qb of route.queryBuilder) {\n          if (qb.queryMode === 'find') {\n            if (Object.prototype.hasOwnProperty.call(qb, 'select')) {\n              qb.select = (qb.select).join(' ');\n            }\n            if (Object.prototype.hasOwnProperty.call(qb, 'populate')) {\n              qb.populate = commonService.transformSelect(qb.populate);\n            }\n          }\n          if (!qb.outputVariable || qb.outputVariable === '') {\n            qb.outputVariable = `outputVar_${getRandomInt(10000)}`;\n          }\n          qb.queryVarName = `query_${getRandomInt(10000)}`;\n        }\n      }\n    }\n  }\n  return {\n    routes,\n    isQueryBuilderAvailable,\n  };\n};\n\nasync function generatePlatformRoutes (platform, makeRouteObj, customRoutes) {\n  const platformIndexRoutes = {};\n  forEach(platform, (platformObj, platformName) => {\n    const indexRoutes = writeOperations.loadTemplate(`${makeRouteObj.routeFilePath}/platformIndexRoutes.js`);\n    if (!isEmpty(customRoutes)) {\n      const routes = [];\n      const customRoutesOfPlatform = customRoutes.filter((customRoute) => customRoute.platform === platformName);\n      customRoutesOfPlatform.forEach((route) => {\n        const isModelConfigAvailable = has(platformObj, route.model);\n        if (!isModelConfigAvailable) {\n          routes.push(route);\n        }\n      });\n      if (!isEmpty(routes)) {\n        indexRoutes.locals.CUSTOM_ROUTES = routes;\n      }\n    }\n    indexRoutes.locals.PLATFORM = each(platformObj, (model, modelName) => {\n      if (isEmpty(platformObj[modelName])) {\n        delete platformObj[modelName];\n      }\n      return platformObj;\n    });\n    indexRoutes.locals.PLATFORM_NAME = platformName;\n    indexRoutes.locals.ADMIN = platformName === 'admin';\n    indexRoutes.locals.IS_AUTH = makeRouteObj.auth.isAuth && makeRouteObj.auth?.loginPlatform ? makeRouteObj.auth.loginPlatform.includes(platformName) : false;\n    platformIndexRoutes[platformName] = indexRoutes;\n  });\n  return platformIndexRoutes;\n}\nasync function generateRoutes (platform, platformName, makeRouteObj, customRoutesOfPlatform, rolePermissionForPlatform) {\n  const returnRoutes = {};\n  for (const [model, element] of Object.entries(platform)) {\n    if (!isEmpty(element)) {\n      const routes = writeOperations.loadTemplate(`${makeRouteObj.routeFilePath}/modelRoutes.js`);\n      routes.locals.DB_MODEL = model;\n      routes.locals.USER_MODEL = makeRouteObj.auth.userModel === model;\n      routes.locals.MODULE = platformName;\n      routes.locals.LOGIN_ACCESS_PLATFORM = makeRouteObj.auth.loginAccessPlatform;\n      routes.locals.IS_AUTH = makeRouteObj.auth.isAuth;\n      routes.locals.PLATFORM = platformName;\n      if (platformName === 'admin') {\n        routes.locals.ROUTE_PREFIX = `${platformName.toLowerCase()}/${model.toLowerCase()}`;\n      } else {\n        routes.locals.ROUTE_PREFIX = `${platformName.toLowerCase()}/api/v1/${model.toLowerCase()}`;\n      }\n\n      let customPolicyList = [];\n      if (!isEmpty(rolePermissionForPlatform)) {\n        routes.locals.SHOULD_IMPORT_RP_MIDDLEWARE = true;\n      } else {\n        routes.locals.SHOULD_IMPORT_RP_MIDDLEWARE = false;\n      }\n      const apis = [];\n      for (const [key, value] of Object.entries(element)) {\n        let loginFilter;\n        if (makeRouteObj.jsonData.filterByLoggedInUser) {\n          loginFilter = await commonService.getFilterLoggedUser(model, platformName, makeRouteObj.jsonData.filterByLoggedInUser, {\n            isAuth: makeRouteObj.auth.isAuth,\n            userModel: makeRouteObj.auth.userModel,\n            authRoute: value.isAuth,\n          });\n        }\n\n        if (APIS.includes(key) && value.selected) {\n          if (value.isAuth && makeRouteObj.auth.isAuth) {\n            if (rolePermissionForPlatform && rolePermissionForPlatform[model] && rolePermissionForPlatform[model][key] && rolePermissionForPlatform[model][key].length) {\n              value.policy = [...value.policy, 'checkRolePermission'];\n            }\n          }\n          if (value.policy && value.policy.length) {\n            customPolicyList = customPolicyList.concat(value.policy);\n          }\n          apis.push({\n            method: key,\n            isAuth: value.isAuth && makeRouteObj.auth.isAuth,\n            policy: value.policy ? value.policy : [],\n            loginFilter: !!loginFilter,\n            addedBy: loginFilter ? loginFilter.addedByKey : null,\n          });\n        }\n      }\n      routes.locals.SUPPORT_API = apis;\n      customPolicyList = customPolicyList.filter((item, i, ar) => ar.indexOf(item) === i);\n      routes.locals.CUSTOM_POLICY = customPolicyList;\n      const customRoutesOfModel = groupBy(customRoutesOfPlatform, 'model')[model];\n      if (customRoutesOfModel) {\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode(customRoutesOfModel, 'queryBuilder');\n        const transformedControllerDetail = commonService.transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        const customRoutePolicy = commonService.getPolicyForCustomRoutes(transformedControllerDetail.routes);\n        if (customRoutePolicy && customRoutePolicy.length) {\n          routes.locals.CUSTOM_POLICY = flatten([...new Set([...customPolicyList, customRoutePolicy])]);\n        }\n        const controllersToImport = (transformedControllerDetail.routes).map(((obj) => obj.controller));\n        routes.locals.CONTROLLERS_TO_IMPORT = uniq(controllersToImport);\n        routes.locals.PLATFORM = platformName;\n        routes.locals.CUSTOM_ROUTES = transformedControllerDetail.routes;\n        routes.locals.IMPORT = transformedControllerDetail.routes;\n      } else {\n        routes.locals.CUSTOM_ROUTES = [];\n        routes.locals.CONTROLLERS_TO_IMPORT = [];\n      }\n      returnRoutes[model] = routes;\n    } else {\n      const customRoutesOfModel = groupBy(customRoutesOfPlatform, 'model')[model];\n      if (customRoutesOfModel) {\n        const routes = writeOperations.loadTemplate(`${makeRouteObj.routeFilePath}/modelRoutes.js`);\n        routes.locals.DB_MODEL = model;\n        routes.locals.USER_MODEL = false;\n        routes.locals.MODULE = platformName;\n        routes.locals.LOGIN_ACCESS_PLATFORM = makeRouteObj.auth.loginAccessPlatform;\n        routes.locals.IS_AUTH = makeRouteObj.auth.isAuth;\n        routes.locals.CUSTOM_POLICY = [];\n        routes.locals.SUPPORT_API = [];\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode(customRoutesOfModel, 'queryBuilder');\n        const transformedControllerDetail = commonService.transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        const controllersToImport = (transformedControllerDetail.routes).map(((obj) => obj.controller));\n        routes.locals.CONTROLLERS_TO_IMPORT = uniq(controllersToImport);\n        routes.locals.CUSTOM_POLICY = commonService.getPolicyForCustomRoutes(transformedControllerDetail.routes);\n        routes.locals.PLATFORM = platformName;\n        routes.locals.CUSTOM_ROUTES = transformedControllerDetail.routes;\n        routes.locals.IMPORT = transformedControllerDetail.routes;\n        returnRoutes[model] = routes;\n      }\n    }\n  }\n  if (!isEmpty(customRoutesOfPlatform)) {\n    const { customRoutesPath } = makeRouteObj;\n    const customRoutesWithoutModel = customRoutesOfPlatform.filter((route) => (route.createNewFile));\n    customRoutesWithoutModel.forEach((customRoute) => {\n      const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n      const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode([customRoute], 'queryBuilder');\n      const transformedControllerDetail = transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n      route.locals.POLICIES = commonService.getPolicyForCustomRoutes([customRoute]);\n      route.locals.PLATFORM = platformName;\n      route.locals.ROUTES = transformedControllerDetail.routes;\n      route.locals.IMPORT = transformedControllerDetail.routes;\n      route.locals.SERVICE_NAME = customRoute.controller;\n      returnRoutes[customRoute.controller] = route;\n    });\n\n    customRoutesOfPlatform = customRoutesOfPlatform.filter((route) => !isEmpty(route.model));\n    customRoutesOfPlatform.forEach((customRoute) => {\n      const isModelConfigAvailable = has(platform, customRoute.model);\n      if (!isModelConfigAvailable) {\n        const route = writeOperations.loadTemplate(`${customRoutesPath}/route.js`);\n        const routesWithQueryMode = commonService.removeQueryBuilderWithoutQueryMode([customRoute], 'queryBuilder');\n        const transformedControllerDetail = transformControllerDetailsWithQueryBuilder(cloneDeep(routesWithQueryMode));\n        route.locals.POLICIES = commonService.getPolicyForCustomRoutes([customRoute]);\n        route.locals.PLATFORM = platformName;\n        route.locals.ROUTES = transformedControllerDetail.routes;\n        route.locals.IMPORT = transformedControllerDetail.routes;\n        route.locals.SERVICE_NAME = customRoute.controller;\n        returnRoutes[customRoute.model] = route;\n      }\n    });\n  }\n\n  return returnRoutes;\n}\nasync function makeRoutes (makeRoutesObj) {\n  const platform = makeRoutesObj.jsonData.modelConfig;\n  const customRoutes = makeRoutesObj.jsonData.routes && makeRoutesObj.jsonData.routes.apis ? makeRoutesObj.jsonData.routes.apis : undefined;\n  const rolePermission = makeRoutesObj.jsonData.rolePermission ? makeRoutesObj.jsonData.rolePermission : undefined;\n  if (!isEmpty(platform)) {\n    const modelWiseRoutes = {};\n\n    // ? model wise routes\n    for (const [module, element] of Object.entries(platform)) {\n      /*\n       * * module = admin , device , desktop , client\n       * * element = {user:{\"create:{\"selected\":true,\"policy\":[],\"isAuth\":true}\"}}\n       */\n      const customRoutesOfPlatform = groupBy(customRoutes, 'platform')[module];\n      let rolePermissionForPlatform;\n      if (!isEmpty(rolePermission)) {\n        rolePermissionForPlatform = rolePermission[module];\n      }\n      if (!isEmpty(element)) {\n        const modelRoutes = await generateRoutes(element, module, makeRoutesObj, customRoutesOfPlatform, rolePermissionForPlatform);\n        modelWiseRoutes[module] = modelRoutes;\n      }\n    }\n    // ? platform index routes\n    const platformRoutes = await generatePlatformRoutes(platform, makeRoutesObj, customRoutes);\n\n    // ? main index routes\n    const indexRoute = writeOperations.loadTemplate(`${makeRoutesObj.routeFilePath}/index.js`);\n    indexRoute.locals.PLATFORM = platform;\n    if (makeRoutesObj.jsonData.authentication.loginRateLimit) {\n      indexRoute.locals.LOGIN_RATE = makeRoutesObj.jsonData.authentication.loginRateLimit.max;\n      if (makeRoutesObj.jsonData.authentication.loginRateLimit.reActiveTime) indexRoute.locals.REACTIVE_TIME = makeRoutesObj.jsonData.authentication.loginRateLimit.reActiveTime;\n      else indexRoute.locals.REACTIVE_TIME = 1000;\n    } else {\n      indexRoute.locals.LOGIN_RATE = false;\n    }\n\n    return {\n      modelWiseRoutes,\n      platformRoutes,\n      indexRoute,\n    };\n  }\n  return {};\n}\nmodule.exports = { makeRoutes };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createStaticFiles.js",
    "content": "const writeOperations = require('../writeOperations');\n\nasync function generateStaticFilesForCC (templateFolderName, dir, userDirectoryStructure) {\n  writeOperations.copyTemplateMulti(`${templateFolderName}/helpers`, `${dir}${userDirectoryStructure.helperFolderPath}`, '*.js');\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils`, `${dir}${userDirectoryStructure.utilsFolderPath}`, '*.js');\n  // writeOperations.copyTemplate(`${templateFolderName}/validation/genericValidator.js`, `${dir}${userDirectoryStructure.validationFolderPath}/genericValidator.js`);\n  writeOperations.copyTemplate(`${templateFolderName}/validation/index.js`, `${dir}${userDirectoryStructure.validationFolderPath}/index.js`);\n  // writeOperations.copyTemplate(`${templateFolderName}/services/dbService.js`, `${dir}${userDirectoryStructure.serviceFolderPath}/mongoDbService.js`);\n  writeOperations.copyTemplate(`${templateFolderName}/data-access/dbService.js`, `${dir}${userDirectoryStructure.dbServiceFilePath}`);\n  writeOperations.copyTemplate(`${templateFolderName}/views/index.ejs`, `${dir}${userDirectoryStructure.viewsFolderPath}/index.ejs`);\n\n  // create response folder\n  writeOperations.mkdir(dir, `${userDirectoryStructure.utilsFolderPath}/response`);\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils/response/`, `${dir}${userDirectoryStructure.utilsFolderPath}/response`, '*.js');\n}\n\nasync function generateStaticFilesForMVC (templateFolderName, dir, userDirectoryStructure) {\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils`, `${dir}${userDirectoryStructure.utilsFolderPath}`, '*.js');\n  writeOperations.copyTemplate(`${templateFolderName}/views/index.ejs`, `${dir}${userDirectoryStructure.viewsFolderPath}/index.ejs`);\n\n  // create response folder\n  writeOperations.mkdir(dir, `${userDirectoryStructure.utilsFolderPath}/response`);\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils/response/`, `${dir}${userDirectoryStructure.utilsFolderPath}/response`, '*.js');\n}\nasync function generateStaticFilesForMVCSequelize (templateFolderName, dir, userDirectoryStructure) {\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils`, `${dir}${userDirectoryStructure.utilsFolderPath}`, '*.js');\n  writeOperations.copyTemplate(`${templateFolderName}/views/index.ejs`, `${dir}${userDirectoryStructure.viewsFolderPath}/index.ejs`);\n  writeOperations.mkdir(dir, `${userDirectoryStructure.utilsFolderPath}/response`);\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils/response/`, `${dir}${userDirectoryStructure.utilsFolderPath}/response`, '*.js');\n}\nasync function generateStaticFilesForCCSequelize (templateFolderName, dir, userDirectoryStructure) {\n  writeOperations.copyTemplateMulti(`${templateFolderName}/helpers`, `${dir}/helpers`, '*.js');\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils`, `${dir}/utils`, '*.js');\n  // writeOperations.copyTemplate(`${templateFolderName}/validation/genericValidator.js`, `${dir}/validation/genericValidator.js`);\n\n  writeOperations.copyTemplate(`${templateFolderName}/validation/index.js`, `${dir}${userDirectoryStructure.validationFolderPath}/index.js`);\n\n  writeOperations.copyTemplate(`${templateFolderName}/data-access/dbService.js`, `${dir}${userDirectoryStructure.dbServiceFilePath}`);\n  writeOperations.copyTemplate(`${templateFolderName}/views/index.ejs`, `${dir}/views/index.ejs`);\n\n  // create response folder\n  writeOperations.mkdir(dir, `${userDirectoryStructure.utilsFolderPath}/response`);\n  writeOperations.copyTemplateMulti(`${templateFolderName}/utils/response/`, `${dir}${userDirectoryStructure.utilsFolderPath}/response`, '*.js');\n}\nasync function addRolePermissionService (templateFolderName) {\n  const rolePermissionService = writeOperations.loadTemplate(`${templateFolderName}/checkRolePermission.js`);\n  return rolePermissionService;\n}\nmodule.exports = {\n  generateStaticFilesForCC,\n  generateStaticFilesForMVC,\n  generateStaticFilesForCCSequelize,\n  addRolePermissionService,\n  generateStaticFilesForMVCSequelize,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createTestCases/mongooseTestCases.js",
    "content": "/* eslint-disable prefer-destructuring */\n/* global  _ */\nconst { forEach } = require('lodash');\nconst fakeData = require('../generateFakeData');\nconst writeOperations = require('../../writeOperations');\nconst { removeGivenKeyFromObject } = require('../utils/common');\n\nconst getReferenceCollectionsOfModel = (modelJSON) => {\n  const referenceCollections = [];\n  Object.keys(modelJSON).forEach((field) => {\n    if (modelJSON[field].type === 'Schema.Types.ObjectId' && modelJSON[field].ref !== undefined) {\n      referenceCollections.push(modelJSON[field].ref.replace(/@@/g, '').replace(/@@/g, ''));\n    }\n  });\n  return referenceCollections;\n};\n\nconst configureMongoAuthTestCases = (testCaseObj) => {\n  const {\n    jsonData, authObj, platforms, testCaseTemplateFolder, testCasePath,\n  } = testCaseObj;\n  const { authModel } = jsonData.authentication;\n  const allTestCases = {};\n  const dbName = jsonData.config.databaseName;\n\n  const loginAccess = jsonData?.authentication?.loginAccess;\n  const loginAccessOfPlatform = {};\n  _.forEach(platforms, (platform) => {\n    loginAccessOfPlatform[platform] = [];\n    _.forEach(loginAccess, (p, userType) => {\n      if (p.includes(platform)) {\n        loginAccessOfPlatform[platform].push(userType);\n      }\n    });\n  });\n\n  const userTypes = jsonData?.authentication?.types;\n\n  const referenceCollections = getReferenceCollectionsOfModel(jsonData.models[authModel]);\n  forEach(platforms, (platformName) => {\n    const fakeDataOfType = {};\n    let fakeDataOfModels; let\n      authFakeData;\n    for (let i = 0; i < userTypes.length; i += 1) {\n      fakeDataOfModels = fakeData.validSchema(_.cloneDeep(jsonData?.models));\n      authFakeData = fakeDataOfModels[authModel];\n      authFakeData = removeGivenKeyFromObject(authFakeData, ['id', 'resetPasswordLink', 'loginRetryLimit', 'loginReactiveTime', 'role', 'loginOTP']);\n      fakeDataOfType[userTypes[i]] = authFakeData;\n    }\n    const userType = loginAccessOfPlatform[platformName];\n    if (userType.length) {\n      const fakeDataOfUser = fakeDataOfType[userType[0]];\n      fakeDataOfModels = fakeData.validSchema(_.cloneDeep(jsonData?.models));\n      const authTestCase = writeOperations.loadTemplate(`${testCaseTemplateFolder}/auth.test.js`);\n      authTestCase.locals.MODELS = Object.keys(_.pickBy(jsonData.models, (value, key) => referenceCollections.includes(key)));\n      authTestCase.locals.FAKE_DATA = _.pickBy(fakeDataOfModels, (value, key) => referenceCollections.includes(key));\n      authTestCase.locals.DB_NAME = `${dbName}_test`;\n      authTestCase.locals.AUTH_MODEL_JSON = jsonData.models[authModel];\n      authTestCase.locals.ROLE = userType[0];\n      authTestCase.locals.FAKE_DATA_OF_AUTH = fakeDataOfUser;\n      authTestCase.locals.path = testCasePath;\n      authTestCase.locals.PLATFORM = platformName;\n      authTestCase.locals.AUTH_MODEL = authModel;\n      authTestCase.locals.USER_LOGIN_WITH = authObj.userLoginWith;\n      allTestCases[platformName] = {};\n      allTestCases[platformName].auth = authTestCase;\n      Object.assign(allTestCases[platformName], { auth: authTestCase });\n    }\n  });\n  return allTestCases;\n};\n\nmodule.exports = { configureMongoAuthTestCases };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createTestCases/sequelizeTestCases.js",
    "content": "/* eslint-disable prefer-destructuring */\n/* global  _ */\nconst fakeData = require('../generateFakeDataSequelize');\nconst writeOperations = require('../../writeOperations');\nconst { removeGivenKeyFromObject } = require('../utils/common');\n\nconst getReferenceCollectionsOfModel = (modelJSON) => {\n  const referenceCollections = [];\n  Object.keys(modelJSON).forEach((field) => {\n    if (modelJSON[field].type === 'Schema.Types.ObjectId' && modelJSON[field].ref !== undefined) {\n      referenceCollections.push(modelJSON[field].ref.replace(/@@/g, '').replace(/@@/g, ''));\n    }\n  });\n  return referenceCollections;\n};\n\nconst configureSequelizeAuthTestCases = (testCaseObj) => {\n  const {\n    jsonData, authObj, platforms, testCaseTemplateFolder, testCasePath,\n  } = testCaseObj;\n  const { authModel } = jsonData.authentication;\n  const allTestCases = {};\n  const dbName = jsonData.config.databaseName;\n\n  const loginAccess = jsonData?.authentication?.loginAccess;\n  const loginAccessOfPlatform = {};\n  _.forEach(platforms, (platform) => {\n    loginAccessOfPlatform[platform] = [];\n    _.forEach(loginAccess, (p, userType) => {\n      if (p.includes(platform)) {\n        loginAccessOfPlatform[platform].push(userType);\n      }\n    });\n  });\n\n  const userTypes = jsonData?.authentication?.types;\n  const fakeDataOfType = {};\n  let fakeDataOfModels; let\n    authFakeData;\n  for (let i = 0; i < userTypes.length; i += 1) {\n    fakeDataOfModels = fakeData.validSchema(_.cloneDeep(jsonData?.models));\n    authFakeData = fakeDataOfModels[authModel];\n    authFakeData = removeGivenKeyFromObject(authFakeData, ['id', 'resetPasswordLink', 'loginRetryLimit', 'loginReactiveTime', 'role', 'loginOTP']);\n    fakeDataOfType[userTypes[i]] = authFakeData;\n  }\n  const referenceCollections = getReferenceCollectionsOfModel(jsonData.models[authModel]);\n  _.forEach(platforms, (platformName) => {\n    const userType = loginAccessOfPlatform[platformName];\n    if (userType.length) {\n      const fakeDataOfUser = fakeDataOfType[userType[0]];\n      fakeDataOfModels = fakeData.validSchema(_.cloneDeep(jsonData?.models));\n      const authTestCase = writeOperations.loadTemplate(`${testCaseTemplateFolder}/auth.test.js`);\n      authTestCase.locals.MODELS = Object.keys(_.pickBy(jsonData.models, (value, key) => referenceCollections.includes(key)));\n      authTestCase.locals.FAKE_DATA = _.pickBy(fakeDataOfModels, (value, key) => referenceCollections.includes(key));\n      authTestCase.locals.DB_NAME = `${dbName}_test`;\n      authTestCase.locals.AUTH_MODEL_JSON = jsonData.models[authModel];\n      authTestCase.locals.ROLE = userType[0];\n      authTestCase.locals.FAKE_DATA_OF_AUTH = fakeDataOfUser;\n      authTestCase.locals.path = testCasePath;\n      authTestCase.locals.PLATFORM = platformName;\n      authTestCase.locals.AUTH_MODEL = authModel;\n      authTestCase.locals.USER_LOGIN_WITH = authObj.userLoginWith;\n      allTestCases[platformName] = {};\n      allTestCases[platformName].auth = authTestCase;\n      Object.assign(allTestCases[platformName], { auth: authTestCase });\n    }\n  });\n  return allTestCases;\n};\n\nmodule.exports = { configureSequelizeAuthTestCases };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/createUseCaseFiles/index.js",
    "content": "const {\n  forEach, isEmpty, uniq,\n} = require('lodash');\nconst writeOperations = require('../../writeOperations/index');\n\nasync function getDeleteDependentModel (model, deleteDependency) {\n  let deleteModels = [];\n  // eslint-disable-next-line no-restricted-syntax\n  for (const k in deleteDependency) {\n    if (k === model) {\n      deleteModels = deleteDependency[k];\n      break;\n    } else {\n      deleteModels = [];\n    }\n  }\n  return deleteModels;\n}\n\nconst createUseCaseFiles = (rootTemplateDirPath, {\n  modelConfig, deleteDependency, auth, defaultRole,\n}) => {\n  // Create  use case model wise\n  const useCaseList = {};\n  forEach(modelConfig, (modelDetails) => {\n    forEach(modelDetails, (modelOperations, modelName) => {\n      if (!useCaseList[modelName]) {\n        useCaseList[modelName] = {};\n      }\n      forEach(modelOperations, (operationDetails, operation) => {\n        useCaseList[modelName][operation] = operationDetails;\n      });\n    });\n  });\n  // create all use case model wise.\n  const allUseCases = {};\n  forEach(useCaseList, async (operations, model) => {\n    allUseCases[model] = {};\n    const modelFc = model.charAt(0).toUpperCase() + model.slice(1);\n    const deleteDependent = await getDeleteDependentModel(model, deleteDependency);\n    forEach(operations, (operationDetails, operationName) => {\n      // For Create API\n      if (operationName === 'create') {\n        const createUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/create.js`);\n        createUseCase.locals.MODEL_NAME_FC = modelFc;\n        createUseCase.locals.MODEL_NAME = model;\n        if (auth.isAuth && auth.userModel === model) {\n          if (!isEmpty(defaultRole)) {\n            createUseCase.locals.DEFAULT_USER_ROLE = true;\n          }\n        }\n        createUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = createUseCase;\n      }\n\n      if (operationName === 'findAll') {\n        const findAllUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/findAll.js`);\n        findAllUseCase.locals.MODEL_NAME_FC = modelFc;\n        findAllUseCase.locals.MODEL_NAME = model;\n        findAllUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = findAllUseCase;\n      }\n\n      if (operationName === 'count') {\n        const countUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/count.js`);\n        countUseCase.locals.MODEL_NAME_FC = modelFc;\n        countUseCase.locals.MODEL_NAME = model;\n        countUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = countUseCase;\n      }\n\n      if (operationName === 'update') {\n        const updateUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/update.js`);\n        updateUseCase.locals.MODEL_NAME_FC = modelFc;\n        updateUseCase.locals.MODEL_NAME = model;\n        updateUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = updateUseCase;\n      }\n\n      if (operationName === 'delete') {\n        const deleteUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/delete.js`);\n        let dbDependencyInjection = [model];\n        if (deleteDependent.length) {\n          if (!isEmpty(deleteDependent)) {\n            forEach(deleteDependent, (value) => {\n              dbDependencyInjection.push(value.model);\n            });\n          }\n          dbDependencyInjection = uniq(dbDependencyInjection);\n        }\n        deleteUseCase.locals.MODEL_NAME_FC = modelFc;\n        deleteUseCase.locals.MODEL_NAME = model;\n        deleteUseCase.locals.DELETE_DEPENDENT_MODEL = !!deleteDependent.length;\n        deleteUseCase.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n        deleteUseCase.locals.FILE_NAME = `${operationName}One`;\n        allUseCases[model][operationName] = deleteUseCase;\n      }\n\n      if (operationName === 'deleteMany') {\n        const deleteManyUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/deleteMany.js`);\n        let dbDependencyInjection = [model];\n        if (deleteDependent.length) {\n          if (!isEmpty(deleteDependent)) {\n            forEach(deleteDependent, (value) => {\n              dbDependencyInjection.push(value.model);\n            });\n          }\n          dbDependencyInjection = uniq(dbDependencyInjection);\n        }\n        deleteManyUseCase.locals.MODEL_NAME_FC = modelFc;\n        deleteManyUseCase.locals.MODEL_NAME = model;\n        deleteManyUseCase.locals.DELETE_DEPENDENT_MODEL = !!deleteDependent.length;\n        deleteManyUseCase.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n        deleteManyUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = deleteManyUseCase;\n      }\n\n      if (operationName === 'softDelete') {\n        const softDeleteUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/softDelete.js`);\n        let dbDependencyInjection = [model];\n        if (deleteDependent.length) {\n          if (!isEmpty(deleteDependent)) {\n            forEach(deleteDependent, (value) => {\n              dbDependencyInjection.push(value.model);\n            });\n          }\n          dbDependencyInjection = uniq(dbDependencyInjection);\n        }\n        softDeleteUseCase.locals.MODEL_NAME_FC = modelFc;\n        softDeleteUseCase.locals.MODEL_NAME = model;\n        softDeleteUseCase.locals.DELETE_DEPENDENT_MODEL = !!deleteDependent.length;\n        softDeleteUseCase.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n        softDeleteUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = softDeleteUseCase;\n      }\n\n      if (operationName === 'softDeleteMany') {\n        const softDeleteManyUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/softDeleteMany.js`);\n        let dbDependencyInjection = [model];\n        if (deleteDependent.length) {\n          if (!isEmpty(deleteDependent)) {\n            forEach(deleteDependent, (value) => {\n              dbDependencyInjection.push(value.model);\n            });\n          }\n          dbDependencyInjection = uniq(dbDependencyInjection);\n        }\n        softDeleteManyUseCase.locals.MODEL_NAME_FC = modelFc;\n        softDeleteManyUseCase.locals.MODEL_NAME = model;\n        softDeleteManyUseCase.locals.DELETE_DEPENDENT_MODEL = !!deleteDependent.length;\n        softDeleteManyUseCase.locals.DB_DEPENDENCY_INJECTION = dbDependencyInjection;\n        softDeleteManyUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = softDeleteManyUseCase;\n      }\n\n      if (operationName === 'createBulk') {\n        const createBulkUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/createBulk.js`);\n        createBulkUseCase.locals.MODEL_NAME_FC = modelFc;\n        createBulkUseCase.locals.MODEL_NAME = model;\n        if (auth.isAuth && auth.userModel === model) {\n          if (!isEmpty(defaultRole)) {\n            createBulkUseCase.locals.DEFAULT_USER_ROLE = true;\n          }\n        }\n        createBulkUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = createBulkUseCase;\n      }\n\n      if (operationName === 'bulkUpdate') {\n        const bulkUpdateUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/bulkUpdate.js`);\n        bulkUpdateUseCase.locals.MODEL_NAME_FC = modelFc;\n        bulkUpdateUseCase.locals.MODEL_NAME = model;\n        bulkUpdateUseCase.locals.FILE_NAME = 'updateBulk';\n        allUseCases[model][operationName] = bulkUpdateUseCase;\n      }\n\n      if (operationName === 'partialUpdate') {\n        const partialUpdateUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/partialUpdate.js`);\n        partialUpdateUseCase.locals.MODEL_NAME_FC = modelFc;\n        partialUpdateUseCase.locals.MODEL_NAME = model;\n        partialUpdateUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = partialUpdateUseCase;\n      }\n\n      if (operationName === 'findById') {\n        const findByIdUseCase = writeOperations.loadTemplate(`${rootTemplateDirPath}/findById.js`);\n        findByIdUseCase.locals.MODEL_NAME_FC = modelFc;\n        findByIdUseCase.locals.MODEL_NAME = model;\n        findByIdUseCase.locals.FILE_NAME = operationName;\n        allUseCases[model][operationName] = findByIdUseCase;\n      }\n\n      if (auth.isAuth && auth.userModel === model) {\n        const changePassword = writeOperations.loadTemplate(`${rootTemplateDirPath}/changePassword.js`);\n        changePassword.locals.MODEL_NAME_FC = modelFc;\n        changePassword.locals.MODEL_NAME = model;\n        changePassword.locals.FILE_NAME = 'changePassword';\n        changePassword.locals.PASSWORD_FIELD = auth.userLoginWith.password || 'password';\n        allUseCases[model].changePassword = changePassword;\n\n        const updateProfile = writeOperations.loadTemplate(`${rootTemplateDirPath}/updateProfile.js`);\n        updateProfile.locals.MODEL_NAME_FC = modelFc;\n        updateProfile.locals.MODEL_NAME = model;\n        updateProfile.locals.FILE_NAME = 'updateProfile';\n        allUseCases[model].updateProfile = updateProfile;\n      }\n    });\n  });\n  return allUseCases;\n};\n\nconst createCommonUseCaseFiles = async (rootTemplateDirPath, authService) => {\n  // Create common usecase\n  const allCommonUseCases = {};\n\n  // Auth service usecase\n  const loginUser = writeOperations.loadTemplate(`${rootTemplateDirPath}/common/loginUser.js`);\n  forEach(authService.locals, (value, key) => {\n    loginUser.locals[key] = value;\n  });\n  loginUser.locals.USER_MODEL = authService.locals.MODEL;\n  loginUser.locals.FILE_NAME = 'loginUser';\n  loginUser.locals.PLATFORMS = authService.locals.PLATFORMS;\n  allCommonUseCases.loginUser = loginUser;\n\n  // Get RoleAccess Usecase\n  const getRoleAccess = writeOperations.loadTemplate(`${rootTemplateDirPath}/common/getRoleAccess.js`);\n  getRoleAccess.locals.FILE_NAME = 'getRoleAccess';\n  allCommonUseCases.getRoleAccess = getRoleAccess;\n\n  // sendResetPasswordNotification\n  const sendResetPasswordNotification = writeOperations.loadTemplate(`${rootTemplateDirPath}/common/sendResetPasswordNotification.js`);\n  sendResetPasswordNotification.locals.FILE_NAME = 'sendResetPasswordNotification';\n  sendResetPasswordNotification.locals.USER_MODEL = authService.locals.MODEL;\n  sendResetPasswordNotification.locals.EMAIL_FIELD = authService.locals.EMAIL_FIELD;\n  sendResetPasswordNotification.locals.MOBILE_FIELD = authService.locals.MOBILE_FIELD;\n  sendResetPasswordNotification.locals.FORGOT_WITH_LINK = authService.locals.FORGOT_WITH_LINK;\n  sendResetPasswordNotification.locals.FORGOT_WITH_OTP = authService.locals.FORGOT_WITH_OTP;\n  sendResetPasswordNotification.locals.RESET_PASSWORD_TEMPLATE_NAME = authService.locals.RESET_PASSWORD_TEMPLATE_NAME;\n  sendResetPasswordNotification.locals.RESET_PASSWORD_NOTIFICATION_TYPE = authService.locals.RESET_PASSWORD_NOTIFICATION_TYPE;\n  sendResetPasswordNotification.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE = authService.locals.RESET_PASSWORD_TEMPLATE_ATTRIBUTE;\n  allCommonUseCases.sendResetPasswordNotification = sendResetPasswordNotification;\n\n  return allCommonUseCases;\n};\n\nmodule.exports = {\n  createUseCaseFiles,\n  createCommonUseCaseFiles,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/generateFakeData/fakeDataType.js",
    "content": "module.exports = {\n  name: ['name', 'firstname', 'middlename', 'lastname'],\n  email: ['mailid', 'mail', 'email', 'emailid', 'gmail'],\n  age: ['age'],\n  gender: ['sex', 'gender'],\n  phone: ['phone', 'mobile', 'contact', 'mobileno', 'phoneno', 'contactno'],\n  price: ['rate', 'price', 'amount', 'totalamount'],\n  address: ['address', 'place', 'addr'],\n  color: ['color', 'colour'],\n  password: ['password', 'pass'],\n  username: ['username', 'uname'],\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/generateFakeData/index.js",
    "content": "/* global __basedir */\n/* global _ */\nconst fs = require('fs');\nconst faker = require('faker');\nconst ObjectID = require('bson-objectid');\nconst RandExp = require('randexp');\nconst fields = require('./fakeDataType');\nconst { REMOVE_FIELD_FOR_FAKE_DATA } = require('../../constants/constant');\n\nfunction readFile (FileName) {\n  return fs.readFileSync(FileName, { encoding: 'utf8' });\n}\nconst mongooseConfiguration = readFile(`${__basedir}/config/mongooseInput.json`);\nconst jsonMongooseConfig = JSON.parse(mongooseConfiguration);\n\nfunction getFdata (data, key) {\n  let fakeData;\n  _.map(data, (valueData) => {\n    if (_.has(data, 'match')) {\n      const result = data.match.substring(1, data.match.length - 1);\n      const finalRegexp = new RegExp(result);\n      fakeData = new RandExp(finalRegexp).gen();\n    } else {\n      key = key !== 0 ? key.toLowerCase() : key;\n      switch (valueData) {\n      case 'String':\n        // console.log(key)\n        if (key) {\n          key = key.toLowerCase();\n        } if (fields.name.includes(key)) {\n          fakeData = faker.name.findName();\n        } else if (fields.gender.includes(key)) {\n          fakeData = faker.name.gender();\n        } else if (fields.email.includes(key)) {\n          fakeData = faker.internet.email();\n        } else if (fields.address.includes(key)) {\n          fakeData = faker.address.streetAddress();\n        } else if (fields.color.includes(key)) {\n          fakeData = faker.commerce.color();\n        } else if (fields.phone.includes(key)) {\n          fakeData = faker.phone.phoneNumber();\n        } else if (fields.password.includes(key)) {\n          fakeData = faker.internet.password();\n        } else if (fields.username.includes(key)) {\n          fakeData = faker.internet.userName();\n        } else {\n          fakeData = faker.random.word();\n        }\n        break;\n      case 'Number':\n        if (fields.age.includes(key)) {\n          if (_.has(data, 'min') && !_.has(data, 'max')) {\n            fakeData = faker.datatype.number({ min: data.min });\n          } else if (_.has(data, 'max') && !_.has(data, 'min')) {\n            fakeData = faker.datatype.number({ max: data.maxLength });\n          } else if (_.has(data, 'min') && _.has(data, 'max')) {\n            fakeData = faker.datatype.number({\n              min: data.min,\n              max: data.max,\n            });\n          } else {\n            fakeData = faker.datatype.number(\n              {\n                min: 10,\n                max: 99,\n              },\n            );\n          }\n        } else if (fields.price.includes(key)) {\n          if (_.has(data, 'min') && !_.has(data, 'max')) {\n            fakeData = faker.finance.amount({ min: data.min });\n          } else if (_.has(data, 'max') && !_.has(data, 'min')) {\n            fakeData = faker.finance.amount({ max: data.maxLength });\n          } else if (_.has(data, 'min') && _.has(data, 'max')) {\n            fakeData = faker.finance.amount({\n              min: data.min,\n              max: data.max,\n            });\n          } else {\n            fakeData = faker.datatype.number(\n              {\n                min: 10,\n                max: 99,\n              },\n            );\n          }\n        } else {\n          fakeData = faker.datatype.number(\n            {\n              min: 1,\n              max: 999,\n            },\n          );\n        }\n        break;\n      case 'Boolean':\n        fakeData = faker.datatype.boolean();\n        break;\n      case 'Array':\n        break;\n      case 'JSON':\n        break;\n      case 'Mixed':\n        break;\n      case 'Date':\n        fakeData = faker.date.future();\n        break;\n      case 'Buffer':\n        break;\n      case 'Map':\n        break;\n      case 'Schema.Types.ObjectId':\n        // console.log(ObjectID(),\" objId for \",key)\n        fakeData = ObjectID();\n        break;\n      case 'ObjectId':\n        fakeData = ObjectID();\n        break;\n      case 'Email':\n        fakeData = faker.internet.email();\n        break;\n      default:\n        break;\n      }\n    }\n  });\n  return fakeData;\n}\nmodule.exports = {\n  validSchema (input) {\n    try {\n      _.map(input, (modelValue, model) => {\n        _.map(modelValue, (modelObjValue, modelObjKey) => {\n          if (!REMOVE_FIELD_FOR_FAKE_DATA.includes(modelObjKey)) {\n            if (typeof input[model][modelObjKey] === 'object' && !Array.isArray(input[model][modelObjKey])) {\n              const item = input[model][modelObjKey];\n              const data = this.validSchemaObject(item, modelObjKey);\n              input[model][modelObjKey] = data;\n            } else if (Array.isArray(modelObjValue)) {\n              const item = input[model][modelObjKey];\n              const data = this.validSchemaObject(item, modelObjKey);\n              input[model][modelObjKey] = data;\n            } else {\n              const data = getFdata(modelObjValue, modelObjKey);\n              input[model][modelObjKey] = data;\n            }\n          } else {\n            delete input[model][modelObjKey];\n          }\n        });\n        input[model].id = ObjectID();\n      });\n      return input;\n    } catch (error) {\n      throw new Error(error);\n    }\n  },\n  validSchemaObject (item, modelObjKey) {\n    let fakeData;\n    const possibleKeys = Object.keys(jsonMongooseConfig.model.key);\n    fakeData = getFdata(item, modelObjKey);\n    _.map(item, (data, key) => {\n      if (possibleKeys.includes(key)) {\n        delete item[key];\n        switch (key) {\n        case 'type':\n          break;\n        case 'ref':\n          break;\n        case 'index':\n        case 'unique':\n        case 'alias':\n        case 'lowercase':\n        case 'trim':\n        case 'required':\n        case 'immutable':\n        case 'sparse':\n        case 'minLength':\n        case 'maxLength':\n        case 'of':\n          break;\n        case 'default':\n          break;\n        case 'enum':\n          break;\n        case 'validate':\n          break;\n        case 'get':\n          break;\n        case 'set':\n          break;\n        case 'transform':\n          break;\n        case 'match':\n          break;\n        case 'populate':\n          break;\n        case 'min':\n          break;\n        case 'max':\n          break;\n        default:\n          break;\n        }\n      } else if (typeof data === 'object' && !Array.isArray(data)) {\n        /*\n         * console.log(key);\n         * console.log(data)\n         */\n        let fData;\n        if (typeof key === 'number') {\n          fData = this.validSchemaObject(data, modelObjKey);\n        } else {\n          fData = this.validSchemaObject(data, key);\n        }\n\n        item[key] = fData;\n        fakeData = item;\n      } else if (Array.isArray(data)) {\n        const fData = this.validSchemaObject(data, key);\n        item[key] = fData;\n        fakeData = item;\n      } else if (jsonMongooseConfig.model.key.type.includes(data)) {\n        /*\n         * if (typeof key === \"number\") {\n         *     let fData = this.validSchemaObject(data, key);\n         *     item[key] = fData;\n         *     fakeData = item;\n         * } else {\n         *     let fData = this.validSchemaObject(data, key);\n         *     item[key] = fData;\n         *     fakeData = item;\n         * }\n         */\n        const fData = getFdata(data, key);\n        // console.log(fData,\" ---------fdata\")\n        item[key] = fData;\n        fakeData = item;\n      } else {\n        /*\n         * console.log(key, \" \", data)\n         * console.log(\"not any fake to generate.......\")\n         */\n      }\n    });\n    return fakeData;\n  },\n  getFindAllObject () {\n    const obj = {\n      query: {},\n      options: {\n        select: ['field 1', 'field 2'],\n        sort: '',\n        populate: '',\n        offset: 0,\n        page: 1,\n        limit: 10,\n        pagination: true,\n        options: {},\n      },\n      isCountOnly: false,\n\n    };\n    return obj;\n  },\n  getObjectId () {\n    return ObjectID();\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/generateFakeDataSequelize/fakeDataType.js",
    "content": "module.exports = {\n  name: ['name', 'firstname', 'middlename', 'lastname'],\n  email: ['mailid', 'mail', 'email', 'emailid', 'gmail'],\n  age: ['age'],\n  gender: ['sex', 'gender'],\n  phone: ['phone', 'mobile', 'contact', 'mobileno', 'phoneno', 'contactno'],\n  price: ['rate', 'price', 'amount', 'totalamount'],\n  address: ['address', 'place', 'addr'],\n  color: ['color', 'colour'],\n  password: ['password', 'pass'],\n  username: ['username', 'uname'],\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/generateFakeDataSequelize/index.js",
    "content": "/* global __basedir */\n/* global  _ */\nconst fs = require('fs');\nconst faker = require('faker');\nconst ObjectID = require('bson-objectid');\nconst RandExp = require('randexp');\nconst fields = require('./fakeDataType');\nconst {\n  REMOVE_FIELD_FOR_FAKE_DATA, SEQUELIZE_DATATYPE_MAPPINGS,\n} = require('../../constants/constant');\n\nfunction readFile (FileName) {\n  return fs.readFileSync(FileName, { encoding: 'utf8' });\n}\nconst mongooseConfiguration = readFile(`${__basedir}/config/mongooseInput.json`);\nconst jsonMongooseConfig = JSON.parse(mongooseConfiguration);\n\nfunction getFdata (data, key) {\n  let fakeData;\n  _.map(data, () => {\n    if (_.has(data, 'match')) {\n      const result = data.match.substring(1, data.match.length - 1);\n      const finalRegexp = new RegExp(result);\n      fakeData = new RandExp(finalRegexp).gen();\n    } else {\n      key = key !== 0 ? key.toLowerCase() : key;\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_STRING_TYPE.includes(data)) {\n        if (fields.name.includes(key.toLowerCase())) {\n          fakeData = faker.name.findName();\n        } else if (fields.gender.includes(key.toLowerCase())) {\n          fakeData = faker.name.gender();\n        } else if (fields.email.includes(key.toLowerCase())) {\n          fakeData = faker.internet.email();\n        } else if (fields.address.includes(key.toLowerCase())) {\n          fakeData = faker.address.streetAddress();\n        } else if (fields.color.includes(key.toLowerCase())) {\n          fakeData = faker.commerce.color();\n        } else if (fields.phone.includes(key.toLowerCase())) {\n          fakeData = faker.phone.phoneNumber();\n        } else if (fields.password.includes(key.toLowerCase())) {\n          fakeData = faker.internet.password();\n        } else if (fields.username.includes(key.toLowerCase())) {\n          fakeData = faker.internet.userName();\n        } else {\n          fakeData = faker.random.word();\n        }\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_NUMBER_TYPE.includes(data)) {\n        if (fields.age.includes(key)) {\n          if (_.has(data, 'min') && !_.has(data, 'max')) {\n            fakeData = faker.datatype.number({ min: data.min });\n          } else if (_.has(data, 'max') && !_.has(data, 'min')) {\n            fakeData = faker.datatype.number({ max: data.maxLength });\n          } else if (_.has(data, 'min') && _.has(data, 'max')) {\n            fakeData = faker.datatype.number({\n              min: data.min,\n              max: data.max,\n            });\n          } else {\n            fakeData = faker.datatype.number(\n              {\n                min: 10,\n                max: 99,\n              },\n            );\n          }\n        } else if (fields.price.includes(key)) {\n          if (_.has(data, 'min') && !_.has(data, 'max')) {\n            fakeData = faker.finance.amount({ min: data.min });\n          } else if (_.has(data, 'max') && !_.has(data, 'min')) {\n            fakeData = faker.finance.amount({ max: data.maxLength });\n          } else if (_.has(data, 'min') && _.has(data, 'max')) {\n            fakeData = faker.finance.amount({\n              min: data.min,\n              max: data.max,\n            });\n          } else {\n            fakeData = faker.datatype.number(\n              {\n                min: 10,\n                max: 99,\n              },\n            );\n          }\n        } else {\n          fakeData = faker.datatype.number(\n            {\n              min: 1,\n              max: 999,\n            },\n          );\n        }\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_DECIMAL_TYPE.includes(data)) {\n        if (fields.age.includes(key)) {\n          fakeData = faker.datatype.float(\n            {\n              min: 10,\n              max: 99,\n            },\n          );\n        } else if (fields.price.includes(key)) {\n          fakeData = faker.finance.amount();\n        } else {\n          fakeData = faker.datatype.float(\n            {\n              min: 1,\n              max: 999,\n            },\n          );\n        }\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_UUID_TYPE.includes(data)) {\n        fakeData = faker.datatype.uuid();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_DATE_TYPE.includes(data)) {\n        fakeData = faker.date.future();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_BLOB_TYPE.includes(data)) {\n        fakeData = faker.datatype.string();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_JSON_TYPE.includes(data)) {\n        fakeData = faker.datatype.json();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_ARRAY_TYPE.includes(data)) {\n        fakeData = faker.datatype.array();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_GEOMETRY_TYPE.includes(data)) {\n        fakeData = faker.datatype.float();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_RANGE_TYPE.includes(data)) {\n        fakeData = faker.datatype.number();\n      }\n      if (SEQUELIZE_DATATYPE_MAPPINGS.SEQUELIZE_BOOLEAN_TYPE.includes(data)) {\n        fakeData = faker.datatype.boolean();\n      }\n    }\n  });\n  return fakeData;\n}\nmodule.exports = {\n  validSchema (input) {\n    try {\n      _.map(input, (modelValue, model) => {\n        _.map(modelValue, (modelObjValue, modelObjKey) => {\n          if (!REMOVE_FIELD_FOR_FAKE_DATA.includes(modelObjKey)) {\n            if (typeof input[model][modelObjKey] === 'object' && !Array.isArray(input[model][modelObjKey])) {\n              const item = input[model][modelObjKey];\n              const data = this.validSchemaObject(item, modelObjKey);\n              input[model][modelObjKey] = data;\n            } else if (Array.isArray(modelObjValue)) {\n              const item = input[model][modelObjKey];\n              const data = this.validSchemaObject(item, modelObjKey);\n              input[model][modelObjKey] = data;\n            } else {\n              const data = getFdata(modelObjValue, modelObjKey);\n              input[model][modelObjKey] = data;\n            }\n          } else {\n            delete input[model][modelObjKey];\n          }\n        });\n        input[model].id = ObjectID();\n      });\n      // console.log(input);\n      return input;\n    } catch (error) {\n      throw new Error(error);\n    }\n  },\n  validSchemaObject (item, modelObjKey) {\n    let fakeData;\n    const possibleKeys = Object.keys(jsonMongooseConfig.model.key);\n    _.map(item, (data, key) => {\n      if (possibleKeys.includes(key)) {\n        delete item[key];\n        switch (key) {\n        case 'type':\n          // console.log(modelObjKey)\n          fakeData = getFdata(data, modelObjKey);\n          break;\n        case 'ref':\n          break;\n        case 'index':\n        case 'unique':\n        case 'alias':\n        case 'lowercase':\n        case 'trim':\n        case 'required':\n        case 'immutable':\n        case 'sparse':\n        case 'minLength':\n        case 'maxLength':\n        case 'of':\n          break;\n        case 'default':\n          break;\n        case 'enum':\n          break;\n        case 'validate':\n          break;\n        case 'get':\n          break;\n        case 'set':\n          break;\n        case 'transform':\n          break;\n        case 'match':\n          break;\n        case 'populate':\n          break;\n        case 'min':\n          break;\n        case 'max':\n          break;\n        default:\n          break;\n        }\n      } else if (typeof data === 'object' && !Array.isArray(data)) {\n        /*\n         * console.log(key);\n         * console.log(data)\n         */\n        let fData;\n        if (typeof key === 'number') {\n          fData = this.validSchemaObject(data, modelObjKey);\n        } else {\n          fData = this.validSchemaObject(data, key);\n        }\n\n        item[key] = fData;\n        fakeData = item;\n      } else if (Array.isArray(data)) {\n        const fData = this.validSchemaObject(data, key);\n        item[key] = fData;\n        fakeData = item;\n      } else if (jsonMongooseConfig.model.key.type.includes(data)) {\n        /*\n         * if (typeof key === \"number\") {\n         *     let fData = this.validSchemaObject(data, key);\n         *     item[key] = fData;\n         *     fakeData = item;\n         * } else {\n         *     let fData = this.validSchemaObject(data, key);\n         *     item[key] = fData;\n         *     fakeData = item;\n         * }\n         */\n        const fData = getFdata(data, key);\n        // console.log(fData,\" ---------fdata\")\n        item[key] = fData;\n        fakeData = item;\n      } else {\n        /*\n         * console.log(key, \" \", data)\n         * console.log(\"not any fake to generate.......\")\n         */\n      }\n    });\n    return fakeData;\n  },\n  getFindAllObject () {\n    const obj = {\n      query: {},\n      options: {\n        select: ['field 1', 'field 2'],\n        collation: '',\n        sort: '',\n        populate: '',\n        projection: '',\n        lean: false,\n        leanWithId: true,\n        offset: 0,\n        page: 1,\n        limit: 10,\n        pagination: true,\n        useEstimatedCount: false,\n        useCustomCountFn: false,\n        forceCountFn: false,\n        read: {},\n        options: {},\n      },\n      isCountOnly: false,\n\n    };\n    return obj;\n  },\n  getObjectId () {\n    return ObjectID();\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/getDeleteDependency.js",
    "content": "const {\n  isEmpty, uniqWith, isEqual,\n} = require('lodash');\nconst { SQL_RELATIONSHIP_TYPE } = require('../constants/constant');\n\n/* eslint-disable */\nmodule.exports = {\n  getDeleteDependency(schema) {\n    const obj = {};\n    let arr = [];\n    for (const keyOnly in schema) {\n      const myKey = `@@${keyOnly}@@`;\n      if (schema.hasOwnProperty(keyOnly)) {\n        for (const key in schema) {\n          for (const insideKey in schema[key]) {\n            if (schema[key][insideKey].ref === myKey) {\n              const objKey = {};\n              objKey.model = key;\n              objKey.refId = insideKey;\n              arr.push(objKey);\n            }\n            obj[keyOnly] = arr;\n          }\n        }\n      }\n      arr = [];\n    }\n    return obj;\n  },\n\n  getSQLRelationshipDependencies(schema) {\n    const obj = {};\n    let arr = [];\n    for (const keyOnly in schema) {\n      if (schema.hasOwnProperty(keyOnly)) {\n        for (const key in schema) {\n          for (const insideKey in schema[key]) {\n            if (schema[key][insideKey].ref === keyOnly) {\n              const objKey = {};\n              objKey.model = key;\n              schema[key][insideKey].hasOwnProperty('refAttribute') ? objKey.refId = insideKey : objKey.refId = '';\n              schema[key][insideKey].hasOwnProperty('relType') ? objKey.relType = schema[key][insideKey]['relType'] : objKey.relType = 2;\n              schema[key][insideKey].hasOwnProperty('refAttribute') ? objKey.refAttribute = schema[key][insideKey]['refAttribute'] : objKey.refAttribute = null;\n              if (schema[key][insideKey].hasOwnProperty('relType')) {\n                if (schema[key][insideKey]['relType'] !== null) {\n                  if (schema[key][insideKey]['relType'] === SQL_RELATIONSHIP_TYPE.HAS_ONE) {\n                    objKey.relType = 'HAS_ONE';\n                  } else if (schema[key][insideKey]['relType'] === SQL_RELATIONSHIP_TYPE.HAS_MANY) {\n                    objKey.relType = 'HAS_MANY';\n                  } else {\n                    objKey.relType = 'HAS_MANY';\n                  }\n                } else {\n                  objKey.relType = 'HAS_MANY';\n                }\n              }\n              if (objKey.refAttribute !== null) {\n                arr.push(objKey);\n              }\n\n            }\n            obj[keyOnly] = arr;\n          }\n        }\n      }\n      arr = [];\n    }\n    return obj;\n  },\n\n  // not using currently, but it will be useful when we need all the dependent models of any model\n  getDeleteDependency2(modelList) {\n    const obj = {}\n    for (const modelName in modelList) {\n      const mainRefKey = `@@${modelName}@@`;\n      const refList = getChildDeleteDependency(modelList, mainRefKey, modelName)\n      obj[modelName] = refList\n    }\n    return obj;\n  },\n\n  getSQLUniqueIndexesForRelationship(models) {\n    let uniqueIndexColumns = {};\n    if (Object.keys(models).length) {\n      Object.keys(models).forEach((d) => {\n        if (Object.keys(models[d]).length) {\n          Object.keys(models[d]).forEach((attributes) => {\n            if (\n              models[d][attributes].ref !== undefined &&\n              models[d][attributes].refAttribute !== undefined &&\n              models[d][attributes].relType !== undefined\n            ) {\n              const refTable = models[d][attributes].ref;\n              const refAttribute = models[d][attributes].refAttribute;\n              if (models[refTable][refAttribute] !== undefined) {\n                if (!models[refTable][refAttribute].hasOwnProperty('primary')) {\n                  if (!models[refTable][refAttribute].hasOwnProperty('unique')) {\n                    models[refTable][refAttribute].unique = true;\n                    Object.assign(uniqueIndexColumns, { [refTable]: refAttribute });\n                  }\n                }\n              }\n            }\n          });\n        }\n      });\n    }\n    return uniqueIndexColumns;\n  }\n\n};\n\nfunction getChildDeleteDependency(modelList, refKey, currentModel) {\n  let arr = []\n  for (const model in modelList) {\n    for (const field in modelList[model]) {\n      if (modelList[model][field].ref === refKey) {\n        const obj1 = {}\n        obj1.model = model\n        obj1.refId = field\n        obj1.parentModel = currentModel\n        arr.push(obj1)\n        const nestedRef = getChildDeleteDependency(modelList, `@@${model}@@`, model)\n        if (!isEmpty(nestedRef)) {\n          arr = arr.concat(nestedRef)\n        }\n      }\n    }\n  }\n  return uniqWith(arr, isEqual)\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/makeCustomPolicy.js",
    "content": "const { forEach } = require('lodash');\nconst writeOperations = require('../writeOperations');\n\nmodule.exports = {\n  makeIndividualPolicy (policies, middlewarePath) {\n    const returnPolicy = {};\n    forEach(policies, (value, i) => {\n      const policy = writeOperations.loadTemplate(`${middlewarePath}/sampleMiddleware.js`);\n      policy.locals.POLICY = value;\n      returnPolicy[i] = policy;\n    });\n    return returnPolicy;\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/postman/generate-postman-collection.js",
    "content": "const uuid4 = require('uuid').v4;\nconst {\n  clone, isEmpty,\n} = require('lodash');\n\nconst renameKey = (object, key, newKey) => {\n  const clonedObj = clone(object);\n  const targetKey = clonedObj[key];\n  delete clonedObj[key];\n  clonedObj[newKey] = targetKey;\n  return clonedObj;\n};\nconst postman = require('postman-collection');\nglobal._ = require('lodash');\n\nmodule.exports = {\n  async createCollectionV2_0 (info, platform = true) {\n    const mainObj = {};\n    const infoObj = {};\n\n    const mainItem = [];\n    // Project Details\n    infoObj.name = info.project.name;\n    infoObj._postman_id = uuid4();\n    infoObj.description = info.project.description;\n    infoObj.schema = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json';\n\n    const body = {\n      mode: '',\n      raw: '',\n    };\n    const header = [\n      {\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n      },\n    ];\n    body.mode = 'raw';\n    body.raw = '{}';\n\n    if (platform) {\n      info.item.forEach((e) => {\n        const modelItem = [];\n        e.item.forEach((ej) => {\n          const item = [];\n          ej.request?.forEach((r) => {\n            const request = {\n              url: '',\n              method: '',\n              header: null,\n              body: null,\n              description: '',\n              auth: {},\n            };\n            const itemData = {\n              name: '',\n              request: null,\n              response: null,\n              _postman_isSubFolder: true,\n            };\n            request.url = r.url;\n            request.method = r.method;\n            request.header = r.header ? r.header : header;\n            request.body = r.body ? r.body : body;\n            request.auth = r.auth || {};\n\n            // set Item Data\n            itemData.name = r.name;\n\n            itemData.request = request;\n            itemData.response = r.response;\n            item.push(itemData);\n          });\n\n          const modelItemData = {\n            name: null,\n            description: null,\n            item: null,\n          };\n          modelItemData.name = ej.name;\n          modelItemData.description = ej.desc;\n          modelItemData.item = item;\n          modelItem.push(modelItemData);\n        });\n\n        const mainItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        mainItemData.name = e.name;\n        mainItemData.description = e.description;\n        mainItemData.item = modelItem;\n\n        // main Item Data push into main Item\n\n        mainItem.push(mainItemData);\n      });\n    } else {\n      info.item.forEach((e) => {\n        const item = [];\n        e.request.forEach((r) => {\n          const responseObject = {};\n          const request = {\n            url: '',\n            method: '',\n            header: null,\n            body: null,\n            description: '',\n          };\n          const itemData = {\n            name: '',\n            request: null,\n            response: null,\n          };\n          request.url = r.url;\n          request.method = r.method;\n          request.header = header;\n          request.body = r.body ? r.body : body;\n\n          // set Item Data\n          itemData.name = r.name;\n\n          itemData.request = request;\n          responseObject.name = `${r.name}_response`;\n          responseObject.originalRequest = {\n            method: r.method,\n            header: r.header ? r.header : header,\n            url: { raw: r.url },\n          };\n          responseObject.status = 'OK';\n          responseObject.code = 200;\n          responseObject._postman_previewlanguage = 'json';\n          if (Object.keys(r.body ?? body).length) {\n            if (Object.keys(r.body ?? body).includes('raw')) {\n              if (r.body !== undefined) {\n                delete r.body.mode;\n              }\n              if (body.mode) {\n                delete body.mode;\n              }\n            }\n          }\n          responseObject.body = r.body ? r.body : body;\n          responseObject.body = renameKey(responseObject.body, 'raw', 'body');\n          responseObject.body = responseObject.body.body;\n          itemData.response = [responseObject];\n          item.push(itemData);\n        });\n\n        const modelItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        modelItemData.name = e.name;\n        modelItemData.description = e.desc;\n        modelItemData.item = item;\n        mainItem.push(modelItemData);\n      });\n    }\n    // main object\n    mainObj.info = infoObj;\n    mainObj.item = mainItem;\n\n    // console.log(JSON.stringify(mainObj))\n    return JSON.stringify(mainObj, null, 2);\n    // for request end\n  },\n  async createCollectionV2_1 (info, platform = true) {\n    const mainObj = {};\n    const infoObj = {};\n\n    const mainItem = [];\n    // Project Details\n    infoObj.name = info.project.name;\n    infoObj._postman_id = uuid4();\n    infoObj.description = info.project.description;\n    infoObj.schema = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json';\n\n    const body = {\n      mode: '',\n      raw: '',\n    };\n    const header = [\n      {\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n      },\n    ];\n    body.mode = 'raw';\n    body.raw = '{}';\n\n    if (platform) {\n      info.item.forEach((e) => {\n        const modelItem = [];\n        e.item.forEach((ej) => {\n          const item = [];\n          ej.request?.forEach((r) => {\n            const request = {\n              url: '',\n              method: '',\n              header: null,\n              body: null,\n              description: '',\n              auth: {},\n            };\n            const itemData = {\n              name: '',\n              request: null,\n              response: null,\n              _postman_isSubFolder: true,\n            };\n            request.url = postman.Url.parse(r.url);\n            request.method = r.method;\n            request.header = r.header ? r.header : header;\n            request.auth = r.auth || {};\n            // if (r.auth && r.auth.type === 'bearer') {\n\n            // }\n\n            // request.body = r.body ? r.body : body;\n            if (r.body) {\n              if (isEmpty(r.body.raw)) {\n                r.body.raw = '{}';\n              }\n              request.body = r.body;\n            } else {\n              if (isEmpty(body.raw)) {\n                body.raw = '{}';\n              }\n              request.body = body;\n            }\n\n            // set Item Data\n            itemData.name = r.name;\n\n            itemData.request = request;\n            itemData.response = r.response;\n            if (itemData.response?.length) {\n              itemData.response[0].originalRequest.url = postman.Url.parse(r.response[0]?.originalRequest.url.raw);\n            }\n            item.push(itemData);\n          });\n\n          const modelItemData = {\n            name: null,\n            description: null,\n            item: null,\n          };\n          modelItemData.name = ej.name;\n          modelItemData.description = ej.desc;\n          modelItemData.item = item;\n          modelItem.push(modelItemData);\n        });\n\n        const mainItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        mainItemData.name = e.name;\n        mainItemData.description = e.description;\n        mainItemData.item = modelItem;\n\n        // main Item Data push into main Item\n\n        mainItem.push(mainItemData);\n      });\n    } else {\n      info.item.forEach((e) => {\n        const item = [];\n        e.request.forEach((r) => {\n          const request = {\n            url: '',\n            method: '',\n            header: null,\n            body: null,\n            description: '',\n          };\n          const itemData = {\n            name: '',\n            request: null,\n            response: null,\n          };\n          request.url = postman.Url.parse(r.url);\n          request.method = r.method;\n          request.header = header;\n          // request.body = r.body ? r.body : body;\n          if (r.body) {\n            if (isEmpty(r.body.raw)) {\n              r.body.raw = '{}';\n            }\n            request.body = r.body;\n          } else {\n            if (isEmpty(body.raw)) {\n              body.raw = '{}';\n            }\n            request.body = body;\n          }\n          // set Item Data\n          itemData.name = r.name;\n\n          itemData.request = request;\n          itemData.response = r.response;\n          item.push(itemData);\n        });\n\n        const modelItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        modelItemData.name = e.name;\n        modelItemData.description = e.desc;\n        modelItemData.item = item;\n        mainItem.push(modelItemData);\n      });\n    }\n    // main object\n    mainObj.info = infoObj;\n    mainObj.item = mainItem;\n\n    // console.log(JSON.stringify(mainObj))\n    return JSON.stringify(mainObj, null, 2);\n    // for request end\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/postman/index.js",
    "content": "/* eslint-disable */\n/* global MESSAGE, _ */\nconst uuid4 = require('uuid').v4;\nconst fakeData = require('../generateFakeData/index');\nconst { APIS } = require('../../constants/constant');\nconst { forEach, values, isEmpty, create, keys } = require('lodash');\nconst fakerStatic = require('faker');\nlet dayjs = require('dayjs');\nasync function getPlatformFromSchemaDynamic(jsonData, modelConfig, model) {\n    const platformNames = jsonData.authentication.platform;\n    const platformWiseModelSchema = {}\n    forEach(platformNames, (platformName) => {\n        platformWiseModelSchema[platformName] = (modelConfig[platformName] ? modelConfig[platformName][model] : undefined)\n    })\n    return platformWiseModelSchema\n}\nasync function getPostmanCollectionsForLogin(platformStr, userModel, loginWith, fakeModel, port, addDataFormate, value, modelPrivateAttribute, formateModel) {\n    if (addDataFormate) {\n        let boolKeys = []; let dateKeys = [];\n        if (addDataFormate['allModels_data_format']) {\n            for (let index in value) {\n                if (value[index].type === \"Boolean\") {\n                    boolKeys.push(index);\n                } if (value[index].type === \"Date\") {\n                    dateKeys.push(index);\n                }\n            }\n            if (addDataFormate[formateModel]) {\n                Array.prototype.push.apply(addDataFormate[formateModel], addDataFormate['allModels_data_format']);\n            } else {\n                addDataFormate[formateModel] = addDataFormate['allModels_data_format'];\n            }\n        }\n        boolKeys = [];\n        dateKeys = [];\n    }\n    let data = {\n        username: 'username',\n        password: 'password',\n    };\n    const changePass = {\n        oldPassword: 'OldPassword',\n        newPassword: 'NewPassword',\n    };\n    const objectId = fakeData.getObjectId();\n    const platformObj = {\n        name: 'login',\n        desc: `${platformStr} Login`,\n        request: [],\n    };\n    let requestObj = {};\n    let body = {};\n    body.mode = 'raw';\n    requestObj.name = `Login in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/login`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    let resObject = _.cloneDeep(fakeModel[userModel]);\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: objectId });\n    }\n    if (!('loginRetryLimit' in resObject)) {\n        Object.assign(resObject, { loginRetryLimit: 0 });\n    }\n    if (!('token' in resObject)) {\n        Object.assign(resObject, { token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMWRlZDVjMGFjMjAxMmFjMDI4ODkxZiIsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE2MjkzNTEyNzAsImV4cCI6MTYyOTk1MTI3MH0.BJ-WKjNYeFDQ4pn8kfli5gwn6GLz_c3voFht20Agj9k\" });\n    }\n    Object.assign(resObject,\n        {\n            createdAt: fakerStatic.date.future(),\n            updatedAt: fakerStatic.date.future(),\n            isDeleted: false,\n            isActive: true\n        });\n    if (addDataFormate && addDataFormate[formateModel]) {\n        resObject = await filterResponseBasedOnFormate(addDataFormate[formateModel], resObject);\n    }\n\n    if (Object.keys(modelPrivateAttribute).length) {\n        resObject = await removePrivateAttibutesFromResponse(resObject, modelPrivateAttribute)\n    }\n    let jsonData = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Login Successful\",\n        \"data\": resObject\n    };\n    let responseObject = {};\n    responseObject.name = `Login in ${platformStr}_response`;\n    responseObject.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObject.status = 'OK';\n    responseObject.code = 200;\n    responseObject._postman_previewlanguage = 'json';\n    responseObject.body = JSON.stringify(jsonData, undefined, 2);\n    responseObject.header = [\n        { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n    ];\n    responseObject.cookie = [];\n    requestObj.response = [responseObject];\n    platformObj.request.push(requestObj);\n    requestObj = {};\n    body = {};\n    body.mode = \"raw\"\n    requestObj.name = `Register User in ${platformStr}`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/register`;\n    body.raw = JSON.stringify(fakeModel[userModel], undefined, 2);\n    requestObj.body = body;\n    resObject = _.cloneDeep(fakeModel[userModel]);\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: objectId });\n    }\n    if (!('loginRetryLimit' in resObject)) {\n        Object.assign(resObject, { loginRetryLimit: 0 });\n    }\n    Object.assign(resObject,\n        {\n            createdAt: fakerStatic.date.future(),\n            updatedAt: fakerStatic.date.future(),\n            isDeleted: false,\n            isActive: true\n        });\n    if (addDataFormate && addDataFormate[formateModel]) {\n        resObject = await filterResponseBasedOnFormate(addDataFormate[formateModel], resObject);\n    }\n    if (addDataFormate && addDataFormate[formateModel]) {\n        resObject = await filterResponseBasedOnFormate(addDataFormate[formateModel], resObject);\n    }\n\n    if (Object.keys(modelPrivateAttribute).length) {\n        resObject = await removePrivateAttibutesFromResponse(resObject, modelPrivateAttribute)\n    }\n    jsonData = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Your request is successfully executed\",\n        \"data\": resObject\n    };\n    responseObject = {};\n    responseObject.name = `Register User in ${platformStr}_response`;\n    responseObject.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObject.status = 'OK';\n    responseObject.code = 200;\n    responseObject._postman_previewlanguage = 'json';\n    responseObject.body = JSON.stringify(jsonData, undefined, 2);\n    responseObject.header = [\n        { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n    ];\n    responseObject.cookie = [];\n    requestObj.response = [responseObject];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Forgot Password in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/forgot-password`;\n    body.raw = JSON.stringify({\n        email: 'yourmail@gmail.com',\n    }, undefined, 2);\n    requestObj.body = body;\n    const jsonDataForgetPassword = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"otp successfully send to your email.\",\n        \"data\": {}\n    };\n    const responseObjectForgetPassword = {};\n    responseObjectForgetPassword.name = `Forgot Password in ${platformStr}_response`;\n    responseObjectForgetPassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObjectForgetPassword.status = 'OK';\n    responseObjectForgetPassword.code = 200;\n    responseObjectForgetPassword._postman_previewlanguage = 'json';\n    responseObjectForgetPassword.body = JSON.stringify(jsonDataForgetPassword, undefined, 2);\n    responseObjectForgetPassword.header = [];\n    responseObjectForgetPassword.cookie = [];\n    requestObj.response = [responseObjectForgetPassword];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Validate OTP in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/validate-otp`;\n    body.raw = JSON.stringify({\n        otp: '5898',\n    }, undefined, 2);\n    requestObj.body = body;\n    const validateOTPResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Invalid OTP\",\n        \"data\": {}\n    };\n    const responseObjectValidateOTP = {};\n    responseObjectValidateOTP.name = `Validate OTP in ${platformStr}_response`;\n    responseObjectValidateOTP.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObjectValidateOTP.status = 'OK';\n    responseObjectValidateOTP.code = 200;\n    responseObjectValidateOTP._postman_previewlanguage = 'json';\n    responseObjectValidateOTP.body = JSON.stringify(validateOTPResponse, undefined, 2);\n    responseObjectValidateOTP.header = [];\n    responseObjectValidateOTP.cookie = [];\n    requestObj.response = [responseObjectValidateOTP];\n\n    platformObj.request.push(requestObj);\n\n    const header = [];\n    const security = {\n        \"type\": \"bearer\",\n        \"bearer\": {\n            \"token\": \"{{token}}\"\n        }\n    }\n    header.push({\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n    });\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Logout in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/logout`;\n    body.raw = JSON.stringify({});\n    requestObj.body = body;\n    requestObj.header = header;\n    requestObj.auth = security;\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Change Password in ${platformStr}`;\n    requestObj.method = 'PUT';\n    requestObj.url = platformStr.toLowerCase() !== 'admin'\n        ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${userModel.toLowerCase()}/change-password`\n        : `{{url}}/${platformStr.toLowerCase()}/${userModel.toLowerCase()}/change-password`;\n    body.raw = JSON.stringify(changePass, undefined, 2);\n    requestObj.body = body;\n    requestObj.header = header;\n    requestObj.auth = security;\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: objectId });\n    }\n    if (!('loginTry' in resObject)) {\n        Object.assign(resObject, { loginTry: 0 });\n    }\n    const changePasswordResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Password changed successfully\",\n        \"data\": {}\n    };\n    const responseForChangePassword = {};\n    responseForChangePassword.name = `Change Password in ${platformStr}_response`;\n    responseForChangePassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseForChangePassword.status = 'OK';\n    responseForChangePassword.code = 200;\n    responseForChangePassword._postman_previewlanguage = 'json';\n    responseForChangePassword.body = JSON.stringify(changePasswordResponse, undefined, 2);\n    responseForChangePassword.header = [];\n    responseForChangePassword.cookie = [];\n    requestObj.response = [responseForChangePassword];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Reset password in ${platformStr}`;\n    requestObj.method = 'PUT';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/reset-password`;\n    body.raw = JSON.stringify({\n        code: '5898',\n        newPassword: 'yourPassword',\n    }, undefined, 2);\n    requestObj.body = body;\n    const resetPasswordResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Password reset successfully\",\n        \"data\": {}\n    };\n    const responseForResetPassword = {};\n    responseForResetPassword.name = `Reset password in ${platformStr}_response~`;\n    responseForResetPassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseForResetPassword.status = 'OK';\n    responseForResetPassword.code = 200;\n    responseForResetPassword._postman_previewlanguage = 'json';\n    responseForResetPassword.body = JSON.stringify(resetPasswordResponse, undefined, 2);\n    responseForResetPassword.header = [];\n    responseForResetPassword.cookie = [];\n    requestObj.response = [responseForResetPassword];\n    platformObj.request.push(requestObj);\n\n    return platformObj;\n}\nasync function getPostmanCollectionForSocialLogin(platform, details) {\n    const platformObj = {\n        name: 'Social Login',\n        desc: 'Login Through Social Accounts',\n        request: [],\n    };\n    let requestObj = {};\n    let body = {};\n    for (let i = 0; i < details.length; i += 1) {\n        requestObj = {};\n        body = {};\n        body.mode = 'raw';\n        requestObj.name = `Social Login through ${details[i].toLowerCase()}`;\n        requestObj.method = 'GET';\n        requestObj.url = `{{url}}/${platform.toLowerCase()}/auth/${details[i].toLowerCase()}`;\n        body.raw = '{}';\n        requestObj.body = body;\n        platformObj.request.push(requestObj);\n    }\n\n    return platformObj;\n}\nasync function setCustomRoutes(customObj) {\n    try {\n        let newPlatform = {\n            name: \"common\",\n            description: \"Common routes\",\n            item: []\n        }\n        const port = customObj.port;\n        if (customObj.notification.length) {\n            let platformObj = {\n                name: `webNotificationsRoutes`,\n                desc: \"\",\n                request: []\n            }\n            let requestObj = {}\n            let body = {}\n            body.mode = \"raw\"\n            requestObj.name = `create Notification`;\n            requestObj.method = `POST`\n            requestObj.url = `{{url}}/common/api/v1/notification/create`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n\n            requestObj = {}\n            body = {}\n\n            body.mode = \"raw\"\n            requestObj.name = `Mark as read`;\n            requestObj.method = `PUT`\n            requestObj.url = `{{url}}/common/api/v1/notification/markAsRead`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n\n            requestObj = {}\n            body = {}\n\n            body.mode = \"raw\"\n            requestObj.name = `Mark as Visited`;\n            requestObj.method = `PUT`\n            requestObj.url = `{{url}}/common/api/v1/notification/markAsVisited`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n            newPlatform.item.push(platformObj);\n        }\n        // if (!_.isEmpty(customObj.fileObj)) {\n        //     newPlatform.item.push(await getPostmanCollectionForFileUpload(\"common\", customObj.fileObj, customObj.port));\n        // }\n\n        return newPlatform;\n    } catch (error) {\n        throw error;\n    }\n}\nasync function getPostmanCollections(platformStr, key, platform, data = {}, isRole = false, isAuth, port, currentPostmanCollectionDetails = {}, addDataFormate, value, modelPrivateAttribute) {\n    if (addDataFormate) {\n        let boolKeys = []; let dateKeys = [];\n        if (addDataFormate['allModels_data_format']) {\n            for (let index in value) {\n                if (value[index].type === \"Boolean\") {\n                    boolKeys.push(index);\n                } if (value[index].type === \"Date\") {\n                    dateKeys.push(index);\n                }\n            }\n            if (addDataFormate[key]) {\n                Array.prototype.push.apply(addDataFormate[key], addDataFormate['allModels_data_format']);\n            } else {\n                addDataFormate[key] = addDataFormate['allModels_data_format'];\n            }\n        }\n        boolKeys = [];\n        dateKeys = [];\n    }\n\n    let platformObj = {\n        name: key,\n        desc: `${key} Model APIs`,\n        request: [],\n    };\n\n    const id = \":id\";\n    delete data[key].id;\n    if (isRole) {\n        data[key].role = 1;\n    }\n\n    for (let [api, value] of Object.entries(platform)) {\n        if (APIS.includes(api) && value.selected) {\n            let requestObj = {};\n            let body = {};\n            const header = [];\n            header.push({\n                key: 'Content-Type',\n                value: 'application/json',\n                description: '',\n            });\n            let security = {};\n            if (value.isAuth && isAuth) {\n                security = {\n                    \"type\": \"bearer\",\n                    \"bearer\": {\n                        \"token\": \"{{token}}\"\n                    }\n                }\n            }\n            if (api === 'create') {\n                let body = {};\n                body.mode = 'raw';\n                requestObj.name = `add${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin'\n                    ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/create`\n                    : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/create`;\n                body.raw = JSON.stringify(data[key], undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `add${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let createBody = _.cloneDeep(JSON.parse(body.raw));\n                const id = fakeData.getObjectId();\n                if (!('id' in createBody)) {\n                    Object.assign(createBody, { id: id });\n                }\n                Object.assign(createBody,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    createBody = await filterResponseBasedOnFormate(addDataFormate[key], createBody);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    createBody = await removePrivateAttibutesFromResponse(createBody, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(createBody).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete createBody[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": createBody\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'createBulk') {\n                requestObj.name = `insertBulk${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/addBulk` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/addBulk`;\n                const arr = [];\n                const objBulk = {};\n                arr.push(data[key]);\n                objBulk.data = arr;\n                body.mode = 'raw';\n                body.raw = JSON.stringify(objBulk, undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `insertBulk${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let createBody = _.cloneDeep(data[key]);\n                const id = fakeData.getObjectId();\n                if (!('id' in createBody)) {\n                    Object.assign(createBody, { id: id });\n                }\n                Object.assign(createBody,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    createBody = await filterResponseBasedOnFormate(addDataFormate[key], createBody);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    createBody = await removePrivateAttibutesFromResponse(createBody, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(createBody).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete createBody[keys];\n                        }\n                    });\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": [createBody]\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'findAll') {\n                let findAllFakeobj = fakeData.getFindAllObject();\n                requestObj.name = `findAll${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/list` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/list`;\n                body.mode = 'raw';\n                body.raw = JSON.stringify(findAllFakeobj, undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `findAll${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                const id = fakeData.getObjectId();\n                let responseDataForFindAll = _.cloneDeep(data[key]);\n                if (!('id' in responseDataForFindAll)) {\n                    Object.assign(responseDataForFindAll, { id: id });\n                }\n                Object.assign(responseDataForFindAll,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    responseDataForFindAll = await filterResponseBasedOnFormate(addDataFormate[key], responseDataForFindAll);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    responseDataForFindAll = await removePrivateAttibutesFromResponse(responseDataForFindAll, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(responseDataForFindAll).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete responseDataForFindAll[keys];\n                        }\n                    })\n                }\n                let findAllObject = {\n                    \"data\": [responseDataForFindAll],\n                    \"paginator\": {\n                        \"itemCount\": 1,\n                        \"offset\": 0,\n                        \"perPage\": 10,\n                        \"pageCount\": 1,\n                        \"currentPage\": 1,\n                        \"slNo\": 1,\n                        \"hasPrevPage\": false,\n                        \"hasNextPage\": false,\n                        \"prev\": null,\n                        \"next\": null\n                    }\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": findAllObject\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'count') {\n                requestObj.name = `get${key}Count`;\n                requestObj.method = 'POST',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/count` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/count`;\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ where: { isActive: true } }, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `get${key}Count_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"totalRecords\": 10\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'findById') {\n                requestObj.name = `get${key}`;\n                requestObj.method = 'GET',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/${id}` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/${id}`;\n                const responseObject = {};\n                responseObject.name = `get${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'GET',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseForGet = _.cloneDeep(data[key]);\n                const id_ = fakeData.getObjectId();\n                if (!('id' in responseForGet)) {\n                    Object.assign(responseForGet, { id: id_ });\n                }\n                Object.assign(responseForGet,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    responseForGet = await filterResponseBasedOnFormate(addDataFormate[key], responseForGet);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    responseForGet = await removePrivateAttibutesFromResponse(responseForGet, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(responseForGet).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete responseForGet[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": responseForGet\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'update') {\n                body.mode = 'raw';\n                requestObj.name = `update${key}`;\n                requestObj.method = 'PUT';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/update/${id}` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/update/${id}`;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                body.raw = JSON.stringify(data[key], undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `update${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let dataForUpdate = _.cloneDeep(data[key]);\n                const id1 = fakeData.getObjectId();\n                let bodyRawData = dataForUpdate;\n                if (!('id' in dataForUpdate)) {\n                    Object.assign(dataForUpdate, { id: id1 });\n                }\n                Object.assign(dataForUpdate,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    dataForUpdate = await filterResponseBasedOnFormate(addDataFormate[key], dataForUpdate);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    dataForUpdate = await removePrivateAttibutesFromResponse(dataForUpdate, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(dataForUpdate).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete dataForUpdate[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": dataForUpdate\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'bulkUpdate') {\n                requestObj.name = `updateBulk${key}`;\n                requestObj.method = 'PUT',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/updateBulk` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/updateBulk`;\n                const objUpdateBulk = {\n                    filter: {\n                        isActive: true,\n                    },\n                    data: {\n                        isDeleted: false,\n                    },\n                };\n                body.mode = 'raw';\n                body.raw = JSON.stringify(objUpdateBulk, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `updateBulk${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                const id = fakeData.getObjectId();\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: id });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"acknowledged\": true,\n                        \"modifiedCount\": 59,\n                        \"upsertedId\": null,\n                        \"upsertedCount\": 0,\n                        \"matchedCount\": 59\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'partialUpdate') {\n                const pBody = {};\n                pBody.isActive = true;\n                pBody.isDeleted = false;\n                body.mode = 'raw';\n                requestObj.name = `partialupdate${key}`;\n                requestObj.method = 'PUT';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/partial-update/${id}` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/partial-update/${id}`;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                body.raw = JSON.stringify(pBody, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `partialupdate${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                const id1 = fakeData.getObjectId();\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: id1 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": bodyRawData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'softDelete') {\n                requestObj.name = `softDelete${key}`;\n                requestObj.method = 'PUT',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/softDelete/${id}` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/softDelete/${id}`;\n                const responseObject = {};\n                responseObject.name = `softDelete${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"acknowledged\": true,\n                        \"modifiedCount\": 1,\n                        \"upsertedId\": null,\n                        \"upsertedCount\": 0,\n                        \"matchedCount\": 1\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'delete') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ isWarning: true }, undefined, 2);\n                requestObj.name = `delete${key}`;\n                requestObj.method = 'DELETE',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.body = body;\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/delete/${id}` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/delete/${id}`;\n                const responseObject = {};\n                responseObject.name = `delete${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'DELETE',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"n\": 1,\n                        \"ok\": 1,\n                        \"deletedCount\": 1\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n\n            }\n            if (api === 'deleteMany') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ isWarning: true, ids: [id] }, undefined, 2);\n                requestObj.name = `deleteMany${key}`;\n                requestObj.method = 'POST';\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/deleteMany` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/deleteMany`;\n                const responseObject = {};\n                responseObject.name = `deleteMany${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'DELETE',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"n\": 2,\n                        \"ok\": 1,\n                        \"deletedCount\": 2\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'softDeleteMany') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ ids: [id] }, undefined, 2);\n                requestObj.name = `softDeleteMany${key}`;\n                requestObj.method = 'PUT';\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n                    `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/softDeleteMany` :\n                    `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/softDeleteMany`;\n                const responseObject = {};\n                responseObject.name = `softDeleteMany${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"acknowledged\": true,\n                        \"modifiedCount\": 1,\n                        \"upsertedId\": null,\n                        \"upsertedCount\": 0,\n                        \"matchedCount\": 1\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [\n                    { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n                ];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n        }\n\n    }\n    if (isAuth && isRole && _.includes(platformStr)) {\n        let requestObj = {};\n        let body = {};\n        const header = [];\n        header.push({\n            key: 'Content-Type',\n            value: 'application/json',\n            description: '',\n        });\n        let security = {\n            \"type\": \"bearer\",\n            \"bearer\": {\n                \"token\": \"{{token}}\"\n            }\n        }\n\n        body.mode = 'raw';\n        requestObj.name = `updateProfile`;\n        requestObj.method = 'PUT';\n        requestObj.url = platformStr.toLowerCase() !== 'admin' ?\n            `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/update-profile` :\n            `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/update-profile`;\n        header.length ? requestObj.header = header : '';\n        requestObj.auth = security\n        body.raw = JSON.stringify(data[key], undefined, 2);\n        requestObj.body = body;\n        const responseObject = {};\n        responseObject.name = `updateProfile${key}_response`;\n        responseObject.originalRequest = {\n            method: 'PUT',\n            header: [],\n            url: {\n                raw: requestObj.url,\n            },\n        };\n        responseObject.status = 'OK';\n        responseObject.code = 200;\n        responseObject._postman_previewlanguage = 'json';\n        const id1 = fakeData.getObjectId();\n        let bodyRawData = _.cloneDeep(data[key]);\n        if (!('id' in bodyRawData)) {\n            Object.assign(bodyRawData, { id: id1 });\n        }\n        Object.assign(bodyRawData,\n            {\n                createdAt: fakerStatic.date.future(),\n                updatedAt: fakerStatic.date.future(),\n                isDeleted: false,\n                isActive: true\n            });\n        if (addDataFormate && addDataFormate[key]) {\n            bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n        }\n        if (Object.keys(modelPrivateAttribute).length) {\n            bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n        }\n        let responseJsonData = {\n            \"status\": \"SUCCESS\",\n            \"message\": \"Your request is successfully executed\",\n            \"data\": bodyRawData\n        };\n        responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n        responseObject.body = responseJsonData;\n        responseObject.header = [\n            { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n        ];\n        responseObject.cookie = [];\n        requestObj.response = [responseObject];\n        platformObj.request.push(requestObj);\n\n        // GET loggedInUserInfo \n        requestObj = {};\n        body = {};\n        header = [];\n        header.push({\n            key: 'Content-Type',\n            value: 'application/json',\n            description: '',\n        });\n        security = {\n            \"type\": \"bearer\",\n            \"bearer\": {\n                \"token\": \"{{token}}\"\n            }\n        }\n        // body.mode = 'raw';\n        requestObj.name = `get loggedin User`;\n        requestObj.method = 'GET',\n            requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/me` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/me`;\n        header.length ? requestObj.header = header : '';\n        requestObj.auth = security\n        // body.raw = JSON.stringify(data[key], undefined, 2);\n        // requestObj.body = body;\n        responseObject = {};\n        responseObject.name = `loggedInUserInfo_response`;\n        responseObject.originalRequest = {\n            method: 'GET',\n            header: [],\n            url: {\n                raw: requestObj.url,\n            },\n        };\n        responseObject.status = 'OK';\n        responseObject.code = 200;\n        responseObject._postman_previewlanguage = 'json';\n        bodyRawData = _.cloneDeep(data[key]);\n        if (!('id' in bodyRawData)) {\n            Object.assign(bodyRawData, { id: 101 });\n        }\n       // Object.assign(bodyRawData, defaultKeyObject);\n        if (addDataFormate && addDataFormate[key]) {\n            bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n        }\n        if (Object.keys(modelPrivateAttribute).length) {\n            bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n        }\n\n        responseJsonData = {\n            \"status\": \"SUCCESS\",\n            \"message\": \"Your request is successfully executed\",\n            \"data\": bodyRawData\n        };\n        responseObject.body = JSON.stringify(responseJsonData, undefined, 2);\n        responseObject.header = [];\n        responseObject.cookie = [];\n        requestObj.response = [responseObject];\n        platformObj.request.push(requestObj);\n    }\n\n    platformObj = _.cloneDeep(await sortMethods(platformObj));\n    return platformObj;\n}\nasync function getPostmanCollectionForFileUpload(platform, fileObject) {\n    try {\n        let platformObj = {\n            name: \"File Upload\",\n            desc: `Upload Files`,\n            request: []\n        }\n        let requestObj = {}\n        requestObj = {};\n        requestObj.body = {};\n        requestObj.body.mode = \"formdata\"\n        requestObj.name = `File upload in ${platform}`\n        requestObj.method = \"POST\"\n        if (platform.toLowerCase() != \"admin\") {\n            requestObj.url = `{{url}}/${platform.toLowerCase()}/api/v1/upload`;\n        }\n        else {\n            requestObj.url = `{{url}}/${platform.toLowerCase()}/upload`;\n        }\n        let formdata = [\n            {\n                \"key\": \"file[]\",\n                \"type\": \"file\",\n                \"description\": \"Select file to upload\"\n            },\n            {\n                \"key\": \"file[]\",\n                \"type\": \"file\",\n                \"disabled\": true,\n                \"description\": \"Select Another file to upload multiple files\"\n            },\n            {\n                \"key\": \"folder\",\n                \"value\": \"Enter foldername\",\n                \"type\": \"text\",\n                \"disabled\": true,\n                \"description\": \"Optional, enable to upload file to specific folder\"\n            },\n            {\n                \"key\": \"fileName\",\n                \"value\": \"Enter fileName\",\n                \"type\": \"text\",\n                \"disabled\": true,\n                \"description\": \"Optional, enable to give Specific file name to uploaded File\"\n            }\n        ];\n        requestObj.body.formdata = formdata;\n        requestObj.header = [];\n        requestObj.header.push({\n            key: 'Content-Type',\n            value: 'multipart/form-data',\n            description: '',\n        });\n        let security = {}\n        if (fileObject.authentication) {\n            security = {\n                \"type\": \"bearer\",\n                \"bearer\": {\n                    \"token\": \"{{token}}\"\n                }\n            }\n        }\n        requestObj.auth = security;\n        let responseJsonData = {\n            \"status\": \"SUCCESS\",\n            \"message\": \"Your request is successfully executed\",\n            \"data\": [\n                {\n                    \"status\": true,\n                    \"path\": `path to download file`,\n                }\n            ]\n        };\n        responseJsonData = JSON.stringify(responseJsonData, undefined, 2);\n        let responseObject = {};\n        responseObject.name = `File upload in ${platform}`;\n        responseObject.originalRequest = {\n            method: 'POST',\n            header: [],\n            url: {\n                raw: requestObj.url,\n            },\n        };\n        responseObject.status = 'OK';\n        responseObject.code = 200;\n        responseObject._postman_previewlanguage = 'json';\n        responseObject.body = responseJsonData;\n        responseObject.header = [\n            { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n        ];\n        responseObject.cookie = [];\n        requestObj.response = [responseObject];\n        platformObj.request.push(requestObj);\n\n        if (fileObject.storage !== undefined && fileObject.storage.toLowerCase() === 's3_private') {\n            //download api for s3 private\n            requestObj = {};\n            requestObj.body = {};\n            requestObj.body.mode = \"raw\"\n            requestObj.name = `Get Presigned Url for S3 private Upload`\n            requestObj.method = \"POST\"\n            if (platform.toLowerCase() != \"admin\") {\n                requestObj.url = `{{url}}/${platform.toLowerCase()}/api/v1/generate-pre-signed-url`;\n            }\n            else {\n                requestObj.url = `{{url}}/${platform.toLowerCase()}/generate-pre-signed-url`;\n            }\n            requestObj.body.raw = JSON.stringify({ uri: \"s3 URL\" }, undefined, 2);\n            requestObj.header = [];\n            requestObj.header.push({\n                key: 'Content-Type',\n                value: 'application/json',\n                description: '',\n            })\n            if (fileObject.authentication) {\n                requestObj.header.push({\n                    \"key\": \"Authorization\",\n                    \"value\": \"Bearer {{token}}\",\n                    \"type\": \"text\"\n                })\n            }\n            responseJsonData = {\n                \"status\": \"SUCCESS\",\n                \"message\": \"Your request is successfully executed\",\n                \"data\": [\n                    {\n                        \"status\": true,\n                        \"path\": `URL to access file`,\n                    }\n                ]\n            };\n            responseJsonData = JSON.stringify(responseJsonData, undefined, 2);\n            responseObject = {};\n            responseObject.name = `Get Presigned Url for S3 private Upload`;\n            responseObject.originalRequest = {\n                method: 'POST',\n                header: [],\n                url: {\n                    raw: requestObj.url,\n                },\n            };\n            responseObject.status = 'OK';\n            responseObject.code = 200;\n            responseObject._postman_previewlanguage = 'json';\n            responseObject.body = responseJsonData;\n            responseObject.header = [\n                { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n            ];\n            responseObject.cookie = [];\n            requestObj.response = [responseObject];\n            platformObj.request.push(requestObj);\n        }\n\n        return platformObj;\n\n    } catch (error) {\n        throw new Error(error.message);\n    }\n}\n\nasync function getCollectionForPostman(jsonData, isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth) {\n    // \"pf\" === \"platform\"\n\n    const port = jsonData?.config?.port;\n    let pfNames = jsonData.authentication.platform;\n    let pfWiseItems = {}\n    let pfWiseItemsArray = []\n    let pfWiseCount = {}\n    let fieldSelection = {}\n    let privateModelData = {};\n    if (!_.isEmpty(jsonData[\"fieldSelection\"])) {\n        fieldSelection = jsonData[\"fieldSelection\"];\n    }\n    if (!_.isEmpty(jsonData[\"modelPrivate\"])) {\n        privateModelData = jsonData[\"modelPrivate\"];\n    }\n    for (const pfName of pfNames) {\n        pfWiseItems[pfName] = {\n            name: null,\n            description: null,\n            item: []\n        }\n        pfWiseCount[pfName] = 0\n    }\n\n    for (const model in jsonData[\"models\"]) {\n        let loginWith = [];\n        let values = {};\n        if (userModel == model) {\n            for (let [k, v] of Object.entries(jsonData[\"models\"][model])) {\n                if (k.includes('SSO'.toLowerCase())) {\n                    delete jsonData[\"models\"][model][k];\n                }\n            }\n            loginWith = _.keys(_.pickBy(userLoginWith));\n            let modelsKeys = _.keys(jsonData[\"models\"][model]);\n            if (!modelsKeys.includes(loginWith[0])) {\n                jsonData[\"models\"][model][loginWith[0]] = {\n                    \"type\": \"String\",\n                    \"unique\": true,\n                    \"uniqueCaseInsensitive\": true\n                }\n            }\n        }\n        let modelObj = {}\n        modelObj[model] = jsonData[\"models\"][model]\n        let fakeModel = fakeData.validSchema(_.cloneDeep(modelObj));\n        let pfDetails = await getPlatformFromSchemaDynamic(jsonData, jsonData[\"modelConfig\"], model);\n\n        for (const pfName of pfNames) {\n            let loginAccessRole = _.keys(loginAccessPlatform);\n            pfWiseItems[pfName].name = pfName;\n            pfWiseItems[pfName].description = `${pfName} APIs`\n            pfWiseCount[pfName]++\n            let modelPrivateAttribute = {};\n            let format = {};\n            if (!_.isEmpty(privateModelData[model])) {\n                modelPrivateAttribute = privateModelData[model];\n            }\n            if (!_.isEmpty(jsonData['authentication']['addDataFormate'])) {\n                format = jsonData['authentication']['addDataFormate'];\n            }\n            if (!_.isEmpty(pfDetails[pfName])) {\n                let currentPostmanPlatformDetails = fieldSelection[pfName];\n                let currentModelNameDetails = {};\n                if (currentPostmanPlatformDetails) {\n                    currentModelNameDetails = currentPostmanPlatformDetails[model];\n                }\n                let modelDetails = await getPostmanCollections(pfName, model, pfDetails[pfName], fakeModel, userModel === model, isAuth, port, currentModelNameDetails, format, jsonData[\"models\"][model], modelPrivateAttribute);\n                pfWiseItems[pfName].item.push(modelDetails)\n            }\n\n            if (isAuth && userModel === model) {\n                let loginDetail = await getPostmanCollectionsForLogin(pfName, userModel, loginWith[0], fakeModel, port, format, jsonData[\"models\"][model], modelPrivateAttribute, model);\n                pfWiseItems[pfName].item.push(loginDetail)\n            }\n            if (pfWiseCount[pfName] == 1 && socialAuth.required) {\n                let details = [];\n                if (socialAuth.platforms.length) {\n                    _.each(socialAuth.platforms, p => {\n                        if (p.platforms.includes(pfName)) {\n                            details.push(p.type);\n                        }\n                    });\n                }\n                if (details.length) {\n                    let socialDetails = await getPostmanCollectionForSocialLogin(pfName, details);\n                    pfWiseItems[pfName].item.push(socialDetails)\n                }\n            }\n            if (pfWiseCount[pfName] == 1 && !_.isEmpty(jsonData[\"fileUpload\"])) {\n                _.each(jsonData[\"fileUpload\"].uploads, async u => {\n                    if (u.platform.toLowerCase() == pfName) {\n                        let platformObj = await getPostmanCollectionForFileUpload(pfName, u);\n                        pfWiseItems[pfName].item.push(platformObj);\n                    }\n                })\n            }\n\n        }\n\n    }\n    if (!_.isEmpty(jsonData[\"routes\"]?.apis)) {\n\n        let platformWiseGroup = _.groupBy(jsonData[\"routes\"]?.apis, \"platform\");\n        let customRoutesWithOutPlatform;\n        if (platformWiseGroup && platformWiseGroup['undefined']) {\n            customRoutesWithOutPlatform = platformWiseGroup['undefined']\n            pfWiseItems[\"Custom Routes\"] = {\n                name: \"Custom Routes\",\n                description: \"Custom Routes\",\n                item: []\n            }\n            pfWiseCount[\"Custom Routes\"] = 0\n            delete platformWiseGroup['undefined']\n        }\n\n        for (let obj in platformWiseGroup) {\n            let newPlatform = {\n                name: null,\n                description: null,\n                item: []\n            }\n            let platformObj = {\n                name: `customRoutes`,\n                desc: \"\",\n                request: []\n            }\n            platformWiseGroup[obj].forEach((p, k) => {\n                // newPlatform.name = obj.charAt(0).toUpperCase() + obj.slice(1);\n                newPlatform.name = obj;\n                newPlatform.description = p.descriptions\n                let requestObj = {}\n                let body = {}\n                body.mode = \"raw\"\n                requestObj.name = `${p.api}`\n                requestObj.method = `${p.method.toUpperCase()}`\n                requestObj.url = `{{url}}${p.api}`\n                body.raw = \"{}\"\n                requestObj.body = body;\n                platformObj.request.push(requestObj)\n\n            });\n            // console.log('pfNames :>> ', pfNames);\n            // for(const pfName of pfNames){\n            // console.log('obj :>> ', obj);\n            if (_.includes(pfNames, obj)) {\n                pfWiseItems[obj].item.push(platformObj)\n                // console.log('platformObj :>> ', platformObj);\n            } else {\n                newPlatform.item.push(platformObj);\n                if (!pfWiseItems[obj]) {\n                    pfWiseItems[obj] = {\n                        name: obj,\n                        description: `${obj} Apis`,\n                        item: []\n                    }\n                    pfWiseCount[obj] = 0\n\n                }\n                pfWiseItems[obj].item.push(newPlatform)\n                pfWiseCount[obj] += 1\n                // console.log('newPlatform :>> ', newPlatform);\n            }\n            // }\n\n        }\n\n        if (!_.isEmpty(customRoutesWithOutPlatform)) {\n            let newPlatform = {\n                name: \"routes\",\n                description: \"routes\",\n                item: []\n            }\n            let platformObj = {\n                name: `customRoutes`,\n                desc: \"\",\n                request: []\n            }\n            customRoutesWithOutPlatform.forEach((p, k) => {\n                // newPlatform.name = obj.charAt(0).toUpperCase() + obj.slice(1);\n                // newPlatform.name = obj;\n                // newPlatform.description = p.descriptions\n                let requestObj = {}\n                let body = {}\n                body.mode = \"raw\"\n                requestObj.name = `${p.api}`\n                requestObj.method = `${p.method.toUpperCase()}`\n                requestObj.url = `{{url}}${p.api}`\n                body.raw = \"{}\"\n                requestObj.body = body;\n                platformObj.request.push(requestObj)\n            });\n            pfWiseItems[\"Custom Routes\"].item.push(platformObj)\n            pfWiseCount[\"Custom Routes\"] += 1\n        }\n\n    }\n\n    // for(const pfName of pfNames){\n    //     console.log('pfName :>> ', pfName);\n    //     console.log('pfWiseItems[pfName].item.length :>> ', pfWiseItems[pfName].item.length);\n    // }\n    let webNot = [];\n    if (!isEmpty(jsonData[\"modelNotifications\"])) {\n        Object.values(jsonData.modelNotifications).forEach((keys) => {\n            for (const [k, val] of Object.entries(keys)) {\n                if (APIS.includes(k) && val.selected) {\n                    webNot.push(val.post ? val.post.webNotification === true : val.pre.webNotification === true);\n                }\n            }\n        });\n    }\n\n\n\n    let fileObj = {};\n    if (!_.isEmpty(jsonData[\"fileUpload\"])) {\n        for (let i = 0; i < jsonData[\"fileUpload\"].uploads.length; i++) {\n            if (!_.isEmpty(jsonData[\"fileUpload\"].uploads[i].platform)) {\n                fileObj = jsonData[\"fileUpload\"].uploads[i];\n                break;\n            }\n        }\n    }\n\n    let customObj = {\n        notification: webNot,\n        fileObj,\n        port\n    }\n    let customItems = await setCustomRoutes(customObj);\n    if (customItems.item.length) {\n        pfWiseItems.common = customItems;\n    }\n\n    pfWiseItemsArray = values(pfWiseItems)\n    return pfWiseItemsArray\n}\nasync function sortMethods(methods) {\n    let post = [], put = [], get = [], del = [];\n    for (let i = 0; i < methods.request.length; i++) {\n        key = methods.request[i].method;\n        if (key == 'PUT') {\n            put.push(methods.request[i]);\n        }\n        else if (key == 'GET') {\n            get.push(methods.request[i]);\n        }\n        else if (key == 'DELETE') {\n            del.push(methods.request[i]);\n        }\n        else {\n            post.push(methods.request[i]);\n        }\n    }\n\n    let returnObj = [\n        ...get, ...post, ...put, ...del\n    ]\n    Object.assign(methods, { request: returnObj })\n    return methods;\n}\n\nasync function generateEnvForPostman(config) {\n    let jsonObj = {\n        \"id\": uuid4(),\n        \"name\": `${config.projectName}_environment`,\n        \"values\": [\n            {\n                \"key\": \"token\",\n                \"value\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMWRlZDVjMGFjMjAxMmFjMDI4ODkxZiIsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE2MjkzNTEyNzAsImV4cCI6MTYyOTk1MTI3MH0.BJ-WKjNYeFDQ4pn8kfli5gwn6GLz_c3voFht20Agj9k\",\n                \"enabled\": true\n            },\n            {\n                \"key\": \"url\",\n                \"value\": `http://localhost:${config.port || 3000}`,\n                \"enabled\": true\n            }\n        ],\n        \"_postman_variable_scope\": \"environment\",\n        \"_postman_exported_at\": new Date(),\n        \"_postman_exported_using\": \"Postman\"\n    }\n    return jsonObj;\n}\n\nconst getPushNotificationRoutes = (platform, pushNotificationData) => {\n    let platformObj = {\n        name: \"Push Notification\",\n        desc: `Push Notification Routes`,\n        request: []\n    }\n    let data = {\n        userId: '611cbe48fe58009a1603f9f2',\n        playerId: 'xxx12345xxx',\n        deviceId: '2001abcdef',\n        isActive: true,\n        isDeleted: false\n    }\n\n    let requestObj = {}\n    let body = {}\n    body.mode = 'raw';\n    requestObj = {};\n    requestObj.body = {};\n    requestObj.name = `Add Player Id`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}/${platform.toLowerCase()}/auth/push-notification/addPlayerId`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    requestObj.response = [];\n    platformObj.request.push(requestObj);\n\n    requestObj = {}\n    body = {}\n    data = {\n        deviceId: '012345abcde'\n    }\n    body.mode = 'raw';\n    requestObj = {};\n    requestObj.body = {};\n    requestObj.name = `Remove Player Id`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}//${platform.toLowerCase()}/auth/push-notification/removePlayerId`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    requestObj.response = [];\n    platformObj.request.push(requestObj);\n    return platformObj;\n}\n\nasync function removePrivateAttibutesFromResponse(fakeModel, privateModelData) {\n    let fakeData = _.cloneDeep(fakeModel);\n    if (!_.isEmpty(fakeData)) {\n        if (!_.isEmpty(privateModelData)) {\n            Object.keys(fakeModel).forEach(fm => {\n                Object.keys(privateModelData).forEach(pm => {\n                    if (fm === pm) {\n                        if (Array.isArray(fakeModel[fm])) {\n                            //Remove field from array\n                            if (fakeModel[fm].length) {\n                                let objArray = fakeModel[fm][0];\n                                Object.keys(objArray).forEach(obj => {\n                                    Object.keys(privateModelData[pm]).forEach(m => {\n                                        if (obj === m) {\n                                            if (privateModelData[pm][m] === true) {\n                                                delete objArray[obj];\n                                            }\n                                        }\n                                    })\n                                })\n                                fakeData[fm] = [objArray];\n                            }\n                        } else {\n                            if (typeof fakeModel[fm] === 'object' && Object.keys(fakeModel[fm]).length && Object.keys(privateModelData[pm]).length) {\n                                //Remove field from object\n                                Object.keys(fakeModel[fm]).forEach(d => {\n                                    Object.keys(privateModelData[pm]).forEach(m => {\n                                        if (m === d) {\n                                            if (privateModelData[pm][m] === true) {\n                                                delete fakeData[pm][m];\n                                            }\n                                        }\n                                    })\n                                })\n                            } else {\n                                //Remove model property\n                                if (privateModelData[pm] === true) {\n                                    delete fakeData[pm];\n                                }\n                            }\n                        }\n                    }\n                })\n            });\n        }\n    }\n    return fakeData;\n}\n\nasync function filterResponseBasedOnFormate(formateArray, data) {\n    // let newData={};\n    for (let index of formateArray) {\n        for (let nestIndex in index) {\n            switch (index.dataType) {\n                case 'string':\n                    if (index[nestIndex] in data) {\n                        if (data[index.attribute[0]] && data[index.attribute[1]]) {\n                            if (index.operator === 'space') {\n                                data[index[nestIndex]] = data[index.attribute[0]].toString().concat(' ', data[index.attribute[1]].toString())\n                            } else {\n                                data[index[nestIndex]] = data[index.attribute[0]].toString().concat(`${index.operator}`, data[index.attribute[1]].toString())\n                            }\n                        }\n                    }\n                    if (!data.hasOwnProperty(index.targetAttr)) {\n                        if (index.operator === 'space') {\n                            data[index.targetAttr] = data[index.attribute[0]].toString().concat(' ', data[index.attribute[1]].toString())\n                        } else {\n                            data[index.targetAttr] = data[index.attribute[0]].toString().concat(`${index.operator}`, data[index.attribute[1]].toString())\n                        }\n                    }\n                    break;\n                case 'boolean':\n                    //  console.log(index.attribute.true);\n                    for (let boolIndex in data) {\n                        if (typeof data[boolIndex] === 'boolean') {\n                            if (data[boolIndex]) {\n                                data[boolIndex] = index.attribute.true;\n                            } else {\n                                data[boolIndex] = index.attribute.false;\n                            }\n\n                        }\n                    }\n                    break;\n\n                case 'date':\n                    for (let dateIndex in data) {\n                        if (data[dateIndex] instanceof (Date)) {\n                            data[dateIndex] = dayjs(data[dateIndex]).format(index.attribute);\n                        }\n                    }\n                    break;\n            }\n        }\n    }\n    return data;\n}\nmodule.exports = {\n    getCollectionForPostman,\n    generateEnvForPostman\n};\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/render/index.js",
    "content": "/* eslint-disable linebreak-style */\n/* global MODE_0666 */\n/* global _ */\nconst dotenv = require('dotenv');\nconst path = require('path');\nconst sortedObject = require('sorted-object');\nconst fs = require('fs');\nconst replace = require('key-value-replace');\nconst writeOperations = require('../../writeOperations');\nconst { PROJECT_TYPE } = require('../../constants/constant');\n\ndotenv.config({ path: `${__dirname}/../../.env` });\n\nasync function createConstantFiles (templateFolder, dir, constants, toPath) {\n  if (constants) {\n    writeOperations.mkdir(dir, toPath);\n    _.forEach(constants, (value, key) => {\n      const requestConstant = writeOperations.loadTemplate(`${templateFolder}/requestConstant.js`);\n      requestConstant.locals.CONSTANTS = JSON.stringify(value);\n      requestConstant.locals.FILE_NAME = key;\n      writeOperations.write(path.join(dir, `${toPath}/${key}.js`), requestConstant.render());\n    });\n  }\n}\n\nasync function startRenderingEJS (dir, templateFolder, renderObject) {\n  const {\n    type, app, db, models, controllerDetails, modelWiseRoutes, authModule, authControllerIndex, pkg, emailService,\n    smsService, indexRoute, modelValidation, constants, env,\n    seeder, customPolicy, postmanCollectionJSONV20, postmanCollectionJSONV21, platformRoutes, customRoutes, shouldCopyQueryService, isAuth,\n    fileUpload, socialData, allEJSEntities, controllerIndex, controllerIndexForCustomRoute,\n    deleteDependent, userDirectoryStructure, servicesOfCustomRoutes, tableRelationships, dbConnection, customRoutePackageDependencies, testCases,\n    commonService, readme, envPostman,\n    thirdPartySMSServices, thirdPartyEmailService, templateRegistry, rolePermissionService, customRoutesWithPath, customRouteIndexes, dataAccessFiles, useCaseFiles, commonUseCaseFiles, middlewareIndex,\n    customRoutesUsecase, fileUploadService, fileUploadUsecase,\n    fileUploadControllerIndex,\n  } = renderObject;\n\n  // db\n\n  if (type === PROJECT_TYPE.CC_SEQUELIZE) {\n    if (db && dbConnection) {\n      let dbFilePath = userDirectoryStructure.configFolderPath.split('/').filter((e) => e !== '');\n      // let dbFileName = dbFilePath.pop();\n      if (!fs.existsSync(`${dir}${dbFilePath.join('/')}`)) {\n        writeOperations.mkdir(dir, dbFilePath.join('/'));\n      }\n      writeOperations.write(path.join(dir, `${dbFilePath.join('/')}/db.js`), db.render());\n      // writeOperations.write(path.join(dir, '/config/db.js'), db.render());\n      dbFilePath = userDirectoryStructure.dbConnectionFolderPath.split('/').filter((e) => e !== '');\n      dbFilePath.pop();\n      writeOperations.write(path.join(dir, `${dbFilePath.join('/')}/dbConnection.js`), dbConnection.render());\n    }\n  } else if (db) {\n    const dbFilePath = userDirectoryStructure.dbConnectionFolderPath.split('/').filter((e) => e !== '');\n    const dbFileName = dbFilePath.pop();\n    if (!fs.existsSync(`${dir}${dbFilePath.join('/')}`)) {\n      writeOperations.mkdir(dir, dbFilePath.join('/'));\n    }\n    writeOperations.write(path.join(dir, `${dbFilePath.join('/')}/${dbFileName}`), db.render());\n    // writeOperations.write(path.join(dir, '/config/db.js'), db.render());\n    if (dbConnection) {\n      writeOperations.write(path.join(dir, `${dbFilePath.join('/')}/dbConnection.js`), dbConnection.render());\n    }\n  }\n  const dbFilePath = userDirectoryStructure.dbConnectionFolderPath.split('/').filter((e) => e !== '');\n  dbFilePath.pop();\n\n  if (!_.isEmpty(seeder)) {\n    app.locals.SEEDER = true;\n    writeOperations.mkdir(dir, userDirectoryStructure.seedersPath);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.seedersPath}/index.js`), seeder.render());\n  }\n\n  // model\n  _.forEach(models, (value, key) => {\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.modelFolderPath}/${key}.js`), value.render());\n  });\n\n  // dataAccessFiles\n  if (!_.isEmpty(dataAccessFiles)) {\n    _.forEach(dataAccessFiles, (value, key) => {\n      writeOperations.mkdir(dir, `${userDirectoryStructure.dataAccessFolderPath}`);\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.dataAccessFolderPath}/${key}Db.js`), value.render());\n    });\n  }\n\n  if (!_.isEmpty(tableRelationships)) {\n    // generate sql relationships\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.modelFolderPath}/index.js`), tableRelationships.render());\n  }\n\n  writeOperations.write(path.join(dir, `${userDirectoryStructure.utilsFolderPath}/common.js`), commonService.render());\n\n  // controller Index file if project is cc\n  if (!_.isEmpty(controllerIndex)) {\n    _.forEach(controllerIndex, (value, key) => {\n      writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}`, key);\n      _.forEach(value, (model) => {\n        _.forEach(model, (v, k) => {\n          writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${key}`, k);\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.controllerFolderPath}/${key}/${k}/index.js`), v.render(), MODE_0666);\n        });\n      });\n    });\n  }\n\n  // controller\n  const controller = controllerDetails.platformWiseController;\n  if (!_.isEmpty(controllerDetails.packageDependencies.dependencies)) {\n    Object.assign(pkg.dependencies, controllerDetails.packageDependencies.dependencies);\n  }\n  _.forEach(controller, (value, platform) => {\n    writeOperations.mkdir(`${dir}/controller`, platform);\n    _.forEach(value, (api, model) => {\n      const controllerPath = replace(api.locals.path, {\n        model,\n        platform,\n      });\n      writeOperations.write(path.join(dir, controllerPath), api.render(), MODE_0666);\n    });\n  });\n\n  // model wise Routes\n  if (!_.isEmpty(modelWiseRoutes)) {\n    _.forEach(modelWiseRoutes, (value, platformName) => {\n      writeOperations.mkdir(`${dir}/routes`, platformName);\n      _.forEach(value, (modelRoute, model) => {\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${platformName}/${model}Routes.js`), modelRoute.render(), MODE_0666);\n      });\n    });\n  }\n\n  // delete dependency\n  if (!_.isEmpty(deleteDependent)) {\n    /*  writeOperations.write(path.join(dir, '/utils/deleteDependent.js'), deleteDependent.render(), MODE_0666); */\n    _.forEach(deleteDependent, (dependency) => {\n      if (dependency.locals.PROJECT_TYPE === PROJECT_TYPE.MVC || dependency.locals.PROJECT_TYPE === PROJECT_TYPE.MVC_SEQUELIZE) {\n        writeOperations.write(path.join(dir, '/utils/deleteDependent.js'), dependency.render(), MODE_0666);\n      } else {\n        writeOperations.mkdir(dir, `${userDirectoryStructure.useCaseFolderPath}/${dependency.locals.MODEL_NAME}`);\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.useCaseFolderPath}/${dependency.locals.MODEL_NAME}/deleteDependent.js`), dependency.render(), MODE_0666);\n      }\n    });\n  }\n\n  // authentication\n  if (!_.isEmpty(authModule)) {\n    // app\n    _.forEach(authModule.app.locals, (value, appKey) => {\n      app.locals[appKey] = value;\n    });\n\n    // auth controller Index\n    if (!_.isEmpty(authControllerIndex)) {\n      _.forEach(authControllerIndex, (value, platformName) => {\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${platformName}`, 'authentication');\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.controllerFolderPath}/${platformName}/authentication/index.js`), value.render(), MODE_0666);\n      });\n    }\n\n    if (!_.isEmpty(useCaseFiles)) {\n      writeOperations.mkdir(dir, `${userDirectoryStructure.useCaseFolderPath}`);\n      _.forEach(useCaseFiles, (modelOperations, modelName) => {\n        writeOperations.mkdir(dir, `${userDirectoryStructure.useCaseFolderPath}/${modelName}`);\n        _.forEach(modelOperations, (operationEjs) => {\n          // console.log(require('util').inspect(operationEjs, false, null, true)); process.exit(1);\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.useCaseFolderPath}/${modelName}/${operationEjs.locals.FILE_NAME}.js`), operationEjs.render());\n        });\n        /*  */\n      });\n    }\n    // ? file Upload Service\n    if (!_.isEmpty(fileUploadService)) {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.serviceFolderPath}/fileUpload`)) { writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, 'fileUpload'); }\n\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/fileUpload/index.js`), fileUploadService.render(), MODE_0666);\n    }\n\n    // ? file upload use-case\n    if (!_.isEmpty(fileUploadUsecase)) {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.useCaseFolderPath}/fileUpload`)) { writeOperations.mkdir(`${dir}${userDirectoryStructure.useCaseFolderPath}`, 'fileUpload'); }\n\n      _.forEach(fileUploadUsecase, (usecase) => {\n        // currently only one object in array from input so here file name is not dynamic\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.useCaseFolderPath}/fileUpload/upload.js`), usecase.render(), MODE_0666);\n      });\n    }\n    // ? file upload controller index for cc\n    if (!_.isEmpty(fileUploadControllerIndex)) {\n      _.forEach(fileUploadControllerIndex, (fileUploadCtrlInd) => {\n        if (fileUploadCtrlInd.locals.PLATFORM === 'admin') {\n          if (!fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}/fileUpload`)) {\n            writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}`, 'fileUpload');\n          }\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}/fileUpload/index.js`), fileUploadCtrlInd.render(), MODE_0666);\n        } else {\n          if (!fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}/fileUpload`)) {\n            writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}`, 'fileUpload');\n          }\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.controllerFolderPath}/${fileUploadCtrlInd.locals.PLATFORM}/fileUpload/index.js`), fileUploadCtrlInd.render(), MODE_0666);\n        }\n      });\n    }\n    // middleware index.js\n    if (middlewareIndex) {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/index.js`), middlewareIndex.render(), MODE_0666);\n    }\n\n    // package\n    Object.assign(pkg.dependencies, authModule.packageDependency.dependencies);\n\n    /*\n     * constant\n     * writeOperations.write(path.join(dir, `${userDirectoryStructure.configFolderPath}/authConstant.js`), authModule.constant.render(), MODE_0666);\n     */\n    writeOperations.mkdir(dir, userDirectoryStructure.constantFolderPath);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.constantFolderPath}/authConstant.js`), authModule.constant.render(), MODE_0666);\n\n    // authSetup\n    _.forEach(authModule.authSetup, (value, platformName) => {\n      // passport strategies\n      if (type === PROJECT_TYPE.MVC || type === PROJECT_TYPE.MVC_SEQUELIZE) {\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.configFolderPath}/${platformName}PassportStrategy.js`), value.passport.render(), MODE_0666);\n      } else {\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/${platformName}PassportStrategy.js`), value.passport.render(), MODE_0666);\n      }\n      // writeOperations.write(path.join(dir, `/config/${platformName}PassportStrategy.js`), value.passport.render(), MODE_0666);\n      writeOperations.write(path.join(dir, `/routes/${platformName}/auth.js`), value.authRoutes.render(), MODE_0666);\n      const authPath = replace(value.authController.locals.PATH, { platform: platformName });\n      value.authController.locals.PLATFORM_NAME = platformName.toUpperCase();\n      writeOperations.write(path.join(dir, `${authPath}/authController.js`), value.authController.render(), MODE_0666);\n    });\n\n    writeOperations.mkdir(`${dir}${userDirectoryStructure.viewsFolderPath}`, 'successfullyResetPassword');\n    writeOperations.copyTemplate(`${templateFolder}${templateRegistry.viewsFolderPath}/resetPassword.ejs`, `${dir}${userDirectoryStructure.viewsFolderPath}/successfullyResetPassword/html.ejs`);\n\n    // authService\n    if (type === PROJECT_TYPE.MVC || type === PROJECT_TYPE.MVC_SEQUELIZE) {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/auth.js`), authModule.authService.render(), MODE_0666);\n    }\n\n    // policy\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/auth.js`), authModule.policy.middleware.render(), MODE_0666);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/loginUser.js`), authModule.policy.authUser.render(), MODE_0666);\n\n    // Auth usecase for CC\n    _.forEach(authModule.authSetup, (value) => {\n      if (value.authUsecase) {\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.useCaseFolderPath}`, 'authentication');\n        _.forEach(value.authUsecase, (usecase) => {\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.useCaseFolderPath}/authentication/${usecase.locals.FILE_NAME}.js`), usecase.render(), MODE_0666);\n        });\n      }\n    });\n  }\n\n  if (!_.isEmpty(commonUseCaseFiles)) {\n    writeOperations.mkdir(dir, `${userDirectoryStructure.useCaseFolderPath}/common`);\n    _.forEach(commonUseCaseFiles, (usecaseEjs) => {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.useCaseFolderPath}/common/${usecaseEjs.locals.FILE_NAME}.js`), usecaseEjs.render());\n    });\n  }\n\n  if (emailService || isAuth) {\n    pkg.dependencies.nodemailer = '~6.7.2';\n    writeOperations.mkdir(`${dir}${userDirectoryStructure.viewsFolderPath}`, 'emailTemplate');\n    const emailTemp = writeOperations.loadTemplate(`${templateFolder}${templateRegistry.viewsFolderPath}/emailTemplate`);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.viewsFolderPath}/emailTemplate/html.ejs`), emailTemp.render(), MODE_0666);\n    writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, 'email');\n    const emailNotificationService = writeOperations.loadTemplate(`${templateFolder}${templateRegistry.serviceFolderPath}/emailService.js`);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/email/emailService.js`), emailNotificationService.render(), MODE_0666);\n  }\n  if (smsService || isAuth) {\n    pkg.dependencies.axios = '~0.21.1';\n    writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, 'sms');\n    const smsNotificationService = writeOperations.loadTemplate(`${templateFolder}${templateRegistry.serviceFolderPath}/smsService.js`);\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/sms/smsService.js`), smsNotificationService.render(), MODE_0666);\n  }\n\n  //  validation\n  if (type === PROJECT_TYPE.CLEAN_CODE || type === PROJECT_TYPE.CC_SEQUELIZE) {\n    if (!_.isEmpty(modelValidation)) {\n      _.forEach(modelValidation, (value, key) => {\n        if (!fs.existsSync(`${value.locals.PATH}/schema`)) {\n          writeOperations.mkdir(dir, `${value.locals.PATH}/schema`);\n        }\n        writeOperations.write(path.join(dir, `${value.locals.PATH}/schema/${key}.js`), value.render());\n      });\n    }\n  } else {\n    _.forEach(modelValidation, (value, key) => {\n      writeOperations.write(path.join(dir, `${value.locals.PATH}/${key}Validation.js`), value.render());\n    });\n  }\n\n  // constants\n  if (!_.isEmpty(constants)) {\n    await createConstantFiles(`${templateFolder}${templateRegistry.configFolderPath}`, dir, constants, userDirectoryStructure.constantFolderPath);\n  }\n\n  // custom policy\n  if (!_.isEmpty(customPolicy)) {\n    _.forEach(customPolicy, (value, policy) => {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/${policy}.js`), value.render(), MODE_0666);\n    });\n  }\n\n  // role permission middleware\n  if (!_.isEmpty(rolePermissionService)) {\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.middlewareFolderPath}/checkRolePermission.js`), rolePermissionService.render(), MODE_0666);\n  }\n\n  // customRoutes\n  if (!_.isEmpty(customRoutes)) {\n    if (!_.isEmpty(customRoutes.new)) {\n      // index route\n      if (customRoutes.new.platform && customRoutes.new.platform.length) {\n        _.forEach(customRoutes.new.platform, (value) => {\n          indexRoute.locals.PLATFORM[value] = {};\n        });\n      }\n      _.forEach(customRoutes.new.controllerNServiceNRoutes, (value, customRoute) => {\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.routesFolderPath}`, customRoute);\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}`, customRoute);\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, customRoute);\n        _.forEach(value, (element, customKey) => {\n          if (customRoutes.shouldCreateFolderOfController && !fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/${customRoute}/${customKey}`)) {\n            writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${customRoute}`, customKey);\n          }\n          const controllerPath = replace(element.controller.locals.path, {\n            platform: customRoute,\n            controller: customKey,\n          });\n          writeOperations.write(path.join(dir, controllerPath), element.controller.render(), MODE_0666);\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/${customRoute}/${customKey}Service.js`), element.service.render(), MODE_0666);\n          if (!_.isEmpty(element.route)) {\n            writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${customRoute}/${customKey}Routes.js`), element.route.render(), MODE_0666);\n          }\n        });\n      });\n      _.forEach(customRoutes.new.routeIndex, (element, customRoute) => {\n        writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${customRoute}/index.js`), element.indexRoute.render(), MODE_0666);\n      });\n    }\n    if (!_.isEmpty(customRoutes.old)) {\n      _.forEach(customRoutes.old.controllerNServiceNRoutes, (element, customRoute) => {\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, customRoute);\n        _.forEach(element, (value, customKey) => {\n          if (customRoutes.shouldCreateFolderOfController && !fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/${value.controller.locals.platform}/${customKey}`)) {\n            writeOperations.mkdir(`${dir}${userDirectoryStructure.controllerFolderPath}/${value.controller.locals.platform}`, customKey);\n          }\n          const controllerPath = replace(value.controller.locals.path, {\n            platform: value.controller.locals.platform,\n            controller: customKey,\n          });\n          writeOperations.write(path.join(dir, controllerPath), value.controller.render(), MODE_0666);\n          writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/${customRoute}/${customKey}Service.js`), value.service.render(), MODE_0666);\n          if (!_.isEmpty(value.route)) {\n            writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${customRoute}/${customKey}Routes.js`), value.route.render(), MODE_0666);\n          }\n        });\n      });\n\n      if (!_.isEmpty(customRouteIndexes)) {\n        _.forEach(customRouteIndexes, (element, customKey) => {\n          if (!_.isEmpty(platformRoutes)) {\n            _.forEach(platformRoutes, (value, platformName) => {\n              if (platformName === customKey) {\n                platformRoutes[platformName].locals.ROUTES = element;\n              }\n            });\n          }\n        });\n      }\n    }\n    if (shouldCopyQueryService && !fs.existsSync(`${dir}${userDirectoryStructure.serviceFolderPath}/customQueryService.js`)) {\n      writeOperations.copyTemplate(`${templateFolder}${templateRegistry.serviceFolderPath}/customQueryService.js.ejs`, `${dir}${userDirectoryStructure.serviceFolderPath}/customQueryService.js`);\n    }\n  }\n\n  if (!_.isEmpty(customRoutesWithPath)) {\n    if (!_.isEmpty(customRoutesWithPath.controllers)) {\n      _.forEach(customRoutesWithPath.controllers, (controller1, con) => {\n        if (!fs.existsSync(`${dir}${con}`)) { writeOperations.mkdir(`${dir}`, con); }\n        _.forEach(controller1, (c) => {\n          writeOperations.write(path.join(dir, `${con}/${c.locals.name}.js`), c.render(), MODE_0666);\n        });\n      });\n    }\n    if (!_.isEmpty(customRoutesWithPath.routes)) {\n      _.forEach(customRoutesWithPath.routes, (route1, r) => {\n        if (!fs.existsSync(`${dir}${r}`)) { writeOperations.mkdir(`${dir}`, r); }\n        _.forEach(route1, (c) => {\n          writeOperations.write(path.join(dir, `${r}/${c.locals.name}.js`), c.render(), MODE_0666);\n        });\n      });\n    }\n  }\n\n  if (!_.isEmpty(customRoutePackageDependencies)) {\n    Object.assign(pkg.dependencies, customRoutePackageDependencies.dependencies);\n  }\n  if (controllerIndexForCustomRoute && controllerIndexForCustomRoute.length) {\n    _.forEach(controllerIndexForCustomRoute, (index) => {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/${index.locals.PLATFORM}/${index.locals.CONTROLLER}`)) {\n        writeOperations.mkdir(`${dir}`, `${userDirectoryStructure.controllerFolderPath}/${index.locals.PLATFORM}/${index.locals.CONTROLLER}`);\n      }\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.controllerFolderPath}/${index.locals.PLATFORM}/${index.locals.CONTROLLER}/index.js`), index.render(), MODE_0666);\n    });\n  }\n\n  if (servicesOfCustomRoutes && servicesOfCustomRoutes.length) {\n    _.forEach(servicesOfCustomRoutes, (service) => {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.serviceFolderPath}/${service.locals.PLATFORM}`)) {\n        writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, service.locals.PLATFORM);\n      }\n\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/${service.locals.PLATFORM}/${service.locals.SERVICE_NAME}Service.js`), service.render(), MODE_0666);\n    });\n  }\n\n  if (!_.isEmpty(customRoutesUsecase)) {\n    _.forEach(customRoutesUsecase, (usecase) => {\n      if (!fs.existsSync(`${dir}${usecase.locals.folderPath}`)) {\n        writeOperations.mkdir(`${dir}`, usecase.locals.folderPath);\n      }\n      writeOperations.write(path.join(dir, usecase.locals.path), usecase.render(), MODE_0666);\n    });\n  }\n\n  // fileUpload\n  if (!_.isEmpty(fileUpload)) {\n    console.log(fileUpload);\n    _.forEach(fileUpload.controllers, (f) => {\n      if (f.platform === 'common') {\n        if (!fs.existsSync(`${dir}${userDirectoryStructure.controllerFolderPath}/common`)) {\n          writeOperations.mkdir(dir, `${userDirectoryStructure.controllerFolderPath}/common`);\n        }\n      }\n      if (fileUpload.isFolder) {\n        writeOperations.mkdir(dir, `${userDirectoryStructure.controllerFolderPath}/${f.platform}/fileUpload`);\n      }\n\n      const controllerPath = replace(f.controller.locals.PATH, { platform: f.platform });\n      if (!fs.existsSync(controllerPath)) {\n        writeOperations.mkdir(dir, controllerPath);\n      }\n      writeOperations.write(path.join(dir, `${controllerPath}/fileUploadController.js`), f.controller.render());\n    });\n    _.forEach(fileUpload.routes, (f) => {\n      if (!_.isEmpty(platformRoutes[f.platform])) {\n        Object.assign(platformRoutes[f.platform].locals.PLATFORM, { upload: [] });\n      }\n      if (!fs.existsSync(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${f.platform}`))) {\n        writeOperations.mkdir(dir, `${userDirectoryStructure.routesFolderPath}/${f.platform}`);\n      }\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${f.platform}/uploadRoutes.js`), f.mainRoute.render());\n    });\n    Object.assign(pkg.dependencies, fileUpload.packageDependencies.dependencies);\n  }\n\n  if (!_.isEmpty(allEJSEntities)) {\n    _.forEach(allEJSEntities, (value, key) => {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.entityFolderPath}/${key}.js`), value.render());\n    });\n  }\n\n  // adding dependencies of social Login\n  if (!_.isEmpty(socialData)) {\n    Object.assign(pkg.dependencies, socialData.pkg.dependencies);\n    _.forEach(socialData.app.locals.uses, (value) => {\n      app.locals.uses.push(value);\n    });\n  }\n\n  // platform index routes\n  if (!_.isEmpty(platformRoutes)) {\n    _.forEach(platformRoutes, (platformIndex, platformName) => {\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/${platformName}/index.js`), platformIndex.render(), MODE_0666);\n    });\n  }\n  // index routes\n  if (!_.isEmpty(indexRoute)) {\n    app.locals.IS_ROUTE = true;\n    if (!_.isEmpty(customRoutesWithPath) && !_.isEmpty(customRoutesWithPath.mainIndexRoute)) {\n      indexRoute.locals.CUSTOM_ROUTE = customRoutesWithPath.mainIndexRoute;\n    }\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.routesFolderPath}/index.js`), indexRoute.render(), MODE_0666);\n  }\n\n  // Third-Party SMS Services\n  if (!_.isEmpty(thirdPartySMSServices)) {\n    if (!fs.existsSync(`${dir}${userDirectoryStructure.serviceFolderPath}/sms`)) { writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, 'sms'); }\n    writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/sms/smsService.js`), thirdPartySMSServices.render(), MODE_0666);\n  }\n\n  // ? Third party email services\n  if (!_.isEmpty(thirdPartyEmailService)) {\n    if (!_.isEmpty(thirdPartyEmailService.email)) {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.serviceFolderPath}/email`)) { writeOperations.mkdir(`${dir}${userDirectoryStructure.serviceFolderPath}`, 'email'); }\n      writeOperations.write(path.join(dir, `${userDirectoryStructure.serviceFolderPath}/email/emailService.js`), thirdPartyEmailService.email.render(), MODE_0666);\n    }\n  }\n\n  // ? test cases\n  if (!_.isEmpty(testCases)) {\n    if (_.isEmpty(pkg.devDependencies)) {\n      Object.assign(pkg, { devDependencies: {} });\n    }\n    Object.assign(pkg.devDependencies, { jest: '^27.0.6' });\n    Object.assign(pkg.devDependencies, { supertest: '^6.1.3' });\n    Object.assign(pkg.scripts, { test: 'jest --runInBand --verbose --detectOpenHandles' });\n    if (!fs.existsSync(`${dir}${userDirectoryStructure.testCasePath}`)) { writeOperations.mkdir(dir, userDirectoryStructure.testCasePath); }\n    _.forEach(testCases, (platforms, platformName) => {\n      if (!fs.existsSync(`${dir}${userDirectoryStructure.testCasePath}/${platformName}`)) { writeOperations.mkdir(`${dir}${userDirectoryStructure.testCasePath}`, `${platformName}`); }\n      _.forEach(platforms, (model, modelName) => {\n        const testCasePath = replace(model.locals.path, {\n          platform: platformName,\n          model: modelName,\n        });\n        writeOperations.write(path.join(dir, testCasePath), model.render(), MODE_0666);\n      });\n    });\n  }\n\n  // app js\n\n  // env file\n  if (!_.isEmpty(env)) {\n    /*\n     * if (userDirectoryStructure.mainJSFilePath.includes('.js')) {\n     *   userDirectoryStructure.mainJSFilePath = '';\n     * }\n     */\n    const filePath = userDirectoryStructure.envFilePath.split('/').filter((e) => e !== '');\n    const fileName = filePath.pop();\n    if (filePath.length) {\n      // mkdir\n      writeOperations.mkdir(dir, filePath.join('/'));\n    }\n    writeOperations.write(path.join(dir, `${filePath.join('/')}/${fileName}`), env.env.render());\n    if (!_.isEmpty(env.customEnv)) {\n      _.forEach(env.customEnv, (value, key) => {\n        writeOperations.write(path.join(dir, `${filePath.join('/')}/${fileName}.${key}`), value.render());\n      });\n    }\n  }\n\n  // app.js\n  writeOperations.write(path.join(dir, 'app.js'), app.render(), MODE_0666);\n\n  // package.json\n  pkg.dependencies = sortedObject(pkg.dependencies);\n  writeOperations.write(path.join(dir, 'package.json'), `${JSON.stringify(pkg, null, 2)}\\n`);\n\n  // postman collection - V2.0\n  if (!_.isEmpty(postmanCollectionJSONV20)) {\n    writeOperations.write(path.join(dir, '/postman/postman-collection.json'), postmanCollectionJSONV20);\n  }\n  // postman collection - V2.1\n  if (!_.isEmpty(postmanCollectionJSONV20)) {\n    writeOperations.write(path.join(dir, '/postman/postman-collection-v.2.1.0.json'), postmanCollectionJSONV21);\n  }\n\n  if (!_.isEmpty(envPostman)) {\n    writeOperations.write(path.join(dir, '/postman/environment-file.json'), JSON.stringify(envPostman, undefined, 2));\n  }\n\n  // ReadME file\n  if (readme) {\n    writeOperations.write(path.join(dir, 'README.md'), readme.render());\n  }\n  // .gitignore file\n  writeOperations.copyTemplate(`${templateFolder}/.gitignore`, `${dir}/.gitignore`);\n}\n\nmodule.exports = { startRenderingEJS };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/requestValidation.js",
    "content": "/* eslint-disable */\nconst _ = require('lodash');\n\nconst validate = module.exports = {};\n\nvalidate.getValidation = async function (schema, enumData) {\n  let schemaObj = {}; let models;\n  let modelObj = {}, updateModelObj = {}, modelTestobj = {};\n  let modelType, otherTypes;\n  let joiModel;\n  let joiValidation = {};\n  let flag = true;\n  joiValidation.arrayOpen = 'joi.array().items(';\n  joiValidation.objectOpen = 'joi.object({';\n  joiValidation.arrayClose = ')';\n  joiValidation.objectClose = '})';\n\n  _.each(schema, (value, key) => {\n    delete value['updatedBy'];\n    delete value['addedBy'];\n    delete value['createdAt'];\n    delete value['updatedAt'];\n    delete value['modifiedBy'];\n  });\n  let closeStatus = 0;\n  for (let schemaIndex in schema) {\n    for (let valueIndex in schema[schemaIndex]) {\n      let status = false;\n      for (let modelEnum in enumData) {\n        if (schemaIndex === modelEnum) {\n          for (let enumValueIndex in enumData[modelEnum]) {\n            if (enumValueIndex === valueIndex) {\n              if (schema[schemaIndex][valueIndex].type === 'String' || schema[schemaIndex][valueIndex].type === 'Number') {\n                if (enumData[modelEnum][enumValueIndex].default) {\n                  schemaObj[valueIndex] = `joi.${_.toLower(schema[schemaIndex][valueIndex].type)}().default(${enumData[modelEnum][enumValueIndex].enumFile}Default.${enumData[modelEnum][enumValueIndex].enumAttribute}.${enumData[modelEnum][enumValueIndex].default})`;\n                } else {\n                  schemaObj[valueIndex] = `joi.${_.toLower(schema[schemaIndex][valueIndex].type)}()`;\n                }\n              } else\n                schemaObj[valueIndex] = `joi.string()..default(${enumData[modelEnum][enumValueIndex].enumFile}Default.${enumData[modelEnum][enumValueIndex].enumAttribute}.${enumData[modelEnum][enumValueIndex].default})`;\n              status = true;\n            }\n          }\n        }\n      }\n      models = schema[schemaIndex][valueIndex];\n      if (models.type) {\n        //'string'\n        if (typeof models.type === 'string' && !status) {\n          modelType = getTypes(models.type);\n          otherTypes = getOtherTypes(Object.keys(models), Object.values(models));\n          if (otherTypes) {\n            joiModel = modelType.concat(otherTypes);\n            schemaObj[valueIndex] = joiModel;\n          } else {\n            schemaObj[valueIndex] = modelType;\n          }\n          //['String']\n        } else if (Array.isArray(models.type) && models.type.length === 1 && !status) {\n          modelType = getTypes(models.type[0]);\n\n          otherTypes = getOtherTypes(Object.keys(models), Object.values(models));\n          if (otherTypes) {\n            joiModel = joiValidation.arrayOpen.concat(modelType, otherTypes, joiValidation.arrayClose);\n            schemaObj[valueIndex] = joiModel;\n          } else {\n            schemaObj[valueIndex] = joiValidation.arrayOpen.concat(modelType, joiValidation.arrayClose);\n          }\n        }\n      }\n      //without type('String')\n      else if (!models.type && typeof models !== 'object' && !status) {\n        modelType = getTypes(models);\n        schemaObj[valueIndex] = modelType;\n\n        //object\n      } else if (typeof models === 'object' && !Array.isArray(models) && !status) {\n        schemaObj[valueIndex] = joiValidation.objectOpen;\n        for (let index in models) {\n          if (models[index].type) {\n            modelType = getTypes(models[index].type);\n            otherTypes = getOtherTypes(Object.keys(models[index]), Object.values(models[index]));\n            if (otherTypes) {\n              schemaObj[valueIndex] += `${index}:${modelType}${otherTypes},`;\n              closeStatus = 1;\n            } else {\n              schemaObj[valueIndex] += `${index}:${modelType},`;\n              closeStatus = 1;\n            }\n          } else {\n            //2 level object\n            if (typeof models[index] === 'object' && !status) {\n              for (let nestIndex in models[index]) {\n                if (models[index][nestIndex].type && !Array.isArray(models[index])) {\n                  modelType = getTypes(models[index][nestIndex].type);\n                  otherTypes = getOtherTypes(Object.keys(models[index][nestIndex]), Object.values(models[index][nestIndex]));\n                  if (otherTypes) {\n                    schemaObj[valueIndex] = joiValidation.objectOpen;\n                    schemaObj[valueIndex] += `${index}:${joiValidation.objectOpen}${nestIndex}:${modelType}${otherTypes}${joiValidation.objectClose}`;\n                    schemaObj[valueIndex] += joiValidation.objectClose;\n                  } else {\n                    schemaObj[valueIndex] = joiValidation.objectOpen;\n                    schemaObj[valueIndex] += `${index}:${joiValidation.objectOpen}${nestIndex}:${modelType}${joiValidation.objectClose}`;\n                    schemaObj[valueIndex] += joiValidation.objectClose;\n                  }\n                  //object of array\n                } else if (Array.isArray(models[index]) && !status) {\n                  schemaObj[valueIndex] = joiValidation.objectOpen;\n                  schemaObj[valueIndex] += `${index}:${joiValidation.arrayOpen}`;\n                  schemaObj[valueIndex] += joiValidation.arrayClose;\n                  schemaObj[valueIndex] += joiValidation.objectClose;\n                  flag = false;\n                } else {\n                  //more then 2 levels\n                  schemaObj[valueIndex] = 'joi.object()';\n                }\n              }\n            } else {\n              if (!models.type && typeof models === 'object' && flag) {\n                schemaObj[valueIndex] = joiValidation.objectOpen;\n                for (let otherModels in models) {\n                  modelType = getTypes(models[otherModels]);\n                  schemaObj[valueIndex] += `${otherModels}:${modelType},`;\n                }\n                schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n                schemaObj[valueIndex] += joiValidation.objectClose;\n              }\n            }\n          }\n        }\n\n        if (closeStatus === 1) {\n          schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n          schemaObj[valueIndex] += joiValidation.objectClose;\n          closeStatus = 0;\n        }\n      } else if (Array.isArray(models) && !status) {\n        for (let arrayIndex of models) {\n          schemaObj[valueIndex] = `${joiValidation.arrayOpen}`;\n          schemaObj[valueIndex] += `joi.object(`;\n          for (let objectIndex in arrayIndex) {\n            if (Array.isArray(objectIndex)) {\n              if (arrayIndex[objectIndex].type) {\n                modelType = getTypes(arrayIndex[objectIndex].type);\n                otherTypes = getOtherTypes(Object.keys(arrayIndex[objectIndex]), Object.values(arrayIndex[objectIndex]));\n                if (otherTypes) {\n                  schemaObj[valueIndex] += `${objectIndex}:${modelType}${otherTypes},`;\n                } else {\n                  schemaObj[valueIndex] += `${objectIndex}:${modelType},`;\n                }\n              } else {\n                modelType = getTypes(arrayIndex[objectIndex]);\n                schemaObj[valueIndex] += `${objectIndex}:${modelType},`;\n              }\n            }\n          }\n          schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n          schemaObj[valueIndex] += ')';\n          schemaObj[valueIndex] += joiValidation.arrayClose;\n        }\n      }\n    }\n    modelTestobj[schemaIndex] = schemaObj;\n    schemaObj = {};\n  }\n  _.each(modelTestobj, (v, x) => {\n    _.each(v, (val, y) => {\n      if (val && !val.includes('required')) {\n        val = `${val}.allow(null).allow('')`;\n        v[y] = val;\n      }\n      v[y] = val;\n      let hasActive = Reflect.has(v, 'isActive');\n      if (!hasActive) {\n        v.isActive = 'joi.boolean()';\n      }\n      let hasDelete = Reflect.has(v, 'isDeleted');\n      if (!hasDelete) {\n        v.isDeleted = 'joi.boolean()';\n      }\n      modelTestobj[x] = v;\n    });\n\n  });\n  updateObj = _.cloneDeep(modelTestobj);\n  _.each(updateObj, (v, y) => {\n    _.each(v, (val, i) => {\n      if (val && val.includes('required')) {\n        val = val.split('.required()').join('.when({is:joi.exist(),then:joi.required(),otherwise:joi.optional()})');\n        v[i] = val;\n      }\n    });\n  });\n\n  modelObj.models = modelTestobj;\n\n  updateModelObj.models = updateObj;\n\n  return { modelObj, updateModelObj };\n}\nfunction getTypes(modelType) {\n  let type;\n  switch (modelType) {\n    case 'String':\n    case 'string':\n    case 'MultiLine':\n      type = 'joi.string()';\n      break;\n\n    case 'Number':\n      type = 'joi.number().integer()';\n      break;\n\n    case 'object':\n    case 'JSON':\n      type = 'joi.object()';\n      break;\n\n    case 'Decimal':\n    case 'Currency':\n      type = 'joi.number()';\n      break;\n\n    case 'ObjectId':\n      type = 'joi.string().regex(/^[0-9a-fA-F]{24}$/)';\n      break;\n\n    case 'Date':\n      type = 'joi.date()';\n      break;\n\n    case 'TimeStamp':\n      type = 'joi.date().timestamp()';\n      break;\n\n    case 'Boolean':\n      type = 'joi.boolean()';\n      break;\n\n    case 'Array':\n      type = 'joi.array().items()';\n      break;\n\n\n    case 'Mixed':\n      type = 'joi.any()';\n      break;\n\n    case 'SingleLine':\n      type = 'joi.string().regex(/^[^\\r\\n]+$/)';\n      break;\n\n    case 'Email':\n      type = 'joi.string().email()';\n      break;\n\n    case 'URL':\n      type = 'joi.string().uri()';\n      break;\n\n    case 'Percentage':\n      type = 'joi.number().min(0).max(100)';\n  }\n  return type;\n\n}\n\nfunction getOtherTypes(key, value) {\n  let type = '';\n  if (Array.isArray(key) && Array.isArray(value)) {\n    for (let i = 0; i < key.length; i++) {\n      if (key[i] === 'required') {\n        if (value[i]) {\n          type = '.required()';\n        }\n      } else if (key[i] === 'default') {\n        if (typeof value[i] === 'string') {\n          type += `.${key[i]}('${value[i]}')`;\n        } else {\n          type += `.${key[i]}(${value[i]})`;\n        }\n      } else if (key[i] === 'trim') {\n        type += '.trim()';\n      } else if (key[i] === 'match') {\n        type += `.regex(${value[i]})`;\n      } else if (key[i] === 'minLength' || key[i] === 'mix') {\n        type += `.min(${value[i]})`;\n      } else if (key[i] === 'maxLength' || key[i] === 'max') {\n        type += `.max(${value[i]})`;\n      } else if (key[i] === 'enum') {\n        if (Array.isArray(value[i])) {\n          value[i] = value[i].join();\n          value[i] = value[i].split(',').map((word) => `'${word.trim()}'`).join(',');\n          type += `.valid(${value[i]})`;\n        } if (typeof value[i] === 'string') {\n          type += `.valid(${value[i]})`;\n        }\n      } else if (key[i] === 'lowercase') {\n        type += '.case(\\'lower\\')';\n      } else if (key[i] === 'uppercase') {\n        type += '.case(\\'upper\\')';\n      } else if (key[i] === 'precision') {\n        type += `.precision(${value[i]})`;\n      }\n    }\n  }\n  return type;\n\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/schemaValidation.js",
    "content": "/* eslint-disable no-else-return */\n/* eslint-disable no-new-func */\n/* eslint-disable no-empty */\n/* eslint-disable valid-typeof */\n/* eslint-disable no-case-declarations */\n/* global _ */\nconst fs = require('fs');\nconst missMatchType = require('../config/possibleMissMatchType');\nconst writeOperations = require('../writeOperations');\n\nfunction readFile (FileName) {\n  return fs.readFileSync(FileName, { encoding: 'utf8' });\n}\nconst mongooseConfiguration = readFile(`${__dirname}/../config/mongooseInput.json`);\nconst jsonMongooseConfig = JSON.parse(mongooseConfiguration);\nconst errorLogs = [];\n\nconst isRegExp = (string) => {\n  try {\n    return new Function(`\n            \"use strict\";\n            try {\n                new RegExp(${string});\n                return true;\n            } catch (e) {\n                return false;\n            }\n        `)();\n  } catch (e) {\n    return false;\n  }\n};\nmodule.exports = {\n  // eslint-disable-next-line consistent-return\n  validSchema (input, logsPath) {\n    try {\n      let valid = true;\n      _.map(input, (modelValue, model) => {\n        _.map(modelValue, (modelObjValue, modelObjKey) => {\n          if (typeof input[model][modelObjKey] === 'object' && !Array.isArray(input[model][modelObjKey])) {\n            const item = input[model][modelObjKey];\n            valid = this.validSchemaObject(item, input, model);\n            if (!valid) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = modelObjKey;\n              errorLogs.push(errObj);\n              /*\n               * let msg = `${model} model and attribute ${modelObjKey} is not valid.`;\n               * writeFile(errorLogFile, msg);\n               * msg = '#########################################';\n               * writeFile(errorLogFile, msg);\n               */\n            }\n            // throw new Error(`${modelObjKey} Model Schema is not valid`);\n          } else if (Array.isArray(modelObjValue)) {\n            // console.log(modelObjValue, \"Model OBJ value\")\n            if (modelObjKey !== 'enum') {\n              const item = input[model][modelObjKey];\n              valid = this.validSchemaObject(item, input, model);\n              if (!valid) {\n                const errObj = {};\n                errObj.model = model;\n                errObj.attribute = modelObjKey;\n                errorLogs.push(errObj);\n                /*\n                 * let msg = `${model} model and attribute ${modelObjKey} is not valid.`;\n                 * writeFile(errorLogFile, msg);\n                 * msg = '#########################################';\n                 * writeFile(errorLogFile, msg);\n                 */\n              }\n            }\n            // throw new Error(`${modelObjKey} Model Schema is not valid`);\n          } else {\n            const item = input[model];\n            // console.log(modelObjKey,\" \",modelObjValue);\n            if (jsonMongooseConfig.model.key.type.includes(modelObjValue)) {\n              if (modelObjValue === 'ObjectId') {\n                item[modelObjKey] = 'Schema.Types.ObjectId';\n              } else if (modelObjValue === 'Mixed' || modelObjValue === 'JSON' || modelObjValue === 'Object') {\n                item[modelObjKey] = 'Schema.Types.Mixed';\n              }\n            } else {\n              valid = false;\n            }\n            // console.log(valid, \"valid in type\")\n            if (!valid) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = modelObjKey;\n              errorLogs.push(errObj);\n              /*\n               * let msg = `${modelObjKey} in ${model} Schema is not valid`;\n               * writeFile(errorLogFile, msg);\n               * msg = '#########################################';\n               * writeFile(errorLogFile, msg);\n               */\n            }\n            // throw new Error(`${modelObjKey} in ${model} Schema is not valid`);\n          }\n        });\n        /*\n         * set IsDelete and IsActive Field\n         * if (!modelValue.isDeleted) {\n         */\n        modelValue.isDeleted = { type: 'Boolean' };\n        /*\n         * }\n         * if (!modelValue.isActive) {\n         */\n        modelValue.isActive = { type: 'Boolean' };\n\n        if (!_.isEmpty(modelValue._id)) {\n          delete modelValue._id;\n        }\n        // }\n      });\n      if (valid) {\n        return input;\n      }\n      /*\n       * const msg = 'not valid schema';\n       * writeFile(errorLogFile, msg);\n       * throw new Error(\"not valid schema\");\n       */\n    } catch (error) {\n      /*\n       * const msg = error.message;\n       * writeFile(errorLogFile, msg);\n       */\n      throw new Error(error);\n    } finally {\n      if (errorLogs.length) {\n        const errorTemplate = writeOperations.loadTemplate('logs/error.log');\n        errorTemplate.locals.ERRORS = errorLogs;\n        writeOperations.write(`${logsPath}/errors.log`, errorTemplate.render());\n      }\n      // console.log(errorLogs);\n    }\n  },\n  validSchemaObject (item, input, model) {\n    let valid = true;\n    const possibleKeys = Object.keys(jsonMongooseConfig.model.key);\n    _.map(item, (data, key) => {\n      /*\n       * if ((_.isEmpty(_.trim(data)) || data === '')) {\n       *   delete item[key];\n       *   key = '';\n       * }\n       * if (key) {\n       */\n      if (possibleKeys.includes(key) && typeof data !== 'object') {\n        switch (key) {\n        case 'type':\n          if (!jsonMongooseConfig.model.key[key].includes(data)) {\n            // console.log(\"not valid \", key,\" \", data)\n            if (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = key;\n              errObj.value = data;\n              errObj.suggestion = `type should be from  ${jsonMongooseConfig.model.key[key].join()}.`;\n              errorLogs.push(errObj);\n              /*\n               * const msg = `${model} model and it's attribute ${key} and value ${data} is not supported by mongoose.\n               *               solution: type should be from  ${jsonMongooseConfig.model.key[key].join()}.`;\n               * writeFile(errorLogFile, msg);\n               */\n              valid = false;\n            }\n          }\n          if (data === 'ObjectId') {\n            item[key] = 'Schema.Types.ObjectId';\n          } else if (data === 'Mixed' || data === 'JSON' || data === 'Object') {\n            item[key] = 'Schema.Types.Mixed';\n          }\n          // console.log(valid, \"valid in type\")\n          break;\n        case 'ref':\n          const modelKey = Object.keys(input);\n          if (!modelKey.includes(data) && typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n            /*\n             * const msg = `reference error!!! ${model} model and it's attribute ${key} and value ${data} is not included in models names.\n             *               solution: reference should be from your models- ${modelKey.join()}.`;\n             * writeFile(errorLogFile, msg);\n             */\n            const errObj = {};\n            errObj.message = 'reference error !!!';\n            errObj.model = model;\n            errObj.attribute = key;\n            errObj.value = data;\n            errObj.suggestion = `Reference should be from your models - ${modelKey.join()}.`;\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          if (valid) {\n            if (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) {\n              item[key] = `##${data}##`;\n            } else {\n              item[key] = `@@${data}@@`;\n            }\n          }\n          // console.log(valid, \"valid in ref\");\n          break;\n        case 'index':\n        case 'unique':\n        case 'alias':\n        case 'lowercase':\n        case 'trim':\n        case 'required':\n        case 'immutable':\n        case 'sparse':\n        case 'minLength':\n        case 'maxLength':\n        case 'of':\n          valid = this.checkTypeInSchema(key, data);\n          if (valid === true && key === 'unique' && item.type === 'String') {\n            item.uniqueCaseInsensitive = true;\n          } else if (valid === true && (key === 'alias' || key === 'of')) {\n            if (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) {\n              item[key] = `##${data}##`;\n            } else {\n              item[key] = `@@${data}@@`;\n            }\n          }\n          // console.log(valid, \"valid in \" + key)\n          break;\n        case 'default':\n          // console.log(item.type,\" item type\")\n          // eslint-disable-next-line valid-typeof\n          /*\n           * if ((typeof data === item.type.toLowerCase()) || (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`'))) {\n           *   if (typeof data === 'string') {\n           *     item[key] = `@@${data}@@`;\n           *   }\n           * }\n           */\n          if ((typeof data === item.type.toLowerCase()) || (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) || (typeof data === 'string' && item.type === 'Date')) {\n            if (typeof data === 'string') {\n              if (data.startsWith('`${') && data.endsWith('}`')) {\n                item[key] = `##${data}##`;\n              } else {\n                item[key] = `@@${data}@@`;\n              }\n            }\n          } else if (typeof data === 'number' || typeof data === 'boolean' || typeof data === 'undefined') {\n            item[key] = `@@${data}@@`;\n          } else {\n            /*\n             * const msg = `${model} model and it's attribute default and value ${data} must have same datatype as attribute.\n             *               solution: default value's type should be ${item.type}.`;\n             * writeFile(errorLogFile, msg);\n             */\n            const errObj = {};\n            errObj.model = model;\n            errObj.attribute = 'default';\n            errObj.value = data;\n            errObj.message = 'value must have same datatype as attribute.';\n            errObj.suggestion = `default value's type should be ${item.type}.`;\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          break;\n        case 'enum':\n          if (Array.isArray(data) || !(_.startsWith(data, '`${') && _.endsWith(data, '}`'))) {\n            /*\n             * const msg = `${model} model and it's attribute enum and value ${data} must have array or a function that returns an array`;\n             * writeFile(errorLogFile, msg);\n             */\n            const errObj = {};\n            errObj.model = model;\n            errObj.attribute = 'enum';\n            errObj.value = data;\n            errObj.suggestion = 'value must have array or a function that returns an array.';\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          // console.log(valid, \"valid in enum\")\n          break;\n        case 'validate':\n          break;\n        case 'get':\n          break;\n        case 'set':\n          break;\n        case 'transform':\n          break;\n        case 'match':\n          if (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n            const validRegex = isRegExp(data);\n            if (!validRegex) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = 'match';\n              errObj.value = data;\n              errObj.message = 'not a valid regular expression.';\n              errorLogs.push(errObj);\n              valid = false;\n            }\n            item[key] = data;\n          }\n          break;\n        case 'populate':\n          break;\n        case 'min':\n          /*\n           * _.map(jsonMongooseConfig.model.key[key], (v) => {\n           *   if (v !== typeof (data)) {\n           *     valid = false;\n           *   }\n           * });\n           * console.log(valid, \"valid in min\")\n           */\n          if (item.type === 'Number') {\n            if ((jsonMongooseConfig.model.key.min[0] !== typeof data) || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          } else if (item.type === 'Date') {\n            if (jsonMongooseConfig.model.key.min[1] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          }\n          break;\n        case 'max':\n          /*\n           * _.map(jsonMongooseConfig.model.key[key], (v) => {\n           *   if (v !== typeof (data)) {\n           *     valid = false;\n           *   }\n           * });\n           */\n          if (item.type === 'Number') {\n            if (jsonMongooseConfig.model.key.max[0] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          } else if (item.type === 'Date') {\n            if (jsonMongooseConfig.model.key.max[1] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          }\n          // console.log(valid, \"valid in max\")\n          break;\n        default:\n          break;\n        }\n        /*\n         * if (!valid) {\n         *     let msg = `Model schema is not valid at ${key} and value ${data}.`;\n         *     writeFile(errorLogFile, msg);\n         *     // throw new Error(`Schema is not valid at ${key} and value ${data}.`);\n         * }\n         */\n      } else if (typeof data === 'object' && !Array.isArray(data)) {\n        valid = this.validSchemaObject(data, input, model);\n      } else if (Array.isArray(data)) {\n        valid = this.validSchemaObject(data, input, model);\n      } else if ((jsonMongooseConfig.model.key.type.includes(data)) || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n        // console.log(\"no type key\");\n        if (data === 'ObjectId') {\n          item[key] = 'Schema.Types.ObjectId';\n        } else if (data === 'Mixed' || data === 'JSON' || data === 'Object') {\n          item[key] = 'Schema.Types.Mixed';\n        }\n      } else if (key === 'columnType' || (key === '_id' && typeof data === 'boolean')) {\n        delete item[key];\n      } else {\n        valid = false;\n        /*\n         * const msg = `${model} model and it's attribute ${key} and value ${data} is not supported by mongoose.\n         *                     solution: Did you mean ${missMatchType.getCorrectName(key)} ?`;\n         * writeFile(errorLogFile, msg);\n         */\n        const suggestionKey = missMatchType.getCorrectName(key);\n        const errObj = {};\n        errObj.model = model;\n        errObj.attribute = key;\n        errObj.value = data;\n        errObj.suggestion = suggestionKey ? `Did you mean ${missMatchType.getCorrectName(key)} ?` : '';\n        errorLogs.push(errObj);\n        // throw new Error(`Schema is not valid at ${key} and value ${data}.`);\n      }\n      // }\n    });\n    return valid;\n  },\n  checkTypeInSchema (key, data) {\n    // eslint-disable-next-line valid-typeof\n    if (!(jsonMongooseConfig.model.key[key] === typeof (data)) && !(typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`'))) {\n      return false;\n    }\n    return true;\n  },\n\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/composeModels.js",
    "content": "/* eslint-disable no-restricted-syntax */\n/* eslint-disable guard-for-in */\n/* eslint-disable no-shadow */\nconst {\n  isEmpty, forEach, groupBy, clone, cloneDeep,\n} = require('lodash');\nconst { flatten } = require('flat');\nconst writeOperations = require('../../writeOperations');\nconst {\n  getSQLRelationshipDependencies, getSQLUniqueIndexesForRelationship,\n} = require('../getDeleteDependency');\nconst { SEQUELIZE_INDEX_TYPE } = require('../../constants/constant');\n\nconst renameKey = (object, key, newKey) => {\n  const clonedObj = clone(object);\n  if (Object.keys(clonedObj).length > 0) {\n    Object.keys(clonedObj).forEach((s) => {\n      clonedObj[s][newKey] = clonedObj[s][key];\n      delete clonedObj[s][key];\n    });\n  } else {\n    const targetKey = clonedObj[key];\n    delete clonedObj[key];\n    clonedObj[newKey] = targetKey;\n  }\n  return clonedObj;\n};\n\nconst parseEnum = (object, constants) => {\n  const clonedObj = clone(object);\n  if (Object.keys(clonedObj).length) {\n    Object.keys(clonedObj).forEach((k) => {\n      const element = clonedObj[k];\n      const { enumFile } = element;\n      const { enumAttribute } = element;\n      const enumValues = constants?.[enumFile]?.[enumAttribute];\n      if (Array.isArray(enumValues)) {\n        clonedObj[k].default = [enumValues.indexOf(element.default)] ?? [0];\n      }\n    });\n  }\n  return clonedObj;\n};\n\nconst concatAttributes = (finalJSON, obj) => {\n  const array = [];\n  const stringAttributeArray = [];\n  let internalObj = {};\n  let formate;\n  let flag = false;\n  for (const index of finalJSON) {\n    switch (index.dataType) {\n    case 'string':\n      if (index.operator === 'space') {\n        formate = `values.${index.attribute[0]}.toString().concat(\" \",`;\n      } else {\n        formate = `values.${index.attribute[0]}.toString().concat(\"${index.operator}\",`;\n      }\n      if (index.attribute.length >= 1) {\n        formate += `values.${index.attribute[1]}.toString())`;\n      } else {\n        formate += ')';\n      }\n      stringAttributeArray.push(index.attribute[0]);\n      stringAttributeArray.push(index.attribute[1]);\n      internalObj[index.targetAttr] = formate;\n      break;\n\n    case 'boolean':\n      if (obj.boolKeys) {\n        for (const boolIndex of obj.boolKeys) {\n          const nestObj = {};\n          nestObj.true = index.attribute.true;\n          nestObj.false = index.attribute.false;\n          internalObj[boolIndex] = nestObj;\n        }\n      } else {\n        const nestObj = {};\n        nestObj.true = index.attribute.true;\n        nestObj.false = index.attribute.false;\n        internalObj[index.targetAttr] = nestObj;\n      }\n      break;\n\n    case 'date':\n      if (obj.dateKeys) {\n        for (const dateIndex of obj.dateKeys) {\n          internalObj[dateIndex] = `dayjs(values.${dateIndex}).format('${index.attribute}')`;\n        }\n      } else {\n        internalObj[index.targetAttr] = `dayjs(${internalObj[index.targetAttr]}).format('${index.attribute}')`;\n      }\n      flag = true;\n      break;\n\n    case 'DateOnly':\n      if (obj.dateOnlyKey) {\n        for (const dateOnlyIndex of obj.dateOnlyKey) {\n          internalObj[dateOnlyIndex] = `dayjs(values.${dateOnlyIndex}).format('${index.attribute}')`;\n        }\n      } else {\n        internalObj[index.targetAttr] = `dayjs(${internalObj[index.targetAttr]}).format('${index.attribute}')`;\n      }\n      break;\n    default:\n      break;\n    }\n    array.push(internalObj);\n    internalObj = {};\n  }\n  return {\n    array,\n    stringAttributeArray,\n    flag,\n  };\n};\n\nconst createModels = async (dir, jsonData, forValidationModels, modelData, authObject = false) => {\n  let alreadyDoneUser = false;\n  const allEJSModel = {};\n  let tableRelationships = {};\n  if (modelData && modelData.models) {\n    const sqlRelationShip = getSQLRelationshipDependencies(modelData.models);\n    const uniqueIndexForRelationships = getSQLUniqueIndexesForRelationship(modelData.models);\n    const deleteDependency = sqlRelationShip;\n    const index = writeOperations.loadTemplate(`${dir}/index.js`);\n    const modelIndexesJson = jsonData.modelIndexes ? jsonData.modelIndexes : {};\n    if (isEmpty(jsonData.hooks)) Object.assign(jsonData, { hooks: {} });\n    if (Object.keys(uniqueIndexForRelationships).length) {\n      Object.keys(uniqueIndexForRelationships).forEach((ui) => {\n        jsonData.models[ui][uniqueIndexForRelationships[ui]].unique = true;\n      });\n    }\n    forEach(jsonData.models, (value, key) => {\n      const model = writeOperations.loadTemplate(`${dir}/model.js`);\n      if (authObject) {\n        if (authObject.userModel !== '' && authObject.isAuth && !alreadyDoneUser && key === authObject.userModel) {\n          model.locals.IS_AUTH = authObject.isAuth;\n          model.locals.USER = true;\n          model.locals.PASSWORD = authObject.userLoginWith?.password || 'password';\n          value.role = {\n            type: 'DataTypes.INTEGER',\n            required: true,\n          };\n          alreadyDoneUser = true;\n          if (!jsonData.hooks[key]) {\n            Object.assign(jsonData.hooks, { [key]: {} });\n          }\n          if (!jsonData.hooks[key].pre) {\n            Object.assign(jsonData.hooks[key], { pre: [] });\n          }\n          if (!jsonData.hooks[key].post) {\n            Object.assign(jsonData.hooks[key], { post: [] });\n          }\n          jsonData.hooks[key].pre.push({\n            operation: 'beforeCreate',\n            code: `if(${key}.${authObject.userLoginWith?.password || 'password'}){ ${key}.${authObject.userLoginWith?.password || 'password'} =\n          await bcrypt.hash(${key}.${authObject.userLoginWith?.password || 'password'}, 8);}\\n${key}.isActive=true;\\n${key}.isDeleted=false`,\n          });\n          jsonData.hooks[key].post.push({\n            operation: 'afterCreate',\n            code: `sequelize.model('userAuthSettings').create({\n            userId:${key}.id\n          })`,\n          });\n\n          if (authObject.socialAuth !== undefined && authObject.socialAuth.required) {\n            const ssoAuthKeys = {};\n            for (let i = 0; i < authObject.socialAuth.platforms.length; i += 1) {\n              Object.assign(ssoAuthKeys, { [`${authObject.socialAuth.platforms[i].type.toLowerCase()}Id`]: { type: 'DataTypes.STRING' } });\n            }\n            const entries = Object.entries(value);\n            for (let i = 0; i < entries.length; i += 1) {\n              const [k] = entries[i];\n              if (k.includes('SSO'.toLowerCase())) {\n                delete value[k];\n              }\n            }\n            Object.assign(value, ssoAuthKeys);\n          }\n        } else {\n          model.locals.IS_AUTH = false;\n          model.locals.USER = false;\n        }\n      } else {\n        model.locals.USER = false;\n      }\n      if (key !== authObject.userModel) {\n        if (!jsonData.hooks[key]) {\n          Object.assign(jsonData.hooks, { [key]: {} });\n        }\n        if (!jsonData.hooks[key].pre) {\n          Object.assign(jsonData.hooks[key], { pre: [] });\n        }\n        const modelName = key;\n        jsonData.hooks[key].pre.push({\n          operation: 'beforeCreate',\n          code: `${modelName}.isActive=true;\\n${modelName}.isDeleted=false`,\n        });\n        jsonData.hooks[key].pre.push({\n          operation: 'beforeBulkCreate',\n          // eslint-disable-next-line max-len\n          code: `if (${modelName} !== undefined && ${modelName}.length) { \\n for (let index = 0; index < ${modelName}.length; index++) { \\n const element = ${modelName}[index]; \\n element.isActive = true; \\n element.isDeleted = false; \\n } \\n }`,\n        });\n      }\n      const modelArrayIndexes = [];\n      if (modelIndexesJson) {\n        // eslint-disable-next-line array-callback-return\n        Object.keys(modelIndexesJson).map((i) => {\n          if (i === key) {\n            const currentIndexModel = cloneDeep(value);\n            const modelIndexes = modelIndexesJson[i];\n            // if (Object.keys(modelIndexesJson[key]).length) {\n            if (modelIndexes.length) {\n              let fieldsArray = [];\n              // eslint-disable-next-line no-shadow\n              for (let index = 0; index < modelIndexes.length; index += 1) {\n                const element = modelIndexes[index];\n                if (element.indexType === SEQUELIZE_INDEX_TYPE.UNIQUE) {\n                  if (element.fields.length) {\n                    fieldsArray = element.fields ?? [];\n                  }\n                  if (fieldsArray.length) {\n                    modelArrayIndexes.push({\n                      unique: true,\n                      fields: fieldsArray,\n                      name: `${key}_unique_indexes_${Math.floor((Math.random() * 1000000) + 1)}`,\n                    });\n                  }\n                }\n                if (element.indexType === SEQUELIZE_INDEX_TYPE.BTREE) {\n                  const customizedFieldsArray = [];\n                  if (element.indexFields !== undefined && element.indexFields.length) {\n                    // ? Operation for remove collate key in BTree index for sequelize\n                    for (let mIndex = 0; mIndex < element.indexFields.length; mIndex += 1) {\n                      const customFields = element.indexFields[mIndex];\n                      if ('collate' in customFields) {\n                        delete customFields.collate;\n                      }\n                      const x = currentIndexModel[customFields.attribute].type;\n                      if (x === 'DataTypes.INTEGER' && 'length' in customFields) {\n                        delete customFields.length;\n                      }\n                      customizedFieldsArray.push(customFields);\n                    }\n                  }\n                  modelArrayIndexes.push({\n                    using: element.indexType,\n                    fields: customizedFieldsArray,\n                    name: `${element.name}_index_${Math.floor((Math.random() * 1000000) + 1)}`,\n                  });\n                }\n                if (element.indexType === SEQUELIZE_INDEX_TYPE.PARTIAL) {\n                  if (element.indexFields && element.indexFields.length) {\n                    const fields = element.fields ?? [];\n                    if (fields.length > 0) {\n                      for (let jIndex = 0; jIndex < element.indexFields.length; jIndex += 1) {\n                        if (fields.includes(element.indexFields[jIndex].attribute)) {\n                          modelArrayIndexes.push({\n                            name: `${key}_${element.indexFields[jIndex].attribute}_partial_index`,\n                            fields: [element.indexFields[jIndex].attribute],\n                            where: { [element.indexFields[jIndex].operator]: element.indexFields[jIndex].value },\n                          });\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        });\n      }\n      model.locals.INDEX = modelArrayIndexes;\n      model.locals.DB_MODEL = key;\n      model.locals.DB_MODEL_FC = key.charAt(0).toUpperCase() + key.slice(1);\n      model.locals.DB_SCHEMA = value;\n      let deleteModels = [];\n      // eslint-disable-next-line no-restricted-syntax\n      for (const k in deleteDependency) {\n        if (k === key) {\n          deleteModels = deleteDependency[k];\n          break;\n        } else {\n          deleteModels = [];\n        }\n      }\n      if (deleteModels.length) {\n        model.locals.DELETE_DEPENDENT_MODEL = deleteModels;\n      } else {\n        model.locals.DELETE_DEPENDENT_MODEL = false;\n      }\n      if (jsonData.hooks && jsonData.hooks[key]) {\n        let hooks = [];\n        if (jsonData.hooks[key].pre) {\n          hooks.push(...jsonData.hooks[key].pre);\n        }\n        if (jsonData.hooks[key].post) {\n          hooks.push(...jsonData.hooks[key].post);\n        }\n        hooks = groupBy(hooks, 'operation');\n        model.locals.HOOKS = hooks;\n      }\n      if (!isEmpty(jsonData.modelEnum) && !isEmpty(jsonData.modelEnum[key])) {\n        const allConstants = jsonData.constants;\n        parseEnum(jsonData.modelEnum[key], allConstants);\n        renameKey(jsonData.modelEnum[key], 'default', 'defaultValue');\n        renameKey(jsonData.modelEnum[key], 'enumAttribute', 'values');\n        // const constantForCurrentModel = allConstants[jsonData.modelEnum[key].enumFile[jsonData.modelEnum[key].enumAttribute]];\n        model.locals.MODEL_ENUM = jsonData.modelEnum[key];\n        model.locals.IMPORT_KEY = Object.keys(jsonData.modelEnum[key]);\n      } else {\n        model.locals.MODEL_ENUM = false;\n      }\n      index.locals.RELATIONSHIPS = sqlRelationShip;\n      let privateAttributeArray;\n      if (!isEmpty(jsonData.modelPrivate)) {\n        // ? model private attribute\n        if (!isEmpty(jsonData.modelPrivate[key])) {\n          privateAttributeArray = flatten(jsonData.modelPrivate[key]);\n          if (!isEmpty(privateAttributeArray) && Object.keys(privateAttributeArray).length) {\n            const privateAttributeObject = {};\n            // eslint-disable-next-line array-callback-return\n            Object.keys(privateAttributeArray).map((m) => {\n              if (privateAttributeArray[m]) {\n                Object.assign(privateAttributeObject, { [m.split('.private').join('')]: true });\n              }\n            });\n            model.locals.IS_PRIVATE_ATTR = true;\n            model.locals.PRIVATE_ATTRS = privateAttributeObject;\n          } else {\n            model.locals.IS_PRIVATE_ATTR = true;\n          }\n        } else {\n          model.locals.IS_PRIVATE_ATTR = false;\n        }\n      } else {\n        model.locals.IS_PRIVATE_ATTR = false;\n      }\n      if (!isEmpty(jsonData.authentication.addDataFormate)) {\n        jsonData.addDataFormate = jsonData.authentication.addDataFormate;\n        let boolKeys = []; let dateKeys = []; const dateOnlyKey = [];\n        for (const index in value) {\n          if (value[index].type === 'DataTypes.BOOLEAN') {\n            boolKeys.push(index);\n          } if (value[index].type === 'DataTypes.DATE') {\n            dateKeys.push(index);\n          } if (value[index].type === 'DataTypes.DATEONLY') {\n            dateOnlyKey.push(index);\n          }\n        }\n        if (jsonData.addDataFormate[key]) {\n          Array.prototype.push.apply(jsonData.addDataFormate[key], jsonData.addDataFormate.allModels_data_format);\n        } else {\n          jsonData.addDataFormate[key] = jsonData.addDataFormate.allModels_data_format;\n        }\n        let formateArray = [];\n        if (jsonData.addDataFormate[key]) {\n          formateArray = concatAttributes(jsonData.addDataFormate[key], {\n            boolKeys,\n            dateKeys,\n            dateOnlyKey,\n          });\n          model.locals.CONCAT_HOOK = formateArray.array;\n          model.locals.STRING_ATT = formateArray.stringAttributeArray;\n          model.locals.FLAG = formateArray.flag;\n          boolKeys = [];\n          dateKeys = [];\n        }\n      } else {\n        model.locals.CONCAT_HOOK = false;\n      }\n      allEJSModel[key] = model;\n    });\n    if (isEmpty(jsonData.virtualRelationship)) {\n      index.locals.VIRTUAL_RELATION = undefined;\n    } else {\n      index.locals.VIRTUAL_RELATION = jsonData.virtualRelationship;\n    }\n    tableRelationships = index;\n    return {\n      deleteDependency,\n      allEJSModel,\n      tableRelationships,\n    };\n  }\n  return {};\n};\nmodule.exports = { createModels };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/modelValiadation.js",
    "content": "/* global  _ */\nconst fs = require('fs');\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\nconst { SEQUELIZE_DATATYPE_MAPPING_WITH_JAVASCRIPT } = require('../../constants/constant');\n\nfunction readFile (FileName) {\n  return fs.readFileSync(FileName, { encoding: 'utf8' });\n}\nconst sequelizeConfiguration = readFile(path.join(__dirname, '../../config/sequelizeTypeInput.json'));\nconst jsonSequelizeConfig = JSON.parse(sequelizeConfiguration);\nconst errorLogs = [];\n\nconst isRegExp = (string) => {\n  try {\n    // eslint-disable-next-line no-new-func\n    return new Function(`\n              \"use strict\";\n              try {\n                  new RegExp(${string});\n                  return true;\n              } catch (e) {\n                  return false;\n              }\n          `)();\n  } catch (e) {\n    return false;\n  }\n};\n\nmodule.exports = {\n  // eslint-disable-next-line consistent-return\n  validSchema (input, logsPath) {\n    try {\n      let valid = true;\n      _.map(input, (modelValue, model) => {\n        _.map(modelValue, (modelObjValue, modelObjKey) => {\n          if (typeof input[model][modelObjKey] === 'object' && !Array.isArray(input[model][modelObjKey])) {\n            const item = input[model][modelObjKey];\n            valid = this.validSchemaObject(item, input, model);\n            if (!valid) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = modelObjKey;\n              errorLogs.push(errObj);\n            }\n          }\n        });\n      });\n      if (valid) {\n        return input;\n      }\n    } catch (error) {\n      throw new Error(error);\n    } finally {\n      if (errorLogs.length) {\n        const errorTemplate = writeOperations.loadTemplate('logs/error.log');\n        errorTemplate.locals.ERRORS = errorLogs;\n        writeOperations.write(`${logsPath}/errors.log`, errorTemplate.render());\n      }\n    }\n  },\n  validSchemaObject (item, input, model) {\n    let valid = true;\n    const possibleKeys = Object.keys(jsonSequelizeConfig.model.key);\n    _.map(item, (data, key) => {\n      if ((_.isEmpty(_.trim(data)) || data === '')) {\n        delete item[key];\n        key = '';\n      }\n      if (possibleKeys.includes(key) && typeof data !== 'object') {\n        switch (key) {\n        case 'type':\n          if (!jsonSequelizeConfig.model.key[key].includes(data)) {\n            if (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = key;\n              errObj.value = data;\n              errObj.suggestion = `type should be from  ${jsonSequelizeConfig.model.key[key].join()}.`;\n              errorLogs.push(errObj);\n              valid = false;\n            }\n          }\n          break;\n        case 'ref':\n          // eslint-disable-next-line no-case-declarations\n          const modelKey = Object.keys(input);\n          if (!modelKey.includes(data) && typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n            const errObj = {};\n            errObj.message = 'reference error !!!';\n            errObj.model = model;\n            errObj.attribute = key;\n            errObj.value = data;\n            errObj.suggestion = `Reference should be from your models - ${modelKey.join()}.`;\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          if (valid) {\n            if (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) {\n              item[key] = `##${data}##`;\n            } else {\n              item[key] = `@@${data}@@`;\n            }\n          }\n          break;\n        case 'refAttribute':\n          // eslint-disable-next-line no-case-declarations\n          const refModel = item.ref !== undefined && item.ref !== null ? item.ref.split('@').join('') : '';\n          // eslint-disable-next-line no-case-declarations\n          const refModelKey = Object.keys(input[refModel]);\n          if (!refModelKey.includes(data) && typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n            const errObj = {};\n            errObj.message = 'reference error !!!';\n            errObj.model = model;\n            errObj.attribute = key;\n            errObj.value = data;\n            errObj.suggestion = `Reference should be from your models - ${refModelKey.join()}.`;\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          if (valid) {\n            if (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) {\n              item[key] = `##${data}##`;\n            } else {\n              item[key] = `@@${data}@@`;\n            }\n          }\n          break;\n        case 'default':\n          // eslint-disable-next-line valid-typeof\n          if ((typeof data === SEQUELIZE_DATATYPE_MAPPING_WITH_JAVASCRIPT[item.type]) || (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`'))) {\n            if (typeof data === 'string') {\n              if (data.startsWith('`${') && data.endsWith('}`')) {\n                item[key] = `##${data}##`;\n              } else {\n                item[key] = `@@${data}@@`;\n              }\n            } else if (typeof data === 'boolean') {\n              item[key] = data;\n            } else if (typeof data === 'number') {\n              item[key] = data;\n            }\n            // eslint-disable-next-line max-len\n          } else if (typeof data === 'number' || typeof data === 'boolean' || typeof data === 'string' || typeof data === 'undefined') {\n            // ? add condition for enum's validation\n            item[key] = `@@${data}@@`;\n          } else {\n            const errObj = {};\n            errObj.model = model;\n            errObj.attribute = 'default';\n            errObj.value = data;\n            errObj.message = 'value must have same datatype as attribute.';\n            errObj.suggestion = `default value's type should be ${item.type}.`;\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          break;\n        case 'enum':\n          if (Array.isArray(data) || !(_.startsWith(data, '`${') && _.endsWith(data, '}`'))) {\n            const errObj = {};\n            errObj.model = model;\n            errObj.attribute = 'enum';\n            errObj.value = data;\n            errObj.suggestion = 'value must have array or a function that returns an array.';\n            errorLogs.push(errObj);\n            valid = false;\n          }\n          // console.log(valid, \"valid in enum\")\n          break;\n        case 'min':\n          if (item.type === 'Number') {\n            // eslint-disable-next-line valid-typeof\n            if ((jsonSequelizeConfig.model.key.min[0] !== typeof data) || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          } else if (item.type === 'Date') {\n            // eslint-disable-next-line valid-typeof\n            if (jsonSequelizeConfig.model.key.min[1] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          }\n          break;\n        case 'max':\n          if (item.type === 'Number') {\n            // eslint-disable-next-line valid-typeof\n            if (jsonSequelizeConfig.model.key.max[0] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          } else if (item.type === 'Date') {\n            // eslint-disable-next-line valid-typeof\n            if (jsonSequelizeConfig.model.key.max[1] !== typeof data || (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`'))) {\n              valid = false;\n            }\n          }\n          break;\n        case 'lowercase':\n        case 'trim':\n        case 'required':\n        case 'unique':\n        case 'isAutoIncrement':\n        case 'tiny':\n        case 'primary':\n        case 'relType':\n          valid = this.checkTypeInSchema(key, data);\n          if (valid === true && key === 'unique' && item.type === 'String') {\n            item.uniqueCaseInsensitive = true;\n          } else if (valid === true && (key === 'alias' || key === 'of')) {\n            if (typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`')) {\n              item[key] = `##${data}##`;\n            } else {\n              item[key] = `@@${data}@@`;\n            }\n          }\n          break;\n        case 'innerDataType':\n          if (!jsonSequelizeConfig.model.key[key].includes(data)) {\n            if (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = key;\n              errObj.value = data;\n              errObj.suggestion = `type should be from  ${jsonSequelizeConfig.model.key[key].join()}.`;\n              errorLogs.push(errObj);\n              valid = false;\n            }\n          }\n          break;\n        case 'match':\n          if (typeof data === 'string' && !data.startsWith('`${') && !data.endsWith('}`')) {\n            const validRegex = isRegExp(data);\n            if (!validRegex) {\n              const errObj = {};\n              errObj.model = model;\n              errObj.attribute = 'match';\n              errObj.value = data;\n              errObj.message = 'not a valid regular expression.';\n              errorLogs.push(errObj);\n              valid = false;\n            }\n            item[key] = data;\n          }\n          break;\n        default:\n          break;\n        }\n      }\n    });\n    return valid;\n  },\n  checkTypeInSchema (key, data) {\n    // eslint-disable-next-line valid-typeof\n    if (!(jsonSequelizeConfig.model.key[key] === typeof (data)) && !(typeof data === 'string' && data.startsWith('`${') && data.endsWith('}`'))) {\n      return false;\n    }\n    return true;\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/postman/generate-postman-collection.js",
    "content": "const uuid4 = require('uuid').v4;\nconst {\n  clone, isEmpty,\n} = require('lodash');\n\nconst renameKey = (object, key, newKey) => {\n  const clonedObj = clone(object);\n  const targetKey = clonedObj[key];\n  delete clonedObj[key];\n  clonedObj[newKey] = targetKey;\n  return clonedObj;\n};\nconst postman = require('postman-collection');\nglobal._ = require('lodash');\n\nmodule.exports = {\n  async createCollectionV2_0 (info, platform = true) {\n    const mainObj = {};\n    const infoObj = {};\n\n    const mainItem = [];\n    // Project Details\n    infoObj.name = info.project.name;\n    infoObj._postman_id = uuid4();\n    infoObj.description = info.project.description;\n    infoObj.schema = 'https://schema.getpostman.com/json/collection/v2.0.0/collection.json';\n\n    const body = {\n      mode: '',\n      raw: '',\n    };\n    const header = [\n      {\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n      },\n    ];\n    body.mode = 'raw';\n    body.raw = '{}';\n\n    if (platform) {\n      info.item.forEach((e) => {\n        const modelItem = [];\n        e.item.forEach((ej) => {\n          const item = [];\n          ej.request?.forEach((r) => {\n            const request = {\n              url: '',\n              method: '',\n              header: null,\n              body: null,\n              description: '',\n              auth: '',\n            };\n            const itemData = {\n              name: '',\n              request: null,\n              response: null,\n              _postman_isSubFolder: true,\n            };\n            request.url = r.url;\n            request.method = r.method;\n            request.header = r.header ? r.header : header;\n            request.body = r.body ? r.body : body;\n            request.auth = r.auth || {};\n\n            // set Item Data\n            itemData.name = r.name;\n\n            itemData.request = request;\n            itemData.response = r.response;\n            item.push(itemData);\n          });\n\n          const modelItemData = {\n            name: null,\n            description: null,\n            item: null,\n          };\n          modelItemData.name = ej.name;\n          modelItemData.description = ej.desc;\n          modelItemData.item = item;\n          modelItem.push(modelItemData);\n        });\n\n        const mainItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        mainItemData.name = e.name;\n        mainItemData.description = e.description;\n        mainItemData.item = modelItem;\n\n        // main Item Data push into main Item\n\n        mainItem.push(mainItemData);\n      });\n    } else {\n      info.item.forEach((e) => {\n        const item = [];\n        e.request.forEach((r) => {\n          const responseObject = {};\n          const request = {\n            url: '',\n            method: '',\n            header: null,\n            body: null,\n            description: '',\n          };\n          const itemData = {\n            name: '',\n            request: null,\n            response: null,\n          };\n          request.url = r.url;\n          request.method = r.method;\n          request.header = header;\n          request.body = r.body ? r.body : body;\n\n          // set Item Data\n          itemData.name = r.name;\n\n          itemData.request = request;\n          responseObject.name = `${r.name}_response`;\n          responseObject.originalRequest = {\n            method: r.method,\n            header: r.header ? r.header : header,\n            url: { raw: r.url },\n          };\n          responseObject.status = 'OK';\n          responseObject.code = 200;\n          responseObject._postman_previewlanguage = 'json';\n          if (Object.keys(r.body ?? body).length) {\n            if (Object.keys(r.body ?? body).includes('raw')) {\n              if (r.body !== undefined) {\n                delete r.body.mode;\n              }\n              if (body.mode) {\n                delete body.mode;\n              }\n            }\n          }\n          responseObject.body = r.body ? r.body : body;\n          responseObject.body = renameKey(responseObject.body, 'raw', 'body');\n          responseObject.body = responseObject.body.body;\n          itemData.response = [responseObject];\n          item.push(itemData);\n        });\n\n        const modelItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        modelItemData.name = e.name;\n        modelItemData.description = e.desc;\n        modelItemData.item = item;\n        mainItem.push(modelItemData);\n      });\n    }\n    // main object\n    mainObj.info = infoObj;\n    mainObj.item = mainItem;\n\n    // console.log(JSON.stringify(mainObj))\n    return JSON.stringify(mainObj, null, 2);\n    // for request end\n  },\n  async createCollectionV2_1 (info, platform = true) {\n    const mainObj = {};\n    const infoObj = {};\n\n    const mainItem = [];\n    // Project Details\n    infoObj.name = info.project.name;\n    infoObj._postman_id = uuid4();\n    infoObj.description = info.project.description;\n    infoObj.schema = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json';\n\n    const body = {\n      mode: '',\n      raw: '',\n    };\n    const header = [\n      {\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n      },\n    ];\n    body.mode = 'raw';\n    body.raw = '{}';\n\n    if (platform) {\n      info.item.forEach((e) => {\n        const modelItem = [];\n        e.item.forEach((ej) => {\n          const item = [];\n          ej.request?.forEach((r) => {\n            const request = {\n              url: '',\n              method: '',\n              header: null,\n              body: null,\n              description: '',\n              auth: {},\n            };\n            const itemData = {\n              name: '',\n              request: null,\n              response: null,\n              _postman_isSubFolder: true,\n            };\n            request.url = postman.Url.parse(r.url);\n            request.method = r.method;\n            request.header = r.header ? r.header : header;\n            request.auth = r.auth || {};\n            // request.body = r.body ? r.body : body;\n            if (r.body) {\n              if (isEmpty(r.body.raw)) {\n                r.body.raw = '{}';\n              }\n              request.body = r.body;\n            } else {\n              if (isEmpty(body.raw)) {\n                body.raw = '{}';\n              }\n              request.body = body;\n            }\n\n            // set Item Data\n            itemData.name = r.name;\n\n            itemData.request = request;\n            itemData.response = r.response;\n            if (itemData.response?.length) {\n              itemData.response[0].originalRequest.url = postman.Url.parse(r.response[0]?.originalRequest.url.raw);\n            }\n            item.push(itemData);\n          });\n\n          const modelItemData = {\n            name: null,\n            description: null,\n            item: null,\n          };\n          modelItemData.name = ej.name;\n          modelItemData.description = ej.desc;\n          modelItemData.item = item;\n          modelItem.push(modelItemData);\n        });\n\n        const mainItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        mainItemData.name = e.name;\n        mainItemData.description = e.description;\n        mainItemData.item = modelItem;\n\n        // main Item Data push into main Item\n\n        mainItem.push(mainItemData);\n      });\n    } else {\n      info.item.forEach((e) => {\n        const item = [];\n        e.request.forEach((r) => {\n          const request = {\n            url: '',\n            method: '',\n            header: null,\n            body: null,\n            description: '',\n          };\n          const itemData = {\n            name: '',\n            request: null,\n            response: null,\n          };\n          request.url = postman.Url.parse(r.url);\n          request.method = r.method;\n          request.header = header;\n          // request.body = r.body ? r.body : body;\n          if (r.body) {\n            if (isEmpty(r.body.raw)) {\n              r.body.raw = '{}';\n            }\n            request.body = r.body;\n          } else {\n            if (isEmpty(body.raw)) {\n              body.raw = '{}';\n            }\n            request.body = body;\n          }\n          // set Item Data\n          itemData.name = r.name;\n\n          itemData.request = request;\n          itemData.response = r.response;\n          item.push(itemData);\n        });\n\n        const modelItemData = {\n          name: null,\n          description: null,\n          item: null,\n        };\n        modelItemData.name = e.name;\n        modelItemData.description = e.desc;\n        modelItemData.item = item;\n        mainItem.push(modelItemData);\n      });\n    }\n    // main object\n    mainObj.info = infoObj;\n    mainObj.item = mainItem;\n\n    // console.log(JSON.stringify(mainObj))\n    return JSON.stringify(mainObj, null, 2);\n    // for request end\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/postman/index.js",
    "content": "/* eslint-disable */\n/* global MESSAGE, _ */\nconst fakeData = require('../../generateFakeDataSequelize');\nconst uuid4 = require('uuid').v4;\nconst { APIS } = require('../../../constants/constant');\nconst fakerStatic = require('faker');\nconst dayjs = require('dayjs');\nasync function getPlatformFromSchemaDynamic(jsonData, modelConfig, model) {\n    const platformNames = jsonData?.authentication?.platform;\n    const platformWiseModelSchema = {}\n    _.forEach(platformNames, (platformName) => {\n        platformWiseModelSchema[platformName] = (modelConfig[platformName] ? modelConfig[platformName][model] : undefined)\n    })\n    return platformWiseModelSchema\n}\nasync function getPostmanCollectionsForLogin(platformStr, userModel, loginWith, fakeModel, port, addDataFormate, value, modelPrivateAttribute, formateModel) {\n    if (addDataFormate) {\n        let boolKeys = []; let dateKeys = [];\n        if (addDataFormate['allModels_data_format']) {\n            for (let index in value) {\n                if (value[index].type === \"Boolean\") {\n                    boolKeys.push(index);\n                } if (value[index].type === \"Date\") {\n                    dateKeys.push(index);\n                }\n            }\n            if (addDataFormate[formateModel]) {\n                Array.prototype.push.apply(addDataFormate[formateModel], addDataFormate['allModels_data_format']);\n            } else {\n                addDataFormate[formateModel] = addDataFormate['allModels_data_format'];\n            }\n        }\n        boolKeys = [];\n        dateKeys = [];\n    }\n    let data = {\n        username: 'username',\n        password: 'password',\n    };\n    const changePass = {\n        oldPassword: 'OldPassword',\n        newPassword: 'NewPassword',\n    };\n    const platformObj = {\n        name: 'login',\n        desc: `${platformStr} Login`,\n        request: [],\n    };\n    let requestObj = {};\n    let body = {};\n    const header = [];\n    const security = {\n        \"type\": \"bearer\",\n        \"bearer\": {\n            \"token\": \"{{token}}\"\n        }\n    }\n    header.push({\n        key: 'Content-Type',\n        value: 'application/json',\n        description: '',\n    });\n\n    body.mode = 'raw';\n    requestObj.name = `Login in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/login`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    let resObject = _.cloneDeep(fakeModel[userModel]);\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: 101 });\n    }\n    if (!('token' in resObject)) {\n        Object.assign(resObject, { token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMWRlZDVjMGFjMjAxMmFjMDI4ODkxZiIsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE2MjkzNTEyNzAsImV4cCI6MTYyOTk1MTI3MH0.BJ-WKjNYeFDQ4pn8kfli5gwn6GLz_c3voFht20Agj9k\" });\n    }\n    Object.assign(resObject,\n        {\n            createdAt: fakerStatic.date.future(),\n            updatedAt: fakerStatic.date.future(),\n            isDeleted: false,\n            isActive: true\n        });\n    if (addDataFormate && addDataFormate[formateModel]) {\n        resObject = await filterResponseBasedOnFormate(addDataFormate[formateModel], resObject);\n    }\n\n    if (Object.keys(modelPrivateAttribute).length) {\n        resObject = await removePrivateAttibutesFromResponse(resObject, modelPrivateAttribute)\n    }\n    let jsonData = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Login Successful\",\n        \"data\": resObject\n    };\n    let responseObject = {};\n    responseObject.name = `Login in ${platformStr}_response`;\n    responseObject.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObject.status = 'OK';\n    responseObject.code = 200;\n    responseObject._postman_previewlanguage = 'json';\n    responseObject.body = JSON.stringify(jsonData, undefined, 2);\n    responseObject.header = [];\n    responseObject.cookie = [];\n    requestObj.response = [responseObject];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = \"raw\"\n    requestObj.name = `Register User in ${platformStr}`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/register`;\n    body.raw = JSON.stringify(fakeModel[userModel], undefined, 2);\n    requestObj.body = body;\n    resObject = _.cloneDeep(fakeModel[userModel]);\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: 101 });\n    }\n    Object.assign(resObject,\n        {\n            createdAt: fakerStatic.date.future(),\n            updatedAt: fakerStatic.date.future(),\n            isDeleted: false,\n            isActive: true\n        });\n    if (addDataFormate && addDataFormate[formateModel]) {\n        resObject = await filterResponseBasedOnFormate(addDataFormate[formateModel], resObject);\n    }\n\n    if (Object.keys(modelPrivateAttribute).length) {\n        resObject = await removePrivateAttibutesFromResponse(resObject, modelPrivateAttribute)\n    }\n    jsonData = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Your request is successfully executed\",\n        \"data\": resObject\n    };\n    responseObject = {};\n    responseObject.name = `Register User in ${platformStr}_response`;\n    responseObject.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObject.status = 'OK';\n    responseObject.code = 200;\n    responseObject._postman_previewlanguage = 'json';\n    responseObject.body = JSON.stringify(jsonData, undefined, 2);\n    responseObject.header = [];\n    responseObject.cookie = [];\n    requestObj.response = [responseObject];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Forgot Password in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/forgot-password`;\n    body.raw = JSON.stringify({\n        email: 'yourmail@gmail.com',\n    }, undefined, 2);\n    requestObj.body = body;\n    const jsonDataForgetPassword = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Your request is successfully executed\",\n        \"data\": \"otp successfully send to your email.\"\n    };\n    const responseObjectForgetPassword = {};\n    responseObjectForgetPassword.name = `Forgot Password in ${platformStr}_response`;\n    responseObjectForgetPassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObjectForgetPassword.status = 'OK';\n    responseObjectForgetPassword.code = 200;\n    responseObjectForgetPassword._postman_previewlanguage = 'json';\n    responseObjectForgetPassword.body = JSON.stringify(jsonDataForgetPassword, undefined, 2);\n    responseObjectForgetPassword.header = [];\n    responseObjectForgetPassword.cookie = [];\n    requestObj.response = [responseObjectForgetPassword];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Validate OTP in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/validate-otp`;\n    body.raw = JSON.stringify({\n        otp: '5898',\n    }, undefined, 2);\n    requestObj.body = body;\n    const validateOTPResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Your request is successfully executed\",\n        \"data\": \"Invalid OTP\"\n    };\n    const responseObjectValidateOTP = {};\n    responseObjectValidateOTP.name = `Validate OTP in ${platformStr}_response`;\n    responseObjectValidateOTP.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseObjectValidateOTP.status = 'OK';\n    responseObjectValidateOTP.code = 200;\n    responseObjectValidateOTP._postman_previewlanguage = 'json';\n    responseObjectValidateOTP.body = JSON.stringify(validateOTPResponse, undefined, 2);\n    responseObjectValidateOTP.header = [];\n    responseObjectValidateOTP.cookie = [];\n    requestObj.response = [responseObjectValidateOTP];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Logout in ${platformStr}`;\n    requestObj.method = 'POST';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/logout`;\n    body.raw = JSON.stringify({});\n    requestObj.body = body;\n    requestObj.header = header;\n    requestObj.auth = security;\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Change Password in ${platformStr}`;\n    requestObj.method = 'PUT';\n    requestObj.url = platformStr.toLowerCase() !== 'admin'\n        ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${userModel.toLowerCase()}/change-password`\n        : `{{url}}/${platformStr.toLowerCase()}/${userModel.toLowerCase()}/change-password`;\n    body.raw = JSON.stringify(changePass, undefined, 2);\n    requestObj.body = body;\n    requestObj.header = header;\n    requestObj.auth = security;\n    if (!('id' in resObject)) {\n        Object.assign(resObject, { id: 101 });\n    }\n    if (!('loginTry' in resObject)) {\n        Object.assign(resObject, { loginTry: 0 });\n    }\n    const changePasswordResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Password changed successfully\",\n        \"data\": null\n    };\n    const responseForChangePassword = {};\n    responseForChangePassword.name = `Change Password in ${platformStr}_response`;\n    responseForChangePassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseForChangePassword.status = 'OK';\n    responseForChangePassword.code = 200;\n    responseForChangePassword._postman_previewlanguage = 'json';\n    responseForChangePassword.body = JSON.stringify(changePasswordResponse, undefined, 2);\n    responseForChangePassword.header = [];\n    responseForChangePassword.cookie = [];\n    requestObj.response = [responseForChangePassword];\n    platformObj.request.push(requestObj);\n\n    requestObj = {};\n    body = {};\n    body.mode = 'raw';\n    requestObj.name = `Reset password in ${platformStr}`;\n    requestObj.method = 'PUT';\n    requestObj.url = `{{url}}/${platformStr.toLowerCase()}/auth/reset-password`;\n    body.raw = JSON.stringify({\n        code: '5898',\n        newPassword: 'yourPassword',\n    }, undefined, 2);\n    requestObj.body = body;\n    const resetPasswordResponse = {\n        \"status\": \"SUCCESS\",\n        \"message\": \"Your request is successfully executed\",\n        \"data\": \"Password reset successfully\"\n    };\n    const responseForResetPassword = {};\n    responseForResetPassword.name = `Reset password in ${platformStr}_response~`;\n    responseForResetPassword.originalRequest = {\n        method: 'POST',\n        header: [],\n        url: {\n            raw: requestObj.url,\n        },\n    };\n    responseForResetPassword.status = 'OK';\n    responseForResetPassword.code = 200;\n    responseForResetPassword._postman_previewlanguage = 'json';\n    responseForResetPassword.body = JSON.stringify(resetPasswordResponse, undefined, 2);\n    responseForResetPassword.header = [];\n    responseForResetPassword.cookie = [];\n    requestObj.response = [responseForResetPassword];\n    platformObj.request.push(requestObj);\n\n    return platformObj;\n}\nasync function getPostmanCollectionForSocialLogin(platform, details, port) {\n    const platformObj = {\n        name: 'Social Login',\n        desc: 'Login Through Social Accounts',\n        request: [],\n    };\n    let requestObj = {};\n    let body = {};\n    for (let i = 0; i < details.length; i += 1) {\n        requestObj = {};\n        body = {};\n        body.mode = 'raw';\n        requestObj.name = `Social Login through ${details[i].toLowerCase()}`;\n        requestObj.method = 'GET';\n        requestObj.url = `{{url}}/${platform}/auth/${details[i].toLowerCase()}`;\n        body.raw = '{}';\n        requestObj.body = body;\n        platformObj.request.push(requestObj);\n    }\n\n    return platformObj;\n}\nasync function setCustomRoutes(customObj) {\n    try {\n        let newPlatform = {\n            name: \"common\",\n            description: \"Common routes\",\n            item: []\n        }\n        const port = customObj.port;\n        if (customObj.notification.length) {\n            let platformObj = {\n                name: `webNotificationsRoutes`,\n                desc: \"\",\n                request: []\n            }\n            let requestObj = {}\n            let body = {}\n            body.mode = \"raw\"\n            requestObj.name = `create Notification`;\n            requestObj.method = `POST`\n            requestObj.url = `{{url}}/common/api/v1/notification/create`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n\n            requestObj = {}\n            body = {}\n\n            body.mode = \"raw\"\n            requestObj.name = `Mark as read`;\n            requestObj.method = `PUT`\n            requestObj.url = `{{url}}/common/api/v1/notification/markAsRead`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n\n            requestObj = {}\n            body = {}\n\n            body.mode = \"raw\"\n            requestObj.name = `Mark as Visited`;\n            requestObj.method = `PUT`\n            requestObj.url = `{{url}}/common/api/v1/notification/markAsVisited`\n            body.raw = \"{}\"\n            requestObj.body = body;\n            platformObj.request.push(requestObj);\n            newPlatform.item.push(platformObj);\n        }\n        // if (!_.isEmpty(customObj.fileObj)) {\n        //     newPlatform.item.push(await getPostmanCollectionForFileUpload(\"common\", customObj.fileObj, customObj.port));\n        // }\n\n        return newPlatform;\n    } catch (error) {\n        throw error;\n    }\n}\nasync function getPostmanCollections(platformStr, key, platform, data = {}, isRole = false, isAuth, port, currentPostmanCollectionDetails = {}, addDataFormate, value, modelPrivateAttribute) {\n    if (addDataFormate) {\n        let boolKeys = []; let dateKeys = []; let dateOnlyKeys = [];\n        if (addDataFormate['allModels_data_format']) {\n            for (let index in value) {\n                if (value[index].type === \"Boolean\") {\n                    boolKeys.push(index);\n                } if (value[index].type === \"Date\") {\n                    dateKeys.push(index);\n                } if (value[index].type === \"DateOnly\") {\n                    dateOnlyKeys.push(index);\n                }\n            }\n            if (addDataFormate[key]) {\n                Array.prototype.push.apply(addDataFormate[key], addDataFormate['allModels_data_format']);\n            } else {\n                addDataFormate[key] = addDataFormate['allModels_data_format'];\n            }\n        }\n        boolKeys = [];\n        dateKeys = [];\n    }\n    let platformObj = {\n        name: key,\n        desc: `${key} Model APIs`,\n        request: [],\n    };\n\n    const id = \":id\";\n    delete data[key].id;\n    if (isRole) {\n        data[key].role = 1;\n    }\n\n    for (let [api, value] of Object.entries(platform)) {\n        if (APIS.includes(api) && value.selected) {\n            let requestObj = {};\n            let body = {};\n            const header = [];\n            header.push({\n                key: 'Content-Type',\n                value: 'application/json',\n                description: '',\n            });\n            let security = {};\n            if (value.isAuth && isAuth) {\n                security = {\n                    \"type\": \"bearer\",\n                    \"bearer\": {\n                        \"token\": \"{{token}}\"\n                    }\n                }\n            }\n            if (api === 'create') {\n                let body = {};\n                body.mode = 'raw';\n                requestObj.name = `add${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin'\n                    ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/create`\n                    : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/create`;\n                body.raw = JSON.stringify(data[key], undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `add${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(JSON.parse(body.raw));\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 1 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": bodyRawData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'createBulk') {\n                requestObj.name = `insertBulk${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/addBulk` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/addBulk`;\n                const arr = [];\n                const objBulk = {};\n                arr.push(data[key]);\n                objBulk.data = arr;\n                body.mode = 'raw';\n                body.raw = JSON.stringify(objBulk, undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `add${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 101 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": [bodyRawData]\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'findAll') {\n                let findAllFakeobj = {\n                    \"query\": {},\n                    \"options\": {\n                        \"select\": [\n                            \"field 1\", \"field 2\"\n                        ],\n                        \"page\": 1,\n                        \"paginate\": 10\n                    },\n                    \"isCountOnly\": false\n                }\n                requestObj.name = `findAll${key}`;\n                requestObj.method = 'POST';\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/list` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/list`;\n                body.mode = 'raw';\n                body.raw = JSON.stringify(findAllFakeobj, undefined, 2);\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                const responseObject = {};\n                responseObject.name = `findAll${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let findAllObject = _.cloneDeep(data[key]);\n                if (!('id' in findAllObject)) {\n                    Object.assign(findAllObject, { id: 101 });\n                }\n                Object.assign(findAllObject,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    findAllObject = await filterResponseBasedOnFormate(addDataFormate[key], findAllObject);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    findAllObject = await removePrivateAttibutesFromResponse(findAllObject, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(findAllObject).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete findAllObject[keys];\n                        }\n                    })\n                }\n                let jsonPaginatorData = {\n                    \"data\": [findAllObject],\n                    \"paginator\": {\n                        \"currentPage\": 1,\n                        \"itemCount\": 1,\n                        \"pageCount\": 1,\n                        \"perPage\": 25\n                    }\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": jsonPaginatorData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'count') {\n                requestObj.name = `get${key}Count`;\n                requestObj.method = 'POST',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/count` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/count`;\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ where: { isActive: true } }, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `get${key}Count_response`;\n                responseObject.originalRequest = {\n                    method: 'POST',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": {\n                        \"totalRecords\": 10\n                    }\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'findById') {\n                requestObj.name = `get${key}`;\n                requestObj.method = 'GET',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/${id}` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/${id}`;\n                const responseObject = {};\n                responseObject.name = `get${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'GET',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let findByIdResponseData = _.cloneDeep(data[key]);\n                if (!('id' in findByIdResponseData)) {\n                    Object.assign(findByIdResponseData, { id: 101 });\n                }\n                Object.assign(findByIdResponseData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    findByIdResponseData = await filterResponseBasedOnFormate(addDataFormate[key], findByIdResponseData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    findByIdResponseData = await removePrivateAttibutesFromResponse(findByIdResponseData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(findByIdResponseData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete findByIdResponseData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": findByIdResponseData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'update') {\n                body.mode = 'raw';\n                requestObj.name = `update${key}`;\n                requestObj.method = 'PUT',\n                    requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/update/${id}` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/update/${id}`;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                body.raw = JSON.stringify(data[key], undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `update${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(JSON.parse(body.raw));\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 101 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": bodyRawData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'bulkUpdate') {\n                requestObj.name = `updateBulk${key}`;\n                requestObj.method = 'PUT',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/updateBulk` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/updateBulk`;\n                const objUpdateBulk = {\n                    filter: {\n                        isActive: true,\n                    },\n                    data: {\n                        isDeleted: false,\n                    },\n                };\n                body.mode = 'raw';\n                body.raw = JSON.stringify(objUpdateBulk, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `updateBulk${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                // let updateBulkDataResponse = {\n                //     \"status\": \"SUCCESS\",\n                //     \"message\": \"Your request is successfully executed\",\n                //     \"data\": [\n                //         null,\n                //         1\n                //     ]\n                // };\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": [\n                        null,\n                        1\n                    ]\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'partialUpdate') {\n                const pBody = {};\n                pBody.isActive = true;\n                pBody.isDeleted = false;\n                body.mode = 'raw';\n                requestObj.name = `partialupdate${key}`;\n                requestObj.method = 'PUT',\n                    requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/partial-update/${id}` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/partial-update/${id}`;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                body.raw = JSON.stringify(pBody, undefined, 2);\n                requestObj.body = body;\n                const responseObject = {};\n                responseObject.name = `partialupdate${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                // let partialUpdateJsonData = {\n                //     \"status\": \"SUCCESS\",\n                //     \"message\": \"Your request is successfully executed\",\n                //     \"data\": [\n                //         null,\n                //         1\n                //     ]\n                // };\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\":  [\n                        null,\n                        1\n                    ]\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'softDelete') {\n                requestObj.name = `softDelete${key}`;\n                requestObj.method = 'PUT',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/softDelete/${id}` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/softDelete/${id}`;\n                const responseObject = {};\n                responseObject.name = `softDelete${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 101 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": bodyRawData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'delete') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ isWarning: true }, undefined, 2);\n                requestObj.name = `delete${key}`;\n                requestObj.method = 'DELETE',\n                    header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.body = body;\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/delete/${id}` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/delete/${id}`;\n                const responseObject = {};\n                responseObject.name = `delete${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'DELETE',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 101 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": bodyRawData\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n\n            }\n            if (api === 'deleteMany') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ isWarning: true, ids: [id] }, undefined, 2);\n                requestObj.name = `deleteMany${key}`;\n                requestObj.method = 'POST';\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/deleteMany` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/deleteMany`;\n                const responseObject = {};\n                responseObject.name = `deleteMany${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'DELETE',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let bodyRawData = _.cloneDeep(data[key]);\n                if (!('id' in bodyRawData)) {\n                    Object.assign(bodyRawData, { id: 101 });\n                }\n                Object.assign(bodyRawData,\n                    {\n                        createdAt: fakerStatic.date.future(),\n                        updatedAt: fakerStatic.date.future(),\n                        isDeleted: false,\n                        isActive: true\n                    });\n                if (addDataFormate && addDataFormate[key]) {\n                    bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n                }\n                if (Object.keys(modelPrivateAttribute).length) {\n                    bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n                }\n                const projectionFields = currentPostmanCollectionDetails[api];\n                let selectedFields = [];\n                if (projectionFields) {\n                    selectedFields = projectionFields.fields;\n                }\n                if (selectedFields && selectedFields.length) {\n                    Object.keys(bodyRawData).map(keys => {\n                        if (!selectedFields.includes(keys)) {\n                            delete bodyRawData[keys];\n                        }\n                    })\n                }\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": 1\n                };\n                responseJsonData = JSON.stringify(responseJsonData, undefined, 2)\n                responseObject.body = responseJsonData;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n            if (api === 'softDeleteMany') {\n                body.mode = 'raw';\n                body.raw = JSON.stringify({ ids: [id] }, undefined, 2);\n                requestObj.name = `softDeleteMany${key}`;\n                requestObj.method = 'PUT';\n                requestObj.body = body;\n                header.length ? requestObj.header = header : '';\n                requestObj.auth = security\n                requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/softDeleteMany` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/softDeleteMany`;\n                const responseObject = {};\n                responseObject.name = `softDeleteMany${key}_response`;\n                responseObject.originalRequest = {\n                    method: 'PUT',\n                    header: [],\n                    url: {\n                        raw: requestObj.url,\n                    },\n                };\n                responseObject.status = 'OK';\n                responseObject.code = 200;\n                responseObject._postman_previewlanguage = 'json';\n                let softDeleteManyResponse = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": [\n                        1\n                    ]\n                };\n                let responseJsonData = {\n                    \"status\": \"SUCCESS\",\n                    \"message\": \"Your request is successfully executed\",\n                    \"data\": softDeleteManyResponse\n                };\n                softDeleteManyResponse = JSON.stringify(softDeleteManyResponse, undefined, 2)\n                responseObject.body = softDeleteManyResponse;\n                responseObject.header = [];\n                responseObject.cookie = [];\n                requestObj.response = [responseObject];\n                platformObj.request.push(requestObj);\n            }\n        }\n\n    }\n\n    if (isAuth && isRole) {\n        let requestObj = {};\n        let body = {};\n        const header = [];\n        header.push({\n            key: 'Content-Type',\n            value: 'application/json',\n            description: '',\n        });\n        let security = {\n            \"type\": \"bearer\",\n            \"bearer\": {\n                \"token\": \"{{token}}\"\n            }\n        }\n        body.mode = 'raw';\n        requestObj.name = `updateProfile`;\n        requestObj.method = 'PUT',\n            requestObj.url = platformStr.toLowerCase() !== 'admin' ? `{{url}}/${platformStr.toLowerCase()}/api/v1/${key.toLowerCase()}/update-profile` : `{{url}}/${platformStr.toLowerCase()}/${key.toLowerCase()}/update-profile`;\n        header.length ? requestObj.header = header : '';\n        requestObj.auth = security\n        body.raw = JSON.stringify(data[key], undefined, 2);\n        requestObj.body = body;\n        const responseObject = {};\n        responseObject.name = `updateProfile${key}_response`;\n        responseObject.originalRequest = {\n            method: 'PUT',\n            header: [],\n            url: {\n                raw: requestObj.url,\n            },\n        };\n        responseObject.status = 'OK';\n        responseObject.code = 200;\n        responseObject._postman_previewlanguage = 'json';\n        let bodyRawData = _.cloneDeep(data[key]);\n        if (!('id' in bodyRawData)) {\n            Object.assign(bodyRawData, { id: 101 });\n        }\n        Object.assign(bodyRawData,\n            {\n                createdAt: fakerStatic.date.future(),\n                updatedAt: fakerStatic.date.future(),\n                isDeleted: false,\n                isActive: true\n            });\n        if (addDataFormate && addDataFormate[key]) {\n            bodyRawData = await filterResponseBasedOnFormate(addDataFormate[key], bodyRawData);\n        }\n        if (Object.keys(modelPrivateAttribute).length) {\n            bodyRawData = await removePrivateAttibutesFromResponse(bodyRawData, modelPrivateAttribute)\n        }\n\n        const responseJsonData = {\n            \"status\": \"SUCCESS\",\n            \"message\": \"Your request is successfully executed\",\n            \"data\": bodyRawData\n        };\n        responseObject.body = JSON.stringify(responseJsonData.data,undefined,2);\n        responseObject.header = [];\n        responseObject.cookie = [];\n        requestObj.response = [responseObject];\n        platformObj.request.push(requestObj);\n    }\n\n    platformObj = _.cloneDeep(await sortMethods(platformObj));\n    return platformObj;\n}\nasync function getPostmanCollectionForFileUpload(platform, fileObject) {\n    try {\n        let platformObj = {\n            name: \"File Upload\",\n            desc: `Upload Files`,\n            request: []\n        }\n        let security = {};\n        let requestObj = {}\n        requestObj = {};\n        requestObj.body = {};\n        requestObj.body.mode = \"formdata\"\n        requestObj.name = `File upload in ${platform}`\n        requestObj.method = \"POST\"\n        if (platform.toLowerCase() != \"admin\") {\n            requestObj.url = `{{url}}/${platform.toLowerCase()}/api/v1/upload`;\n        }\n        else {\n            requestObj.url = `{{url}}/${platform.toLowerCase()}/upload`;\n        }\n\n        let formdata = [\n            {\n                \"key\": \"file[]\",\n                \"type\": \"file\",\n                \"description\": \"Select file to upload\"\n            },\n            {\n                \"key\": \"file[]\",\n                \"type\": \"file\",\n                \"disabled\": true,\n                \"description\": \"Select Another file to upload multiple files\"\n            },\n            {\n                \"key\": \"folder\",\n                \"value\": \"Enter foldername\",\n                \"type\": \"text\",\n                \"disabled\": true,\n                \"description\": \"Optional, enable to upload file to specific folder\"\n            },\n            {\n                \"key\": \"fileName\",\n                \"value\": \"Enter fileName\",\n                \"type\": \"text\",\n                \"disabled\": true,\n                \"description\": \"Optional, enable to give Specific file name to uploaded File\"\n            }\n        ];\n        requestObj.body.formdata = formdata;\n        requestObj.header = [];\n        requestObj.header.push({\n            key: 'Content-Type',\n            value: 'multipart/form-data',\n            description: '',\n        })\n        if (fileObject.authentication) {\n            security = {\n                \"type\": \"bearer\",\n                \"bearer\": {\n                    \"token\": \"{{token}}\"\n                }\n            }\n        }\n        let responseJsonData = {\n            \"status\": \"SUCCESS\",\n            \"message\": \"Your request is successfully executed\",\n            \"data\": [\n                {\n                    \"status\": true,\n                    \"path\": `path to download file`,\n                }\n            ]\n        };\n        responseJsonData = JSON.stringify(responseJsonData, undefined, 2);\n        let responseObject = {};\n        responseObject.name = `File upload in ${platform}`;\n        responseObject.originalRequest = {\n            method: 'POST',\n            header: [],\n            url: {\n                raw: requestObj.url,\n            },\n        };\n        responseObject.status = 'OK';\n        responseObject.code = 200;\n        responseObject._postman_previewlanguage = 'json';\n        responseObject.body = responseJsonData;\n        responseObject.header = [\n            { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n        ];\n        responseObject.cookie = [];\n        requestObj.response = [responseObject];\n        requestObj.auth = security;\n        platformObj.request.push(requestObj);\n\n        if (fileObject.storage !== undefined && fileObject.storage.toLowerCase() === 's3_private') {\n            //download api for s3 private\n            requestObj = {};\n            security = {};\n            requestObj.body = {};\n            requestObj.body.mode = \"raw\"\n            requestObj.name = `Get Presigned Url for S3 private Upload`\n            requestObj.method = \"POST\"\n            if (platform.toLowerCase() != \"admin\") {\n                requestObj.url = `{{url}}/${platform.toLowerCase()}/api/v1/generate-pre-signed-url`;\n            }\n            else {\n                requestObj.url = `{{url}}/${platform.toLowerCase()}/generate-pre-signed-url`;\n            }\n\n            requestObj.body.raw = JSON.stringify({ uri: \"s3 URL\" }, undefined, 2);\n            requestObj.header = [];\n            requestObj.header.push({\n                key: 'Content-Type',\n                value: 'application/json',\n                description: '',\n            })\n            if (fileObject.authentication) {\n                if (fileObject.authentication) {\n                    security = {\n                        \"type\": \"bearer\",\n                        \"bearer\": {\n                            \"token\": \"{{token}}\"\n                        }\n                    }\n                }\n            }\n            responseJsonData = {\n                \"status\": \"SUCCESS\",\n                \"message\": \"Your request is successfully executed\",\n                \"data\": [\n                    {\n                        \"status\": true,\n                        \"path\": `URL to access file`,\n                    }\n                ]\n            };\n            responseJsonData = JSON.stringify(responseJsonData, undefined, 2);\n            responseObject = {};\n            responseObject.name = `Get Presigned Url for S3 private Upload`;\n            responseObject.originalRequest = {\n                method: 'POST',\n                header: [],\n                url: {\n                    raw: requestObj.url,\n                },\n            };\n            responseObject.status = 'OK';\n            responseObject.code = 200;\n            responseObject._postman_previewlanguage = 'json';\n            responseObject.body = responseJsonData;\n            responseObject.header = [\n                { \"key\": \"Content-Type\", \"value\": \"application/json\" }\n            ];\n            responseObject.cookie = [];\n            requestObj.response = [responseObject];\n            requestObj.auth = security;\n            platformObj.request.push(requestObj);\n        }\n\n        return platformObj;\n\n    } catch (error) {\n        throw new Error(error.message);\n    }\n}\nasync function getCollectionForPostmanDynamic(jsonData, isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth) {\n    try {\n        const port = jsonData?.config?.port;\n        let pfNames = jsonData?.authentication?.platform\n        let pfWiseItems = {}\n        let pfWiseItemsArray = []\n        let pfWiseCount = {}\n        let fieldSelection = {}\n        let privateModelData = {};\n        if (!_.isEmpty(jsonData[\"fieldSelection\"])) {\n            fieldSelection = jsonData[\"fieldSelection\"];\n        }\n        if (!_.isEmpty(jsonData[\"modelPrivate\"])) {\n            privateModelData = jsonData[\"modelPrivate\"];\n        }\n        for (const pfName of pfNames) {\n            pfWiseItems[pfName] = {\n                name: null,\n                description: null,\n                item: []\n            }\n            pfWiseCount[pfName] = 0\n        }\n        for (const model in jsonData[\"models\"]) {\n            let loginWith = [];\n            if (userModel == model) {\n                for (let [k, v] of Object.entries(jsonData[\"models\"][model])) {\n                    if (k.includes('SSO'.toLowerCase())) {\n                        delete jsonData[\"models\"][model][k];\n                    }\n                }\n                loginWith = _.keys(_.pickBy(userLoginWith));\n                let modelsKeys = _.keys(jsonData[\"models\"][model]);\n                if (!modelsKeys.includes(loginWith[0])) {\n                    jsonData[\"models\"][model][loginWith[0]] = {\n                        \"type\": \"String\",\n                        \"unique\": true,\n                        \"uniqueCaseInsensitive\": true\n                    }\n                }\n            }\n            let modelObj = {}\n            modelObj[model] = jsonData[\"models\"][model]\n            let fakeModel = fakeData.validSchema(_.cloneDeep(modelObj));\n            let pfDetails = await getPlatformFromSchemaDynamic(jsonData, jsonData[\"modelConfig\"], model);\n            for (const pfName of pfNames) {\n                let loginAccessRole = _.keys(loginAccessPlatform);\n                pfWiseItems[pfName].name = pfName;\n                pfWiseItems[pfName].description = `${pfName} APIs`\n                pfWiseCount[pfName]++\n                let modelPrivateAttribute = {};\n                let format = {};\n                if (!_.isEmpty(privateModelData[model])) {\n                    modelPrivateAttribute = privateModelData[model];\n                }\n                if (!_.isEmpty(jsonData['authentication']['addDataFormate'])) {\n                    format = jsonData['authentication']['addDataFormate'];\n                }\n                if (!_.isEmpty(pfDetails[pfName])) {\n                    let currentPostmanPlatformDetails = fieldSelection[pfName];\n                    let currentModelNameDetails = {};\n                    if (currentPostmanPlatformDetails) {\n                        currentModelNameDetails = currentPostmanPlatformDetails[model];\n                    }\n                    let modelDetails = await getPostmanCollections(pfName, model, pfDetails[pfName], fakeModel, userModel === model, isAuth, port, currentModelNameDetails, format, jsonData[\"models\"][model], modelPrivateAttribute);\n                    pfWiseItems[pfName].item.push(modelDetails)\n                }\n\n\n                if (isAuth && userModel === model) {\n                    let loginDetail = await getPostmanCollectionsForLogin(pfName, userModel, loginWith[0], fakeModel, port, format, jsonData[\"models\"][model], modelPrivateAttribute, model);\n                    pfWiseItems[pfName].item.push(loginDetail)\n                }\n                if (pfWiseCount[pfName] == 1 && socialAuth.required) {\n                    let details = [];\n                    if (socialAuth.platforms.length) {\n                        _.each(socialAuth.platforms, p => {\n                            if (p.platforms.includes(pfName)) {\n                                details.push(p.type);\n                            }\n                        });\n                    }\n                    if (details.length) {\n                        let socialDetails = await getPostmanCollectionForSocialLogin(pfName, details, port);\n                        pfWiseItems[pfName].item.push(socialDetails)\n                    }\n                }\n                if (pfWiseCount[pfName] == 1 && !_.isEmpty(jsonData[\"fileUpload\"])) {\n                    _.each(jsonData[\"fileUpload\"].uploads, async u => {\n                        if (u.platform.toLowerCase() == pfName) {\n                            let platformObj = await getPostmanCollectionForFileUpload(pfName, u);\n                            pfWiseItems[pfName].item.push(platformObj);\n                        }\n                    })\n                }\n\n            }\n        }\n\n        if (!_.isEmpty(jsonData[\"routes\"]?.apis)) {\n            let platformWiseGroup = _.groupBy(jsonData[\"routes\"]?.apis, \"platform\");\n            for (let obj in platformWiseGroup) {\n                let newPlatform = {\n                    name: null,\n                    description: null,\n                    item: []\n                }\n                let platformObj = {\n                    name: `customRoutes`,\n                    desc: \"\",\n                    request: []\n                }\n                platformWiseGroup[obj].forEach((p, k) => {\n                    // newPlatform.name = obj.charAt(0).toUpperCase() + obj.slice(1);\n                    newPlatform.name = obj;\n                    newPlatform.description = p.descriptions\n                    let requestObj = {}\n                    let body = {}\n                    body.mode = \"raw\"\n                    requestObj.name = `${p.api}`\n                    requestObj.method = `${p.method.toUpperCase()}`\n                    requestObj.url = `{{url}}/${p.api}`\n                    body.raw = \"{}\"\n                    requestObj.body = body;\n                    platformObj.request.push(requestObj)\n\n                });\n                if (_.includes(pfNames, obj)) {\n                    pfWiseItems[obj].item.push(platformObj)\n                } else {\n                    newPlatform.item.push(platformObj);\n                    if (!pfWiseItems[obj]) {\n                        pfWiseItems[obj] = {\n                            name: obj,\n                            description: `${obj} Apis`,\n                            item: []\n                        }\n                        pfWiseCount[obj] = 0\n\n                    }\n                    pfWiseItems[obj].item.push(newPlatform)\n                    pfWiseCount[obj] += 1\n\n                }\n\n            }\n\n        }\n\n\n\n        let webNot = [];\n        if (!_.isEmpty(jsonData[\"modelNotifications\"])) {\n            Object.values(jsonData.modelNotifications).forEach((keys) => {\n                for (const [k, val] of Object.entries(keys)) {\n                    if (APIS.includes(k) && val.selected) {\n                        webNot.push(val.post ? val.post.webNotification === true : val.pre.webNotification === true);\n                    }\n                }\n            });\n        }\n\n        let fileObj = {};\n        if (!_.isEmpty(jsonData[\"fileUpload\"])) {\n            for (let i = 0; i < jsonData[\"fileUpload\"].uploads.length; i++) {\n                if (!_.isEmpty(jsonData[\"fileUpload\"].uploads[i].platform)) {\n                    fileObj = jsonData[\"fileUpload\"].uploads[i];\n                    break;\n                }\n            }\n        }\n\n        let customObj = {\n            notification: webNot,\n            fileObj,\n            port\n        }\n        let customItems = await setCustomRoutes(customObj);\n        if (customItems.item.length) {\n            pfWiseItems.common = customItems;\n        }\n        pfWiseItemsArray = _.values(pfWiseItems)\n        return pfWiseItemsArray\n    } catch (error) {\n        throw error;\n    }\n}\n\nasync function sortMethods(methods) {\n    let post = [], put = [], get = [], del = [];\n    for (let i = 0; i < methods.request.length; i++) {\n        key = methods.request[i].method;\n        if (key == 'PUT') {\n            put.push(methods.request[i]);\n        }\n        else if (key == 'GET') {\n            get.push(methods.request[i]);\n        }\n        else if (key == 'DELETE') {\n            del.push(methods.request[i]);\n        }\n        else {\n            post.push(methods.request[i]);\n        }\n    }\n\n    let returnObj = [\n        ...get, ...post, ...put, ...del\n    ]\n    Object.assign(methods, { request: returnObj })\n    return methods;\n}\nasync function generateEnvForPostman(config) {\n    let jsonObj = {\n        \"id\": uuid4(),\n        \"name\": `${config.projectName}_environment`,\n        \"values\": [\n            {\n                \"key\": \"token\",\n                \"value\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYxMWRlZDVjMGFjMjAxMmFjMDI4ODkxZiIsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE2MjkzNTEyNzAsImV4cCI6MTYyOTk1MTI3MH0.BJ-WKjNYeFDQ4pn8kfli5gwn6GLz_c3voFht20Agj9k\",\n                \"enabled\": true\n            },\n            {\n                \"key\": \"url\",\n                \"value\": `http://localhost:${config.port || 3000}`,\n                \"enabled\": true\n            }\n        ],\n        \"_postman_variable_scope\": \"environment\",\n        \"_postman_exported_at\": new Date(),\n        \"_postman_exported_using\": \"Postman\"\n    }\n    return jsonObj;\n}\n\nconst getPushNotificationRoutes = (platform, pushNotificationData) => {\n    let platformObj = {\n        name: \"Push Notification\",\n        desc: `Push Notification Routes`,\n        request: []\n    }\n    let data = {\n        userId: '123',\n        playerId: 'xxx12345xxx',\n        deviceId: '01234abcde',\n        isActive: true,\n        isDeleted: false\n    }\n\n    let requestObj = {}\n    let body = {}\n    body.mode = 'raw';\n    requestObj = {};\n    requestObj.body = {};\n    requestObj.name = `Add Player Id`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}/${platform}/auth/push-notification/addPlayerId`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    requestObj.response = [];\n    platformObj.request.push(requestObj);\n\n    requestObj = {}\n    body = {}\n    data = {\n        deviceId: '2001abcdef'\n    }\n    body.mode = 'raw';\n    requestObj = {};\n    requestObj.body = {};\n    requestObj.name = `Remove Player Id`\n    requestObj.method = \"POST\"\n    requestObj.url = `{{url}}/${platform}/auth/push-notification/removePlayerId`;\n    body.raw = JSON.stringify(data, undefined, 2);\n    requestObj.body = body;\n    requestObj.response = [];\n    platformObj.request.push(requestObj);\n    return platformObj;\n}\n\nasync function removePrivateAttibutesFromResponse(fakeModel, privateModelData) {\n    let fakeData = _.cloneDeep(fakeModel);\n    if (!_.isEmpty(fakeData)) {\n        if (!_.isEmpty(privateModelData)) {\n            Object.keys(fakeModel).forEach(fm => {\n                Object.keys(privateModelData).forEach(pm => {\n                    if (fm === pm) {\n                        if (Array.isArray(fakeModel[fm])) {\n                            //Remove field from array\n                            if (fakeModel[fm].length) {\n                                let objArray = fakeModel[fm][0];\n                                Object.keys(objArray).forEach(obj => {\n                                    Object.keys(privateModelData[pm]).forEach(m => {\n                                        if (obj === m) {\n                                            if (privateModelData[pm][m] === true) {\n                                                delete objArray[obj];\n                                            }\n                                        }\n                                    })\n                                })\n                                fakeData[fm] = [objArray];\n                            }\n                        } else {\n                            if (typeof fakeModel[fm] === 'object' && Object.keys(fakeModel[fm]).length && Object.keys(privateModelData[pm]).length) {\n                                //Remove field from object\n                                Object.keys(fakeModel[fm]).forEach(d => {\n                                    Object.keys(privateModelData[pm]).forEach(m => {\n                                        if (m === d) {\n                                            if (privateModelData[pm][m] === true) {\n                                                delete fakeData[pm][m];\n                                            }\n                                        }\n                                    })\n                                })\n                            } else {\n                                //Remove model property\n                                if (privateModelData[pm] === true) {\n                                    delete fakeData[pm];\n                                }\n                            }\n                        }\n                    }\n                })\n            });\n        }\n    }\n    return fakeData;\n}\n\nasync function filterResponseBasedOnFormate(formateArray, data) {\n    // let newData={};\n    for (let index of formateArray) {\n        for (let nestindex in index) {\n            switch (index.dataType) {\n                case 'string':\n                    if (index[nestindex] in data) {\n                        if (data[index.attribute[0]] && data[index.attribute[1]]) {\n                            if (index.operator === 'space') {\n                                data[index[nestindex]] = data[index.attribute[0]].toString().concat(' ', data[index.attribute[1]].toString())\n                            } else {\n                                data[index[nestindex]] = data[index.attribute[0]].toString().concat(`${index.operator}`, data[index.attribute[1]].toString())\n                            }\n                        }\n                    } if (!data.hasOwnProperty(index.targetAttr)) {\n                        if (index.operator === 'space') {\n                            data[index.targetAttr] = data[index.attribute[0]].toString().concat(' ', data[index.attribute[1]].toString())\n                        } else {\n                            data[index.targetAttr] = data[index.attribute[0]].toString().concat(`${index.operator}`, data[index.attribute[1]].toString())\n                        }\n                    }\n                    break;\n\n                case 'boolean':\n                    //  console.log(index.attribute.true);\n                    for (let boolIndex in data) {\n                        if (typeof data[boolIndex] === 'boolean') {\n                            if (data[boolIndex]) {\n                                data[boolIndex] = index.attribute.true;\n                            } else {\n                                data[boolIndex] = index.attribute.false;\n                            }\n\n                        }\n                    }\n                    break;\n\n                case 'date':\n                    for (let dateIndex in data) {\n                        if (data[dateIndex] instanceof (Date)) {\n                            data[dateIndex] = dayjs(data[dateIndex]).format(index.attribute);\n                        }\n                    }\n                    break;\n\n                case 'DateOnly':\n                    for (let dateIndex in data) {\n                        if (data[dateIndex] instanceof (Date)) {\n                            data[dateIndex] = dayjs(data[dateIndex]).format(index.attribute);\n                        }\n                    }\n                    break;\n            }\n        }\n    }\n    return data;\n}\nmodule.exports = {\n    getCollectionForPostmanDynamic,\n    generateEnvForPostman\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/requestValidation.js",
    "content": "/* eslint-disable */\nconst _ = require('lodash');\n\nconst validate = module.exports = {};\n\nvalidate.getValidation = async function (schema, enumData) {\n  let schemaObj = {}; let models;\n  let modelObj = {}, updateModelObj = {}, modelTestobj = {};\n  let modelType, otherTypes;\n  let joiModel;\n  let joiValidation = {};\n  let flag = true;\n  joiValidation.arrayOpen = 'joi.array().items(';\n  joiValidation.objectOpen = 'joi.object({';\n  joiValidation.arrayClose = ')';\n  joiValidation.objectClose = '})';\n\n  _.each(schema, (value, key) => {\n    delete value['updatedBy'];\n    delete value['addedBy'];\n    delete value['createdAt'];\n    delete value['updatedAt'];\n    delete value['modifiedBy'];\n  });\n  let closeStatus = 0;\n  for (let schemaIndex in schema) {\n    for (let valueIndex in schema[schemaIndex]) {\n\n      let flag = false;\n      for (let modelEnum in enumData) {\n        if (schemaIndex === modelEnum) {\n          for (let enumValueIndex in enumData[modelEnum]) {\n            if (enumValueIndex === valueIndex) {\n              schemaObj[valueIndex] = `joi.valid(...convertObjectToEnum(${enumData[modelEnum][enumValueIndex].enumFile}Default.${enumData[modelEnum][enumValueIndex].values}))`;\n              flag = true;\n            }\n          }\n        }\n      }\n      models = schema[schemaIndex][valueIndex];\n      if (models.type && flag === false) {\n        //'string'\n        if (typeof models.type === 'string') {\n          modelType = getTypes(models.type);\n          otherTypes = getOtherTypes(Object.keys(models), Object.values(models));\n          if (otherTypes) {\n            joiModel = modelType.concat(otherTypes);\n            schemaObj[valueIndex] = joiModel;\n          } else {\n            schemaObj[valueIndex] = modelType;\n          }\n          //['String']\n        } else if (Array.isArray(models.type) && models.type.length === 1) {\n          modelType = getTypes(models.type[0]);\n\n          otherTypes = getOtherTypes(Object.keys(models), Object.values(models));\n          if (otherTypes) {\n            joiModel = joiValidation.arrayOpen.concat(modelType, otherTypes, joiValidation.arrayClose);\n            schemaObj[valueIndex] = joiModel;\n          } else {\n            schemaObj[valueIndex] = joiValidation.arrayOpen.concat(modelType, joiValidation.arrayClose);\n          }\n        }\n      }\n      //without type('String')\n      else if (!models.type && typeof models !== 'object' && flag === false) {\n        modelType = getTypes(models);\n        schemaObj[valueIndex] = modelType;\n\n        //object\n      } else if (typeof models === 'object' && !Array.isArray(models) && flag === false) {\n        for (let index in models) {\n          if (models[index].type) {\n            modelType = getTypes(models[index].type);\n            otherTypes = getOtherTypes(Object.keys(models[index]), Object.values(models[index]));\n            if (otherTypes) {\n              schemaObj[valueIndex] += `${index}:${modelType}${otherTypes},`;\n              closeStatus = 1;\n            } else {\n              schemaObj[valueIndex] += `${index}:${modelType},`;\n              closeStatus = 1;\n            }\n          } else {\n            //2 level object\n            if (typeof models[index] === 'object') {\n              //console.log(models);\n              for (let nestIndex in models[index]) {\n                if (models[index][nestIndex].type && !Array.isArray(models[index])) {\n                  modelType = getTypes(models[index][nestIndex].type);\n                  otherTypes = getOtherTypes(Object.keys(models[index][nestIndex]), Object.values(models[index][nestIndex]));\n                  if (otherTypes) {\n                    schemaObj[valueIndex] = joiValidation.objectOpen;\n                    schemaObj[valueIndex] += `${index}:${joiValidation.objectOpen}${nestIndex}:${modelType}${otherTypes}${joiValidation.objectClose}`;\n                    schemaObj[valueIndex] += joiValidation.objectClose;\n                  } else {\n                    schemaObj[valueIndex] = joiValidation.objectOpen;\n                    schemaObj[valueIndex] += `${index}:${joiValidation.objectOpen}${nestIndex}:${modelType}${joiValidation.objectClose}`;\n                    schemaObj[valueIndex] += joiValidation.objectClose;\n                  }\n                  //object of array\n                } else if (Array.isArray(models[index])) {\n                  schemaObj[valueIndex] = joiValidation.objectOpen;\n                  schemaObj[valueIndex] += `${index}:${joiValidation.arrayOpen}`;\n                  schemaObj[valueIndex] += joiValidation.arrayClose;\n                  schemaObj[valueIndex] += joiValidation.objectClose;\n                  flag = false;\n                } else {\n                  //more then 2 levels\n                  schemaObj[valueIndex] = 'joi.object()';\n                }\n              }\n            } else {\n              if (!models.type && typeof models === 'object' && flag) {\n                //console.log(models);\n                schemaObj[valueIndex] = joiValidation.objectOpen;\n                for (let otherModels in models) {\n                  //console.log(otherModels);   \n                  modelType = getTypes(models[otherModels]);\n                  schemaObj[valueIndex] += `${otherModels}:${modelType},`;\n                }\n                schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n                schemaObj[valueIndex] += joiValidation.objectClose;\n              }\n            }\n          }\n        }\n        if (closeStatus === 1) {\n          schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n          schemaObj[valueIndex] += joiValidation.objectClose;\n          closeStatus = 0;\n        }\n      } else if (Array.isArray(models) && flag === false) {\n        for (let arrayIndex of models) {\n          schemaObj[valueIndex] = `${joiValidation.arrayOpen}`;\n          schemaObj[valueIndex] += `joi.object(`;\n          for (let objectIndex in arrayIndex) {\n            if (Array.isArray(objectIndex)) {\n              if (arrayIndex[objectIndex].type) {\n                modelType = getTypes(arrayIndex[objectIndex].type);\n                otherTypes = getOtherTypes(Object.keys(arrayIndex[objectIndex]), Object.values(arrayIndex[objectIndex]));\n                if (otherTypes) {\n                  schemaObj[valueIndex] += `${objectIndex}:${modelType}${otherTypes},`;\n                } else {\n                  schemaObj[valueIndex] += `${objectIndex}:${modelType},`;\n                }\n              } else {\n                modelType = getTypes(arrayIndex[objectIndex]);\n                schemaObj[valueIndex] += `${objectIndex}:${modelType},`;\n              }\n            }\n          }\n          schemaObj[valueIndex] = schemaObj[valueIndex].replace(/,\\s*$/, '');\n          schemaObj[valueIndex] += ')';\n          schemaObj[valueIndex] += joiValidation.arrayClose;\n        }\n      }\n    }\n    modelTestobj[schemaIndex] = schemaObj;\n    schemaObj = {};\n  }\n  _.each(modelTestobj, (v, x) => {\n    _.each(v, (val, y) => {\n      if (val && !val.includes('required')) {\n        val = `${val}.allow(null).allow('')`;\n        v[y] = val;\n      }\n      v[y] = val;\n      let hasActive = Reflect.has(v, 'isActive');\n      if (!hasActive) {\n        v.isActive = 'joi.boolean()';\n      }\n      let hasDelete = Reflect.has(v, 'isDeleted');\n      if (!hasDelete) {\n        v.isDeleted = 'joi.boolean()';\n      }\n      modelTestobj[x] = v;\n    });\n  });\n  updateObj = _.cloneDeep(modelTestobj);\n  _.each(updateObj, (v, y) => {\n    _.each(v, (val, i) => {\n      if (val) {\n        if (val.includes('required')) {\n          val = val.split('.required()').join('.when({is:joi.exist(),then:joi.required(),otherwise:joi.optional()})');\n          v[i] = val;\n        }\n      }\n    });\n  });\n\n  modelObj.models = modelTestobj;\n\n  updateModelObj.models = updateObj;\n\n  return { modelObj, updateModelObj };\n}\nfunction getTypes(modelType) {\n  modelType = modelType.toUpperCase();\n  let type;\n  switch (modelType) {\n    case 'STRING':\n    case 'MULTILINE':\n    case 'String':\n      type = 'joi.string()';\n      break;\n\n    case 'GEOMATRY':\n    case 'GEOGRAPHY':\n    case 'ENUM':\n      type = 'joi.any()';\n      break;\n\n    case 'INTEGER':\n    case 'BIGINT':\n      type = 'joi.number().integer()';\n      break;\n\n    case 'OBJECT':\n    case 'JSON':\n    case 'ObjectId':\n      type = 'joi.object()';\n      break;\n\n    case 'DECIMAL':\n    case 'CURRENCY':\n    case 'FLOAT':\n    case 'REAL':\n    case 'Number':\n      type = 'joi.number()';\n      break;\n\n    case 'ObjectId':\n      type = 'joi.number().integer()';\n      break;\n\n    case 'DATE':\n    case 'DATETIME':\n    case 'Date':\n      type = 'joi.date()';\n      break;\n\n    case 'TIMESTAMP':\n      type = 'joi.date().timestamp()';\n      break;\n\n    case 'BOOLEAN':\n    case 'Boolean':\n      type = 'joi.boolean()';\n      break;\n\n    case 'MIXED':\n      type = 'joi.any()';\n      break;\n\n    case 'SINGLELINE':\n      type = 'joi.string().regex(/^[^\\r\\n]+$/)';\n      break;\n\n    case 'EMAIL':\n      type = 'joi.string().email()';\n      break;\n\n    case 'URL':\n      type = 'joi.string().uri()';\n      break;\n\n    case 'PERCENTAGE':\n      type = 'joi.number().min(0).max(100)';\n\n    default:\n      type = 'joi.any()';\n  }\n  return type;\n\n}\n\nfunction getOtherTypes(key, value) {\n  let type;\n  if (Array.isArray(key) && Array.isArray(value)) {\n    for (let i = 0; i < key.length; i++) {\n      if (key[i] === 'required') {\n        type = '.required()';\n      } else if (key[i] === 'default') {\n        if (typeof value[i] === 'string') {\n          type = `.${key[i]}('${value[i]}')`;\n        } else {\n          type = `.${key[i]}(${value[i]})`;\n        }\n      } else if (key[i] === 'trim') {\n        type = '.trim()';\n      } else if (key[i] === 'match') {\n        type = `.regex(${value[i]})`;\n      } else if (key[i] === 'minLength' || key[i] === 'mix') {\n        type = `.min(${value[i]})`;\n      } else if (key[i] === 'maxLength' || key[i] === 'max') {\n        type = `.max(${value[i]})`;\n      } else if (key[i] === 'enum') {\n        if (Array.isArray(value[i])) {\n          value[i] = value[i].join();\n          value[i] = value[i].split(',').map((word) => `'${word.trim()}'`).join(',');\n          type = `.valid(${value[i]})`;\n        } if (typeof value[i] === 'string') {\n          type = `.valid(${value[i]})`;\n        }\n      } else if (key[i] === 'lowercase') {\n        type = '.case(\\'lower\\')';\n      } else if (key[i] === 'uppercase') {\n        type = '.case(\\'upper\\')';\n      } else if (key[i] === 'precision') {\n        type = `.precision(${value[i]})`;\n      }\n    }\n  }\n  return type;\n\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/service.js",
    "content": "const postman = require('./postman');\nconst generatePostmanCollection = require('./postman/generate-postman-collection');\n\nasync function createPostmanCollection (pName, postmanCollections, auth) {\n  const {\n    isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth,\n  } = auth;\n  const infoForPostman = {\n    project: {},\n    item: null,\n  };\n  infoForPostman.project.name = pName;\n  infoForPostman.project.descriptions = `${pName} API Collections`;\n  const dynamicPlatforms = await postman.getCollectionForPostmanDynamic(postmanCollections, isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth);\n  infoForPostman.item = dynamicPlatforms;\n  const jsonCollectionsV20 = await generatePostmanCollection.createCollectionV2_0(infoForPostman);\n  const jsonCollectionsV21 = await generatePostmanCollection.createCollectionV2_1(infoForPostman);\n  const envPostman = await postman.generateEnvForPostman(postmanCollections.config);\n  return [jsonCollectionsV20, jsonCollectionsV21, envPostman];\n}\n\nmodule.exports = { createPostmanCollection };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/sequelize/typeConverter.js",
    "content": "/* global __basedir, _ */\nconst fs = require('fs');\nconst constant = require('../../constants/constant');\n\nconst sqlTypes = JSON.parse(fs.readFileSync(`${__basedir}/config/sequelizeDataType.json`));\n\nconst removeKeys = (object) => {\n  if (Array.isArray(object)) {\n    object.forEach((a) => removeKeys(a));\n  } else if (typeof object === 'object') {\n    if (object !== null) {\n      constant.REMOVE_KEY_FROM_MODEL_FOR_SEQUELIZE_MODEL.forEach((a) => {\n        if (object !== null && object[a] !== null) {\n          delete object[a];\n        }\n      });\n      const values = Object.values(object).filter((v) => Array.isArray(v) || typeof v === 'object');\n      removeKeys(values);\n    }\n  }\n};\n\nfunction setType (data, adapterType, option = {}) {\n  _.forEach(data, (value, key) => {\n    if (typeof value === 'object' && !Array.isArray(value)) {\n      setType(value, adapterType, value);\n    } else if (Array.isArray(value)) {\n      setType(value, adapterType, value);\n    }\n    switch (key) {\n    case 0:\n    case 'type':\n      switch (value) {\n      case 'ObjectId':\n        data[key] = sqlTypes.ObjectId;\n        break;\n      case 'String':\n        if (option.maxLength) {\n          data[key] = sqlTypes.String.length;\n        } else if (option.maxLength === 1 || option.minLength === 1) {\n          data[key] = sqlTypes.String.singleLength;\n        } else {\n          data[key] = sqlTypes.String.noLength;\n        }\n\n        break;\n      case 'Number':\n        if (option.isAutoIncrement) {\n          [data[key]] = sqlTypes.Number.autoIncrement;\n        } else if (option.min && option.max && adapterType === constant.ADAPTER.POSTGRESQL) {\n          data[key] = sqlTypes.Number.minMax;\n        } else {\n          data[key] = sqlTypes.Number.noOption;\n        }\n        break;\n      case 'Boolean':\n        data[key] = sqlTypes.Boolean;\n        break;\n      case 'Date':\n        data[key] = sqlTypes.Date;\n        break;\n      case 'SingleLine':\n      case 'Email':\n      case 'URL':\n        data[key] = sqlTypes.SingleLine;\n        break;\n      case 'MultiLine':\n        data[key] = sqlTypes.MultiLine;\n        break;\n      case 'Object':\n        if (adapterType === constant.ADAPTER.MSSQL) {\n          data[key] = sqlTypes.Object.mssql;\n        } else if (adapterType === constant.ADAPTER.MYSQL) {\n          data[key] = sqlTypes.Object.mysql;\n        } else if (adapterType === constant.ADAPTER.POSTGRESQL) {\n          [, data[key]] = sqlTypes.Object.postgres;\n        }\n        break;\n      case 'Map':\n        if (adapterType === constant.ADAPTER.MSSQL) {\n          data[key] = sqlTypes.Map.mssql;\n        } else if (adapterType === constant.ADAPTER.MYSQL) {\n          data[key] = sqlTypes.Map.mysql;\n        } else if (adapterType === constant.ADAPTER.POSTGRESQL) {\n          [, data[key]] = sqlTypes.Map.postgres;\n        }\n        break;\n      case 'JSON':\n        if (adapterType === constant.ADAPTER.MSSQL) {\n          data[key] = sqlTypes.JSON.mssql;\n        } else if (adapterType === constant.ADAPTER.MYSQL) {\n          data[key] = sqlTypes.JSON.mysql;\n        } else if (adapterType === constant.ADAPTER.POSTGRESQL) {\n          [, data[key]] = sqlTypes.JSON.postgres;\n        }\n        break;\n      case 'Array':\n        if (adapterType === constant.ADAPTER.MSSQL) {\n          data[key] = sqlTypes.Array.mssql;\n        } else if (adapterType === constant.ADAPTER.MYSQL) {\n          data[key] = sqlTypes.Array.mysql;\n        } else if (adapterType === constant.ADAPTER.POSTGRESQL) {\n          const pgArray = sqlTypes.Array.postgres;\n          const pgArrayType = `DataTypes.${data.innerDataType ?? 'STRING'}`;\n          data[key] = `${pgArray}(${pgArrayType})`;\n        }\n        break;\n      case 'Buffer':\n        data[key] = sqlTypes.Buffer;\n        break;\n      case 'Decimal':\n      case 'Percentage':\n      case 'Currency':\n        [, , data[key]] = sqlTypes.Decimal;\n        break;\n      case 'TINYSTRING':\n        data[key] = 'DataTypes.TEXT(\\'tiny\\')';\n        break;\n      case 'TINYINTEGER':\n        data[key] = 'DataTypes.TINYINT';\n        break;\n      default:\n        // eslint-disable-next-line no-case-declarations\n        if (sqlTypes.SequelizeTypes.includes(value)) {\n          if (adapterType === constant.ADAPTER.MSSQL) {\n            data[key] = `DataTypes.${value}`;\n          } else if (adapterType === constant.ADAPTER.MYSQL) {\n            data[key] = `DataTypes.${value}`;\n          } else if (adapterType === constant.ADAPTER.POSTGRESQL) {\n            data[key] = `DataTypes.${value}`;\n          }\n        }\n        break;\n      }\n      break;\n    case 'match':\n      key = 'is';\n      // eslint-disable-next-line no-prototype-builtins\n      if (!data.hasOwnProperty('validate')) {\n        data.validate = {};\n        data.validate[key] = value;\n      } else {\n        data.validate[key] = value;\n      }\n      break;\n    case 'ref':\n      /*\n       * key = \"reference\"\n       * data[key] = value;\n       */\n      break;\n    case 'required':\n      key = 'allowNull';\n      data[key] = !value;\n      break;\n    case 'default':\n      key = 'defaultValue';\n      if (typeof value === 'boolean') {\n        data[key] = value;\n      } else if (typeof value === 'number') {\n        data[key] = value;\n      } else if (typeof value === 'bigint') {\n        data[key] = value;\n      } else if (value !== undefined && value !== null) {\n        if (typeof value === 'string') {\n          if (!value.includes('@@')) {\n            data[key] = `@@${value}@@`;\n          } else {\n            data[key] = `${value}`;\n          }\n        } else {\n          data[key] = `@@${value}@@`;\n        }\n      }\n      break;\n    case 'isAutoIncrement':\n      key = 'autoIncrement';\n      data[key] = value;\n      break;\n    case 'lowercase':\n      key = 'lowercase';\n      data[key] = value;\n      break;\n    case 'trim':\n      key = 'trim';\n      data[key] = value;\n      break;\n    case 'unique':\n      key = 'unique';\n      // eslint-disable-next-line no-prototype-builtins\n      if (data.hasOwnProperty('type')) {\n        if (data.type !== 'DataTypes.TEXT') {\n          data[key] = value;\n        }\n      }\n      break;\n    case 'min':\n      key = 'min';\n      // eslint-disable-next-line no-prototype-builtins\n      if (!data.hasOwnProperty('validate')) {\n        data.validate = {};\n        data.validate[key] = value;\n      } else {\n        data.validate[key] = value;\n      }\n      break;\n    case 'max':\n      key = 'max';\n      // eslint-disable-next-line no-prototype-builtins\n      if (!data.hasOwnProperty('validate')) {\n        data.validate = {};\n        data.validate[key] = value;\n      } else {\n        data.validate[key] = value;\n      }\n      break;\n    case 'primary':\n      key = 'primaryKey';\n      data[key] = value;\n      break;\n    case 'minLength':\n      // eslint-disable-next-line no-prototype-builtins\n      if (!data.hasOwnProperty('validate')) {\n        data.validate = {};\n        data.validate.len = [];\n        // eslint-disable-next-line no-prototype-builtins\n        if (!data.validate.hasOwnProperty('len')) {\n          data.validate.len = [];\n          data.validate.len.push(value ?? 18);\n        }\n        data.validate.len.push(value ?? 18);\n      } else {\n        // eslint-disable-next-line no-prototype-builtins\n        if (!data.validate.hasOwnProperty('len')) {\n          data.validate.len = [];\n          data.validate.len.push(value ?? 18);\n        }\n        data.validate.len.push(value ?? 18);\n      }\n      break;\n    case 'maxLength':\n      // eslint-disable-next-line no-prototype-builtins\n      if (!data.hasOwnProperty('validate')) {\n        data.validate = {};\n        data.validate.len = [];\n        // eslint-disable-next-line no-prototype-builtins\n        if (!data.validate.hasOwnProperty('len')) {\n          data.validate.len = [];\n          data.validate.len.push(value ?? 50);\n        }\n        data.validate.len.push(value ?? 50);\n      } else {\n        // eslint-disable-next-line no-prototype-builtins\n        if (!data.validate.hasOwnProperty('len')) {\n          data.validate.len = [];\n          data.validate.len.push(value ?? 50);\n        }\n        data.validate.len.push(value ?? 50);\n      }\n      break;\n    default:\n      break;\n    }\n  });\n  removeKeys(data);\n  return data;\n}\n\nmodule.exports = { setType };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/service/index.js",
    "content": "/* eslint-disable no-restricted-syntax */\nconst {\n  isEmpty, forEach, pickBy, find, cloneDeep, has,\n} = require('lodash');\nconst { isUri } = require('valid-url');\nconst writeOperations = require('../../writeOperations');\nconst validation = require('../requestValidation');\nconst sequelizeValidation = require('../sequelize/requestValidation');\nconst postman = require('../postman');\nconst commonService = require('../utils/common');\nconst {\n  MODEL_FOR_ROLE_PERMISSION, DEFAULT_ADMIN_EMAIL, DEFAULT_ADMIN_USERNAME, DEFAULT_ROLE,\n} = require('../../constants/constant');\nconst generatePostmanCollection = require('../postman/generate-postman-collection');\nconst fakeDataMongoose = require('../generateFakeData');\nconst fakeDataSequelize = require('../generateFakeDataSequelize');\nconst { removeGivenKeyFromObject } = require('../utils/common');\n\nasync function createMVCBlankFolder (dir, userDirectoryStructure) {\n  writeOperations.mkdir(dir, userDirectoryStructure.controllerFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.modelFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.configFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.publicFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.routesFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.utilsFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.validationFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.serviceFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.middlewareFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.viewsFolderPath);\n  writeOperations.mkdir(dir, 'postman');\n}\nfunction createAppName (Name) {\n  return Name\n    .replace(/[^A-Za-z0-9.-]+/g, '-')\n    .replace(/^[-_.]+|-+$/g, '')\n    .toLowerCase();\n}\nasync function createPackageJson ({\n  name,\n  packages,\n  mainJsFile,\n  sequenceGenerator,\n  jsonData,\n}) {\n  const pkg = {\n    name: createAppName(name),\n    version: '0.0.1',\n    private: true,\n    scripts: { start: `nodemon ${mainJsFile}` },\n    dependencies: {\n      'cookie-parser': '~1.4.4',\n      debug: '~2.6.9',\n      express: '~4.16.1',\n      mongoose: '~6.2.5',\n      dayjs: '~1.10.7',\n      'mongoose-paginate-v2': '~1.3.12',\n      morgan: '~1.9.1',\n      joi: '~17.3.0',\n      'mongoose-id-validator': '~0.6.0',\n      'mongoose-unique-validator': '~3.0.0',\n      dotenv: '~8.2.0',\n      ejs: '~3.1.6',\n      'express-rate-limit': '~5.2.6',\n      cors: '~2.8.5',\n    },\n    devDependencies: {\n      eslint: '~8.10.0',\n      'eslint-config-airbnb': '~18.2.1',\n      'eslint-plugin-import': '~2.25.4',\n      nodemon: '~2.0.15',\n    },\n  };\n  forEach(packages?.dependencies, (depValue, depName) => {\n    if (isUri(depValue)) {\n      packages.dependencies[depName] = `git+${depValue}`;\n    }\n  });\n  forEach(packages?.devDependencies, (depValue, depName) => {\n    if (isUri(depValue)) {\n      packages.devDependencies[depName] = `git+${depValue}`;\n    }\n  });\n  if (!isEmpty(packages)) {\n    if (packages.dependencies) Object.assign(pkg.dependencies, packages.dependencies);\n    if (packages.devDependencies) Object.assign(pkg.devDependencies, packages.devDependencies);\n    if (packages.scripts) Object.assign(pkg.scripts, packages.scripts);\n  }\n  if (!isEmpty(sequenceGenerator)) {\n    Object.assign(pkg.dependencies, { 'mongoose-sequence': '~5.3.1' });\n  }\n  if (!isEmpty(jsonData.rolePermission)) {\n    Object.assign(pkg.dependencies, { 'express-list-endpoints': '~5.0.0' });\n  }\n  return pkg;\n}\n\nasync function createPackageJsonForSequelize ({\n  name,\n  packages,\n  mainJsFile,\n  adapter,\n  jsonData,\n}) {\n  const pkg = {\n    name: createAppName(name),\n    version: '0.0.1',\n    private: true,\n    scripts: { start: `node ${mainJsFile}` },\n    dependencies: {\n      'cookie-parser': '~1.4.4',\n      debug: '~2.6.9',\n      express: '~4.16.1',\n      morgan: '~1.9.1',\n      joi: '~17.3.0',\n      dotenv: '~8.2.0',\n      ejs: '~3.1.6',\n      dayjs: '~1.10.7',\n      'express-rate-limit': '~5.2.6',\n      cors: '~2.8.5',\n      'sequelize-paginate': '~1.1.6',\n      'sequelize-transforms': '~2.0.0',\n    },\n  };\n  forEach(packages?.dependencies, (depValue, depName) => {\n    if (isUri(depValue)) {\n      packages.dependencies[depName] = `git+${depValue}`;\n    }\n  });\n  forEach(packages?.devDependencies, (depValue, depName) => {\n    if (isUri(depValue)) {\n      packages.devDependencies[depName] = `git+${depValue}`;\n    }\n  });\n  if (!isEmpty(packages)) {\n    if (packages.dependencies) Object.assign(pkg.dependencies, packages.dependencies);\n    if (packages.devDependencies) pkg.devDependencies = packages.devDependencies;\n    if (packages.scripts) Object.assign(pkg.scripts, packages.scripts);\n  }\n  if (!isEmpty(adapter)) {\n    Object.assign(pkg.dependencies, { sequelize: '~6.6.5' });\n    if (adapter === 'mssql') {\n      Object.assign(pkg.dependencies, { tedious: '~11.0.9' });\n    } else if (adapter === 'mysql') {\n      Object.assign(pkg.dependencies, { mysql2: '~2.2.5' });\n    } else if (adapter === 'postgres') {\n      Object.assign(pkg.dependencies, { pg: '~8.6.0' });\n    }\n    if (!isEmpty(jsonData.rolePermission)) {\n      Object.assign(pkg.dependencies, { 'express-list-endpoints': '~5.0.0' });\n    }\n  }\n  return pkg;\n}\n\nasync function setUpAppJS (templateFolder, jsonData) {\n  const app = writeOperations.loadTemplate(`${templateFolder}/app.js`);\n\n  app.locals.NO_PLATFORM = false;\n  app.locals.localModules = Object.create(null);\n  app.locals.modules = Object.create(null);\n  app.locals.mounts = [];\n  app.locals.uses = [];\n\n  // Request logger\n  app.locals.modules.logger = 'morgan';\n  app.locals.uses.push('logger(\\'dev\\')');\n\n  // Body parsers\n  app.locals.uses.push('express.json()');\n  app.locals.uses.push('express.urlencoded({ extended: false })');\n\n  // Cookie parser\n  app.locals.modules.cookieParser = 'cookie-parser';\n  app.locals.uses.push('cookieParser()');\n\n  app.locals.uses.push('express.static(path.join(__dirname, \\'public\\'))');\n\n  // role and permission\n  if (jsonData && !isEmpty(jsonData.rolePermission)) {\n    /*\n     * app.locals.ROLES = commonService.uniqRolesFromRolePermissions(jsonData.rolePermission);\n     * app.locals.ROLE_PERMISSION_MODELS = Object.keys(MODEL_FOR_ROLE_PERMISSION);\n     */\n    app.locals.SHOULD_ADD_ROLE_PERMISSION = true;\n  } else {\n    app.locals.SHOULD_ADD_ROLE_PERMISSION = false;\n  }\n  return app;\n}\n\nasync function setDB (dir, adapter = '') {\n  const db = writeOperations.loadTemplate(`${dir}/db.js`);\n  if (!isEmpty(adapter)) {\n    db.locals.ADAPTER = adapter;\n    const dbConnection = writeOperations.loadTemplate(`${dir}/dbConnection.js`);\n    return {\n      db,\n      dbConnection,\n    };\n  }\n  return db;\n}\nasync function createEnvFile (templateFolder, jsonData, {\n  database, port,\n}, options = {}) {\n  const env = writeOperations.loadTemplate(`${templateFolder}/.env`);\n  const envs = {\n    env: {},\n    customEnv: {},\n  };\n\n  env.locals.ENV = {\n    PORT: port,\n    DB_URL: `mongodb://localhost:27017/${database}`,\n    DB_TEST_URL: `mongodb://localhost:27017/${database}_test`,\n    ALLOW_ORIGIN: '*',\n  };\n\n  if (!isEmpty(jsonData.fileUpload) && !isEmpty(jsonData.fileUpload.uploads)) {\n    const flag = find(jsonData.fileUpload.uploads, (u) => u.storage.toLowerCase() === 's3' || u.storage.toLowerCase() === 's3_private');\n    if (!isEmpty(flag)) {\n      env.locals.ENV = {\n        ...env.locals.ENV,\n        AWS_S3_ACCESS_KEY_ID: 'access-key',\n        AWS_S3_SECRET_ACCESS_KEY: 'secret-access-key',\n        AWS_S3_REGION: 'region',\n        AWS_S3_BUCKET_NAME: 'bucket',\n      };\n    }\n    const s3Private = find(jsonData.fileUpload.uploads, (u) => u.storage.toLowerCase() === 's3_private');\n    if (!isEmpty(s3Private)) {\n      env.locals.ENV = {\n        ...env.locals.ENV,\n        AWS_URL_EXPIRATION: 3600,\n      };\n    }\n  }\n\n  if (!isEmpty(options)) {\n    if (!isEmpty(options.env)) {\n      for (const [k, v] of Object.entries(options.env)) {\n        if (k === 'DEVELOPMENT') {\n          if ('PORT' in v) {\n            port = v.PORT;\n            jsonData.config.port = port;\n          }\n          if ('DB_URL' in v) {\n            v.DB_URL = `mongodb://localhost:27017/${v.DB_URL}`;\n          }\n          env.locals.ENV = {\n            ...env.locals.ENV,\n            ...v,\n          };\n        } else {\n          const customEnv = writeOperations.loadTemplate(`${templateFolder}/customEnv`);\n          customEnv.locals.CUSTOM_ENV = {\n            PORT: port,\n            DB_URL: `mongodb://localhost:27017/${database}`,\n            DB_TEST_URL: `mongodb://localhost:27017/${database}_test`,\n            ALLOW_ORIGIN: '*',\n            ...v,\n          };\n          customEnv.locals.CUSTOM_ENV = pickBy(customEnv.locals.CUSTOM_ENV, (v1) => v1 !== undefined);\n          envs.customEnv[k] = customEnv;\n        }\n      }\n    }\n    if (options.socialAuth !== undefined && options.socialAuth.required) {\n      for (let i = 0; i < options.socialAuth.platforms.length; i += 1) {\n        const platform = options.socialAuth.platforms[i].type;\n        // eslint-disable-next-line prefer-const\n        if (!('clientSecret' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.clientSecret)) {\n          options.socialAuth.platforms[i].credential = {\n            ...options.socialAuth.platforms[i].credential,\n            clientSecret: 'xxxxxxxxxxxxx',\n          };\n          // Object.assign(options.socialAuth.platforms[i].credential, { clientSecret: 'xxxxxxxxxxxxx' });\n        }\n        if (!('clientId' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.clientId)) {\n          options.socialAuth.platforms[i].credential = {\n            ...options.socialAuth.platforms[i].credential,\n            clientId: 'xxx-xxx-xxx-xx',\n          };\n          // Object.assign(options.socialAuth.platforms[i].credential, { clientId: 'xxx-xxx-xxx-xx' });\n        }\n\n        let callbackURL = '';\n        if (!('callbackUrl' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.callbackUrl)) {\n          callbackURL = `https://localhost:${port}/auth/${platform.toLowerCase()}/callback`;\n        } else {\n          callbackURL = `https://localhost:${port}${options.socialAuth.platforms[i].credential.callbackUrl}`;\n        }\n        options.socialAuth.platforms[i].credential = {\n          ...options.socialAuth.platforms[i].credential,\n          callbackUrl: callbackURL,\n        };\n\n        let errorURL = '';\n        if (!('errorUrl' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.errorUrl)) {\n          errorURL = `https://localhost:${port}/auth/${platform.toLowerCase()}/error`;\n        } else {\n          errorURL = `https://localhost:${port}${options.socialAuth.platforms[i].credential.errorUrl}`;\n        }\n        options.socialAuth.platforms[i].credential = {\n          ...options.socialAuth.platforms[i].credential,\n          errorUrl: errorURL,\n        };\n\n        // eslint-disable-next-line prefer-const\n        for (let [k, v] of Object.entries(options.socialAuth.platforms[i].credential)) {\n          if (v !== '') {\n            env.locals.ENV = {\n              ...env.locals.ENV,\n              [`${platform.toUpperCase()}_${k.toUpperCase()}`]: v,\n            };\n          }\n        }\n      }\n    }\n  }\n  env.locals.ENV = pickBy(env.locals.ENV, (v) => v !== undefined);\n  envs.env = env;\n  return {\n    envs,\n    jsonData,\n  };\n}\n\nasync function createEnvFileSequelize (templateFolder, jsonData, {\n  database, port,\n}, options = {}) {\n  const env = writeOperations.loadTemplate(`${templateFolder}/.env`);\n  const envs = {\n    env: {},\n    customEnv: {},\n  };\n\n  let dbPort;\n  if (jsonData.adapter === 'mysql') {\n    dbPort = 3306;\n  } else if (jsonData.adapter === 'mssql') {\n    dbPort = 1433;\n  } else if (jsonData.adapter === 'postgres') {\n    dbPort = 5432;\n  }\n  env.locals.ENV = {\n    PORT: port,\n    DATABASE_NAME: `${database}`,\n    ALLOW_ORIGIN: '*',\n    DATABASE_USERNAME: 'user',\n    DATABASE_PASSWORD: 'password',\n    HOST: 'localhost',\n    DB_PORT: dbPort,\n  };\n\n  if (options.shouldAddTestCaseVariables) {\n    Object.assign(env.locals.ENV, {\n      TEST_HOST: 'localhost',\n      TEST_DATABASE_USERNAME: 'test_user',\n      TEST_DATABASE_PASSWORD: 'test_password',\n      TEST_DATABASE_NAME: `${database}_test`,\n      TEST_DB_PORT: dbPort,\n    });\n  }\n  if (!isEmpty(jsonData.fileUpload) && !isEmpty(jsonData.fileUpload.uploads)) {\n    const flag = find(jsonData.fileUpload.uploads, (u) => u.storage.toLowerCase() === 's3' || u.storage.toLowerCase() === 's3_private');\n    if (!isEmpty(flag)) {\n      env.locals.ENV = {\n        ...env.locals.ENV,\n        AWS_S3_ACCESS_KEY_ID: 'access-key',\n        AWS_S3_SECRET_ACCESS_KEY: 'secret-access-key',\n        AWS_S3_REGION: 'region',\n        AWS_S3_BUCKET_NAME: 'bucket',\n      };\n    }\n    const s3Private = find(jsonData.fileUpload.uploads, (u) => u.storage.toLowerCase() === 's3_private');\n    if (!isEmpty(s3Private)) {\n      env.locals.ENV = {\n        ...env.locals.ENV,\n        AWS_URL_EXPIRATION: 3600,\n      };\n    }\n  }\n\n  if (!isEmpty(options)) {\n    if (!isEmpty(options.env)) {\n      for (const [k, v] of Object.entries(options.env)) {\n        if (k === 'DEVELOPMENT') {\n          if ('PORT' in v) {\n            port = v.PORT;\n            jsonData.config.port = port;\n          }\n          env.locals.ENV = {\n            ...env.locals.ENV,\n            ...v,\n          };\n        } else {\n          const customEnv = writeOperations.loadTemplate(`${templateFolder}/customEnv`);\n          customEnv.locals.CUSTOM_ENV = {\n            PORT: port,\n            DATABASE_NAME: `${database}`,\n            ALLOW_ORIGIN: '*',\n            DATABASE_USERNAME: 'user',\n            DATABASE_PASSWORD: 'password',\n            HOST: 'localhost',\n            DB_PORT: dbPort,\n            ...v,\n          };\n          customEnv.locals.CUSTOM_ENV = pickBy(customEnv.locals.CUSTOM_ENV, (v1) => v1 !== undefined);\n          envs.customEnv[k] = customEnv;\n        }\n      }\n    }\n    if (options.socialAuth !== undefined && options.socialAuth.required) {\n      for (let i = 0; i < options.socialAuth.platforms.length; i += 1) {\n        const platform = options.socialAuth.platforms[i].type;\n        // eslint-disable-next-line prefer-const\n        if (!('clientSecret' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.clientSecret)) {\n          options.socialAuth.platforms[i].credential = {\n            ...options.socialAuth.platforms[i].credential,\n            clientSecret: 'xxxxxxxxxxxxx',\n          };\n          // Object.assign(options.socialAuth.platforms[i].credential, { clientSecret: 'xxxxxxxxxxxxx' });\n        }\n        if (!('clientId' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.clientId)) {\n          options.socialAuth.platforms[i].credential = {\n            ...options.socialAuth.platforms[i].credential,\n            clientId: 'xxx-xxx-xxx-xx',\n          };\n          // Object.assign(options.socialAuth.platforms[i].credential, { clientId: 'xxx-xxx-xxx-xx' });\n        }\n        let callbackURL = '';\n        if (!('callbackUrl' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.callbackUrl)) {\n          callbackURL = `https://localhost:${port}/auth/${platform.toLowerCase()}/callback`;\n        } else {\n          callbackURL = `https://localhost:${port}${options.socialAuth.platforms[i].credential.callbackUrl}`;\n        }\n        options.socialAuth.platforms[i].credential = {\n          ...options.socialAuth.platforms[i].credential,\n          callbackUrl: callbackURL,\n        };\n        let errorURL = '';\n        if (!('errorUrl' in options.socialAuth.platforms[i].credential) || isEmpty(options.socialAuth.platforms[i].credential.errorUrl)) {\n          errorURL = `https://localhost:${port}/auth/${platform.toLowerCase()}/error`;\n        } else {\n          errorURL = `https://localhost:${port}${options.socialAuth.platforms[i].credential.errorUrl}`;\n        }\n        options.socialAuth.platforms[i].credential = {\n          ...options.socialAuth.platforms[i].credential,\n          errorUrl: errorURL,\n        };\n\n        // eslint-disable-next-line prefer-const\n        for (let [k, v] of Object.entries(options.socialAuth.platforms[i].credential)) {\n          if (v !== '') {\n            env.locals.ENV = {\n              ...env.locals.ENV,\n              [`${platform.toUpperCase()}_${k.toUpperCase()}`]: v,\n            };\n          }\n        }\n      }\n    }\n  }\n  env.locals.ENV = pickBy(env.locals.ENV, (v) => v !== undefined);\n  envs.env = env;\n  return {\n    envs,\n    jsonData,\n  };\n}\n\nasync function createValidationFile (validationFilePath, jsonData, auth, adapter = '', enumData) {\n  const {\n    isAuth, userModel, socialAuth,\n  } = auth;\n  if (socialAuth.required) {\n    const ssoAuthKeys = { ssoAuth: {} };\n    if (isEmpty(adapter)) {\n      for (let i = 0; i < socialAuth.platforms.length; i += 1) {\n        Object.assign(ssoAuthKeys.ssoAuth, { [`${socialAuth.platforms[i].type.toLowerCase()}Id`]: { type: 'String' } });\n      }\n    } else {\n      for (let i = 0; i < socialAuth.platforms.length; i += 1) {\n        Object.assign(ssoAuthKeys.ssoAuth, { [`${socialAuth.platforms[i].type.toLowerCase()}Id`]: { type: 'STRING' } });\n      }\n    }\n    forEach(jsonData[userModel], (v, k) => {\n      if (k.includes('SSO'.toLowerCase())) {\n        delete jsonData[userModel][k];\n      }\n    });\n    Object.assign(jsonData[userModel], ssoAuthKeys);\n  }\n  const {\n    modelObj, updateModelObj,\n  } = adapter ? await sequelizeValidation.getValidation(jsonData, enumData) : await validation.getValidation(jsonData, enumData);\n\n  jsonData = modelObj;\n  const validatedObj = {};\n\n  forEach(jsonData.models, (value, key) => {\n    let flag = false;\n    for (const index in enumData) {\n      if (index === key) {\n        flag = true;\n      }\n    }\n    const validationTemp = writeOperations.loadTemplate(`${validationFilePath.templateFolderName}/${validationFilePath.validationFolderPath}/validateSchema.js`);\n    const jsonValStr = JSON.stringify(value, null, '\\t');\n    const updateJsonStr = JSON.stringify(updateModelObj.models[key], null, '\\t');\n    let valStr = '';\n    let updateValStr = '';\n    valStr = jsonValStr.toString().replace(/\"/g, '');\n    updateValStr = updateJsonStr.toString().replace(/\"/g, '');\n    if (isAuth && userModel === key) {\n      validationTemp.locals.IS_AUTH = true;\n    } else {\n      validationTemp.locals.IS_AUTH = false;\n    }\n    if (flag) {\n      validationTemp.locals.ENUM_SUPPORT = enumData;\n    } else {\n      validationTemp.locals.ENUM_SUPPORT = false;\n    }\n    if (enumData && enumData[key]) {\n      const array = [];\n      for (const enumIndex in enumData[key]) {\n        if (!array.includes(enumData[key][enumIndex].enumFile)) {\n          array.push(enumData[key][enumIndex].enumFile);\n        }\n      }\n      validationTemp.locals.ENUM_VALIDATION = array;\n    } else {\n      validationTemp.locals.ENUM_VALIDATION = false;\n    }\n    validationTemp.locals.UPDATE_VALIDATION_KEY = updateValStr;\n    validationTemp.locals.VALIDATION_KEY = valStr;\n    validationTemp.locals.MODEL_NAME = key;\n    validationTemp.locals.PATH = validationFilePath.validationFolderPath;\n    validationTemp.locals.MODEL_NAME = key;\n    if (!isEmpty(jsonData.validationVariables) && !isEmpty(jsonData.validationVariables[key])) {\n      validationTemp.locals.VARIABLES = jsonData.validationVariables[key];\n    }\n    validatedObj[key] = validationTemp;\n  });\n  return validatedObj;\n}\nasync function createPostmanCollection (pName, postmanCollections, auth) {\n  const {\n    isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth,\n  } = auth;\n  const infoForPostman = {\n    project: {},\n    item: null,\n  };\n  infoForPostman.project.name = pName;\n  infoForPostman.project.descriptions = `${pName} API Collections`;\n  const platforms = await postman.getCollectionForPostman(postmanCollections, isAuth, userModel, userLoginWith, loginAccessPlatform, userRoles, socialAuth);\n  infoForPostman.item = platforms;\n  const jsonCollectionsV20 = await generatePostmanCollection.createCollectionV2_0(infoForPostman);\n  const jsonCollectionsV21 = await generatePostmanCollection.createCollectionV2_1(infoForPostman);\n  const envPostman = await postman.generateEnvForPostman(postmanCollections.config);\n  return [jsonCollectionsV20, jsonCollectionsV21, envPostman];\n}\nasync function createCCBlankFolder (dir, userDirectoryStructure) {\n  writeOperations.mkdir(dir, userDirectoryStructure.controllerFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.modelFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.entityFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.configFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.publicFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.routesFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.helperFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.utilsFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.validationFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.serviceFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.middlewareFolderPath);\n  writeOperations.mkdir(dir, userDirectoryStructure.viewsFolderPath);\n  writeOperations.mkdir(dir, 'postman');\n  writeOperations.mkdir(dir, 'seeders');\n}\n\nasync function envParser (env) {\n  const envObj = {};\n  forEach(env.environments, (value) => {\n    envObj[value] = {};\n    forEach(env.customJson, (envKeyValue) => {\n      envObj[value][envKeyValue.key] = envKeyValue.value[value];\n    });\n  });\n  return envObj;\n}\n\nasync function addSeederMongoose (jsonData, filePath, authObj) {\n  const roles = authObj.userRoles;\n  const { models } = jsonData;\n  const seeder = writeOperations.loadTemplate(`${filePath}/index.js`);\n  const credentials = !isEmpty(jsonData.authentication.credentials) ? jsonData.authentication.credentials : {};\n  const { userModel } = authObj;\n  const array = []; const userArray = []; const passwordArray = []; const\n    getRoles = [];\n  const requiredKeys = [];\n  const user = {};\n  const userRoleArray = [];\n  forEach(models, (allSchema, allModels) => {\n    if (allModels === userModel) {\n      forEach(allSchema, (nestSchema, nestModel) => {\n        if (has(nestSchema, 'required')) {\n          requiredKeys.push(nestModel);\n        }\n      });\n    }\n  });\n  forEach(roles, (allRoles) => {\n    const fakeDataOfModels = fakeDataMongoose.validSchema(cloneDeep(models));\n    if (!isEmpty(requiredKeys)) {\n      for (const credentialKeys of credentials) {\n        for (const keys of requiredKeys) {\n          if (keys in fakeDataOfModels[userModel]) {\n            credentialKeys[keys] = fakeDataOfModels[userModel][keys];\n          }\n        }\n      }\n    }\n    let authFakeData = {};\n    if (!isEmpty(credentials)) {\n      const existCredentials = credentials.find((credential) => (credential.type === allRoles));\n      if (!isEmpty(existCredentials)) {\n        authFakeData = existCredentials;\n      } else {\n        authFakeData = fakeDataOfModels[userModel];\n      }\n    } else {\n      authFakeData = fakeDataOfModels[userModel];\n    }\n\n    if (allRoles !== 'SYSTEM_USER') {\n      authFakeData = removeGivenKeyFromObject(authFakeData,\n        ['id', 'resetPasswordLink', 'loginRetryLimit', 'loginReactiveTime', 'addedBy', 'role', 'isActive', 'isDeleted', 'updatedBy', 'createdAt', 'updatedAt']);\n      user[allRoles] = authFakeData;\n      const rolesArray = [];\n      rolesArray.push(roles);\n      const userToBeSeeded = {\n        [authObj.userLoginWith.password]: `${authFakeData[authObj.userLoginWith.password]}`,\n        [authObj.userLoginWith.username[0]]: `${authFakeData[authObj.userLoginWith.username[0]]}`,\n      };\n      for (const i of requiredKeys) {\n        if (has(authFakeData, i)) {\n          userToBeSeeded[i] = authFakeData[i];\n        }\n      }\n      const userFindCondition = {\n        [authObj.userLoginWith.username[0]]: authFakeData[authObj.userLoginWith.username[0]],\n        isActive: true,\n        isDeleted: false,\n      };\n\n      userRoleArray.push({\n        [authObj.userLoginWith.username[0]]: `${authFakeData[authObj.userLoginWith.username[0]]}`,\n        [authObj.userLoginWith.password]: `${authFakeData[authObj.userLoginWith.password]}`,\n      });\n\n      const userPassword = authFakeData[authObj.userLoginWith.password];\n      array.push(userFindCondition);\n      passwordArray.push(userPassword);\n      userArray.push(userToBeSeeded);\n      getRoles.push(allRoles);\n\n      seeder.locals.USER_EXIST_CONDITION = array;\n      seeder.locals.USER_PASSWORD = passwordArray;\n      seeder.locals.USER = userArray;\n      seeder.locals.AUTH_MODEL = userModel;\n      seeder.locals.ROLE_NAME = getRoles;\n      seeder.locals.IS_AUTH = authObj.isAuth ? authObj.isAuth : false;\n      seeder.locals.PASSWORD_FIELD = authObj.userLoginWith.password;\n      seeder.locals.AUTH_MODEL_FC = userModel.charAt(0).toUpperCase() + userModel.slice(1);\n    }\n    // role permission\n    if (!isEmpty(jsonData.rolePermission)) {\n      seeder.locals.ROLES = commonService.uniqRolesFromRolePermissions(jsonData.rolePermission);\n      seeder.locals.ROLE_PERMISSION_MODELS = Object.keys(MODEL_FOR_ROLE_PERMISSION);\n      seeder.locals.SHOULD_ADD_ROLE_PERMISSION = true;\n      seeder.locals.ROUTE_ROLE_ARRAY = commonService.getRouteRoleArray(jsonData.rolePermission);\n      seeder.locals.DEFAULT_ADMIN_EMAIL = DEFAULT_ADMIN_EMAIL;\n      seeder.locals.DEFAULT_ADMIN_USERNAME = DEFAULT_ADMIN_USERNAME;\n      seeder.locals.DEFAULT_ROLE = DEFAULT_ROLE;\n      seeder.locals.USER_ROLE_ARRAY = userRoleArray;\n    } else {\n      seeder.locals.SHOULD_ADD_ROLE_PERMISSION = false;\n    }\n  });\n  return [seeder, user];\n}\n\nasync function addSeederSequelize (jsonData, filePath, authObj) {\n  // const roles = commonService.uniqRolesFromRolePermissions(jsonData.rolePermission);\n  const roles = authObj.userRoles;\n  const { models } = jsonData;\n  const seeder = writeOperations.loadTemplate(`${filePath}/index.js`);\n  const { userModel } = authObj;\n  const credentials = !isEmpty(jsonData.authentication.credentials) ? jsonData.authentication.credentials : {};\n  const array = []; const userArray = []; const passwordArray = []; const\n    getRoles = [];\n  const user = {};\n  const requiredKeys = [];\n  const userRoleArray = [];\n  forEach(models, (allSchema, allModels) => {\n    if (allModels === userModel) {\n      forEach(allSchema, (nestSchema, nestModel) => {\n        if (has(nestSchema, 'required')) {\n          requiredKeys.push(nestModel);\n        }\n      });\n    }\n  });\n  forEach(roles, (allRoles) => {\n    const fakeDataOfModels = fakeDataSequelize.validSchema(cloneDeep(models));\n    if (!isEmpty(requiredKeys)) {\n      for (const credentialKeys of credentials) {\n        for (const keys of requiredKeys) {\n          if (keys in fakeDataOfModels[userModel]) {\n            credentialKeys[keys] = fakeDataOfModels[userModel][keys];\n          }\n        }\n      }\n    }\n    let authFakeData = {};\n    if (!isEmpty(credentials)) {\n      const existCredentials = credentials.find((credential) => (credential.type === allRoles));\n      if (!isEmpty(existCredentials)) {\n        authFakeData = existCredentials;\n      } else {\n        authFakeData = fakeDataOfModels[userModel];\n      }\n    } else {\n      authFakeData = fakeDataOfModels[userModel];\n    }\n    if (allRoles !== 'SYSTEM_USER') {\n      authFakeData = removeGivenKeyFromObject(authFakeData,\n        ['id', 'resetPasswordLink', 'loginRetryLimit', 'loginReactiveTime', 'addedBy', 'role', 'isActive', 'isDeleted', 'updatedBy', 'createdAt', 'updatedAt']);\n      user[allRoles] = authFakeData;\n      const userToBeSeeded = {\n        [authObj.userLoginWith.password]: `${authFakeData[authObj.userLoginWith.password]}`,\n        [authObj.userLoginWith.username[0]]: `${authFakeData[authObj.userLoginWith.username[0]]}`,\n      };\n      for (const i of requiredKeys) {\n        if (has(authFakeData, i)) {\n          userToBeSeeded[i] = authFakeData[i];\n        }\n      }\n      const userFindCondition = {\n        [authObj.userLoginWith.username[0]]: authFakeData[authObj.userLoginWith.username[0]],\n        isActive: true,\n        isDeleted: false,\n      };\n\n      userRoleArray.push({\n        [authObj.userLoginWith.username[0]]: `${authFakeData[authObj.userLoginWith.username[0]]}`,\n        [authObj.userLoginWith.password]: `${authFakeData[authObj.userLoginWith.password]}`,\n      });\n\n      const userPassword = authFakeData[authObj.userLoginWith.password];\n      array.push(userFindCondition);\n      passwordArray.push(userPassword);\n      userArray.push(userToBeSeeded);\n      getRoles.push(allRoles);\n      seeder.locals.USER_EXIST_CONDITION = array;\n      seeder.locals.USER_PASSWORD = passwordArray;\n      seeder.locals.USER = userArray;\n      seeder.locals.MODEL = userModel;\n      seeder.locals.ROLE_NAME = getRoles;\n      seeder.locals.IS_AUTH = authObj.isAuth ? authObj.isAuth : false;\n      seeder.locals.PASSWORD_FIELD = authObj.userLoginWith.password;\n      seeder.locals.AUTH_MODEL = userModel;\n      seeder.locals.AUTH_MODEL_FC = userModel.charAt(0).toUpperCase() + userModel.slice(1);\n      seeder.locals.USER_ROLE_ARRAY = userRoleArray;\n    }\n    // role and permission\n    if (!isEmpty(jsonData.rolePermission)) {\n      seeder.locals.ROLES = commonService.uniqRolesFromRolePermissions(jsonData.rolePermission);\n      seeder.locals.ROLE_PERMISSION_MODELS = Object.keys(MODEL_FOR_ROLE_PERMISSION);\n      seeder.locals.SHOULD_ADD_ROLE_PERMISSION = true;\n      seeder.locals.ROUTE_ROLE_ARRAY = commonService.getRouteRoleArray(jsonData.rolePermission);\n      seeder.locals.DEFAULT_ADMIN_EMAIL = DEFAULT_ADMIN_EMAIL;\n      seeder.locals.DEFAULT_ADMIN_USERNAME = DEFAULT_ADMIN_USERNAME;\n      seeder.locals.DEFAULT_ROLE = DEFAULT_ROLE;\n    } else {\n      seeder.locals.SHOULD_ADD_ROLE_PERMISSION = false;\n    }\n  });\n  return [seeder, user];\n}\nconst commonServiceFile = async (path, jsonData) => {\n  const common = writeOperations.loadTemplate(`${path}/common.js`);\n  common.locals.IS_AUTH = jsonData.authentication.isAuthentication;\n  common.locals.LOGIN_WITH = jsonData.authentication.loginWith?.username?.length ? jsonData.authentication.loginWith?.username : ['email'];\n  common.locals.MODEL = jsonData.authentication.authModel;\n  if (!isEmpty(jsonData.rolePermission)) {\n    common.locals.ROLE_PERMISSION = true;\n  } else {\n    common.locals.ROLE_PERMISSION = false;\n  }\n  return common;\n};\n\nmodule.exports = {\n  createMVCBlankFolder,\n  createPackageJson,\n  createPackageJsonForSequelize,\n  setUpAppJS,\n  setDB,\n  createEnvFile,\n  createValidationFile,\n  createPostmanCollection,\n  createCCBlankFolder,\n  envParser,\n  addSeederMongoose,\n  addSeederSequelize,\n  commonServiceFile,\n  createEnvFileSequelize,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/thirdPartyIntegrations/index.js",
    "content": "/* eslint-disable import/no-dynamic-require */\n/* eslint-disable global-require */\n/* eslint-disable no-console */\nconst { forEach } = require('lodash');\n\nasync function addSocialLogin (\n  {\n    jsonData, userModel, socialAuth, noOfDeviceAllowed,\n  },\n) {\n  const { platforms } = socialAuth;\n  const app = { locals: { uses: [] } };\n  const pkg = { dependencies: {} };\n  if (userModel && jsonData.models[userModel]) {\n    const keys = {};\n    const usernameArray = ['username', 'UserName', 'userName', 'Username'];\n    const imageArray = ['pic', 'photo', 'image', 'img', 'profilePic', 'Pic', 'ProfilePic', 'Img', 'Image', 'Photo'];\n    const firstNameArray = ['firstname', 'firstName', 'fname', 'FirstName', 'Fname', 'Firstname', 'FName'];\n    const lastNameArray = ['lastname', 'lastName', 'lname', 'LastName', 'Lname', 'Lastname', 'LName'];\n    Object.keys(jsonData.models[userModel]).forEach((k) => {\n      if (usernameArray.includes(k)) {\n        Object.assign(keys, { username: k });\n      }\n      if (imageArray.includes(k)) {\n        Object.assign(keys, { image: k });\n      }\n      if (firstNameArray.includes(k)) {\n        Object.assign(keys, { firstName: k });\n      }\n      if (lastNameArray.includes(k)) {\n        Object.assign(keys, { lastName: k });\n      }\n      if (k === 'name' || k === 'Name') {\n        Object.assign(keys, { name: k });\n      }\n    });\n    let projectType = jsonData.projectType.toLowerCase();\n    if (projectType === 'cc') {\n      projectType = 'clean-code';\n    }\n    let jsonObject = {\n      id: jsonData.id,\n      config: {\n        projectName: jsonData.config.projectName,\n        path: jsonData.config.path,\n      },\n      model: userModel,\n      keys,\n      projectType,\n      deviceRestriction: noOfDeviceAllowed.required,\n    };\n    if (jsonData.adapter && jsonData.ORM) {\n      jsonObject = {\n        ...jsonObject,\n        adapter: jsonData.adapter,\n        ORM: jsonData.ORM,\n      };\n    }\n    pkg.dependencies.passport = '~0.4.1';\n    forEach(platforms, async (p) => {\n      const main = require(`../../social/${p.type.toLowerCase()}/app.js`);\n      if (p.type.toLowerCase() === 'google') {\n        pkg.dependencies['passport-google-oauth20'] = '~2.0.0';\n      }\n      if (p.type.toLowerCase() === 'linkedin') {\n        pkg.dependencies['passport-linkedin-oauth2'] = '~2.0.0';\n      }\n      if (p.type.toLowerCase() === 'github') {\n        pkg.dependencies['passport-github2'] = '~0.1.12';\n      }\n      if (p.type.toLowerCase() === 'facebook') {\n        pkg.dependencies['passport-facebook'] = '~3.0.0';\n      }\n      jsonObject = {\n        ...jsonObject,\n        platforms: p.platforms,\n        credentials: p.credential || {},\n      };\n      Object.assign(jsonObject, { platforms: p.platforms });\n      await main(jsonObject);\n      app.locals.uses.push(`require('./routes/${p.type.toLowerCase()}-login-routes')`);\n    });\n  }\n  return {\n    app,\n    pkg,\n  };\n}\n\nmodule.exports = { addSocialLogin };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/createApplication/utils/common.js",
    "content": "const {\n  isEmpty, forEach, filter, chain, flatten, map, difference, groupBy, uniq, has, last,\n} = require('lodash');\nconst writeOperations = require('../../writeOperations');\n\nconst identifyPlatform = (modelConfig) => {\n  const admin = {}; const device = {}; const desktop = {}; const client = {};\n  const platform = {};\n  forEach(modelConfig, (value, model) => {\n    if (value.admin !== undefined) {\n      admin[model] = value.admin;\n    }\n    if (modelConfig[model].device !== undefined) {\n      device[model] = value.device;\n    }\n    if (modelConfig[model].desktop !== undefined) {\n      desktop[model] = value.desktop;\n    }\n    if (modelConfig[model].client !== undefined) {\n      client[model] = value.client;\n    }\n  });\n  platform.admin = admin;\n  platform.device = device;\n  platform.desktop = desktop;\n  platform.client = client;\n  return platform;\n};\nconst identifyPlatformNew = (modelConfig, platforms) => {\n  const platformFinal = {};\n  forEach(modelConfig, (value) => {\n    forEach(value, (obj, p) => {\n      if (!platforms.includes(p)) {\n        platforms.push(p);\n      }\n    });\n  });\n  forEach(modelConfig, (value, model) => {\n    forEach(platforms, (platform) => {\n      if (value[platform] !== undefined) {\n        if (!platformFinal[platform]) {\n          platformFinal[platform] = {};\n        }\n        platformFinal[platform][model] = value[platform];\n      }\n    });\n  });\n  return platformFinal;\n};\nconst getFilterLoggedUser = async (model, platformName, filterByLoggedInUser, authObj) => {\n  let filterLoggedUser = false;\n  if (authObj.isAuth && authObj.userModel !== model) {\n    if (authObj.authRoute) {\n      if (filterByLoggedInUser.isLoginUser) {\n        if (filterByLoggedInUser.platform[platformName]) {\n          if (!isEmpty(filterByLoggedInUser) && !isEmpty(filterByLoggedInUser.models) && !isEmpty(filterByLoggedInUser.models[model])) {\n            filterLoggedUser = filterByLoggedInUser.models[model];\n            if (isEmpty(filterLoggedUser.addedByKey)) {\n              filterLoggedUser.addedByKey = 'addedBy';\n            }\n          }\n        }\n      }\n    }\n  }\n  return filterLoggedUser;\n};\n\nconst getRandomIntByMax = (max) => Math.floor(Math.random() * max);\nconst getTemplateByName = (template, name) => {\n  let tmp;\n  if (!isEmpty(template.emailTemplate)) {\n    tmp = template.emailTemplate.find((val) => val.templateName === name);\n    if (!isEmpty(tmp)) {\n      const attributes = {};\n      for (let i = 0; i < tmp.customJson.length; i += 1) {\n        Object.assign(attributes, { [tmp.customJson[i].templateKey]: `${tmp.customJson[i].modelName}.${tmp.customJson[i].mappingKey}` });\n      }\n      Object.assign(tmp, { attribute: attributes });\n    }\n  }\n  if (!isEmpty(template.smsTemplate) && isEmpty(tmp)) {\n    tmp = template.smsTemplate.find((val) => val.templateName === name);\n    if (!isEmpty(tmp)) {\n      const attributes = {};\n      for (let i = 0; i < tmp.customJson.length; i += 1) {\n        Object.assign(attributes, { [tmp.customJson[i].templateKey]: `${tmp.customJson[i].modelName}.${tmp.customJson[i].mappingKey}` });\n      }\n      Object.assign(tmp, { attribute: attributes });\n    }\n  }\n  return tmp;\n};\nconst getUniqModelsFromTasks = (tasks, keyOfQueryBuilder) => {\n  let UNIQ_DN_REQUIRE_VALIDATION_MODELS;\n  let UNIQ_TASK_MODELS;\n  let UNIQ_REQUIRE_VALIDATION_MODELS;\n  const methodsThatRequireValidation = ['create', 'findOneAndUpdate', 'updateMany'];\n  const callTasks = filter(tasks, (t) => { if (t[`${keyOfQueryBuilder}`] !== undefined) { return true; } return false; });\n  const calls = flatten(map(callTasks, `${keyOfQueryBuilder}`));\n  if (calls && calls.length) {\n    const callsThatDNRequireValidation = filter(calls, (call) => { if (!methodsThatRequireValidation.includes(call.queryMode)) { return true; } return false; });\n    if (callsThatDNRequireValidation && callsThatDNRequireValidation.length) {\n      UNIQ_DN_REQUIRE_VALIDATION_MODELS = (chain(callsThatDNRequireValidation).map('model').uniq().value())\n        .filter(Boolean);\n    } else {\n      UNIQ_DN_REQUIRE_VALIDATION_MODELS = undefined;\n    }\n    UNIQ_TASK_MODELS = (chain(calls).map('model').uniq().value())\n      .filter(Boolean);\n    UNIQ_REQUIRE_VALIDATION_MODELS = UNIQ_DN_REQUIRE_VALIDATION_MODELS ? difference(UNIQ_TASK_MODELS, UNIQ_DN_REQUIRE_VALIDATION_MODELS) : UNIQ_TASK_MODELS;\n  } else {\n    UNIQ_TASK_MODELS = [];\n    UNIQ_DN_REQUIRE_VALIDATION_MODELS = [];\n    UNIQ_REQUIRE_VALIDATION_MODELS = [];\n  }\n  return [UNIQ_TASK_MODELS, UNIQ_REQUIRE_VALIDATION_MODELS];\n};\nconst removeQueryBuilderWithoutQueryMode = (queryBuilders, keyOfQueryBuilder) => {\n  forEach(queryBuilders, (queryBuilder) => {\n    if (queryBuilder[`${keyOfQueryBuilder}`] && queryBuilder[`${keyOfQueryBuilder}`].length) {\n      queryBuilder[`${keyOfQueryBuilder}`] = filter(queryBuilder[`${keyOfQueryBuilder}`], 'queryMode');\n      queryBuilder[`${keyOfQueryBuilder}`] = filter(queryBuilder[`${keyOfQueryBuilder}`], (query) => {\n        if (query.queryMode === 'codeBlock') {\n          return true;\n        } if (query.queryMode === 'fileUpload') {\n          return true;\n        }\n        if (query.queryMode !== 'codeBlock' && query.model) {\n          return true;\n        }\n        return false;\n      });\n    }\n  });\n\n  return queryBuilders;\n};\nconst transformSelect = (populateArray) => {\n  forEach(populateArray, (populateObj) => {\n    if (Object.prototype.hasOwnProperty.call(populateObj, 'select')) {\n      populateObj.select = (populateObj.select).join(' ');\n    }\n    if (Object.prototype.hasOwnProperty.call(populateObj, 'populate')) {\n      transformSelect(populateObj.populate);\n    }\n  });\n  return populateArray;\n};\n\nconst doesArrayContainSearchArray = (array, searchArray) => searchArray.every((v) => array.includes(v));\n\nfunction getImportPath (toPath, fromPath) {\n  let arrToPath = toPath.split('/');\n  let arrFromPath = fromPath.split('/');\n\n  arrToPath = arrToPath.filter((i) => i.length > 0);\n  arrFromPath = arrFromPath.filter((i) => i.length > 0);\n\n  arrFromPath = arrFromPath.reverse();\n  arrToPath = arrToPath.reverse();\n\n  const finalPath = []; let\n    pushArr = [];\n  for (let i = 0; i < arrToPath.length; i += 1) {\n    let notSame = false;\n    for (let j = 0; j < arrFromPath.length; j += 1) {\n      if (arrFromPath[j] !== arrToPath[i]) {\n        notSame = true;\n      } else {\n        notSame = false;\n        pushArr = arrFromPath.splice(0, arrFromPath.indexOf(arrFromPath[j]));\n        break;\n      }\n    }\n    if (notSame) {\n      finalPath.push('..');\n    } else {\n      pushArr = pushArr.reverse();\n      finalPath.push(pushArr.join('/'));\n      break;\n    }\n  }\n  if (finalPath.length === 1 && finalPath[0] !== '..') {\n    finalPath[0] = `./${finalPath[0]}`;\n  } else if (finalPath.length === 0) {\n    arrFromPath.reverse();\n    finalPath[0] = `./${arrFromPath.join('/')}`;\n  } else if (finalPath.every((val) => val === finalPath[0])) {\n    arrFromPath.reverse();\n    finalPath.push(arrFromPath.join('/'));\n  }\n  return finalPath.join('/');\n}\n\nconst getPlatformWiseAPIOfCustomRoutes = (customRoutes) => {\n  const platformWiseRoutes = groupBy(customRoutes, 'platform');\n  map(platformWiseRoutes, (routes, platform) => {\n    platformWiseRoutes[platform] = map(routes, (obj) => obj.api);\n  });\n  return platformWiseRoutes;\n};\n\nconst getPolicyForCustomRoutes = (customRoutes) => {\n  customRoutes = flatten(map(customRoutes, (obj) => obj.policies));\n  customRoutes = [...new Set(customRoutes)];\n  return customRoutes.filter(Boolean);\n};\nconst transformControllerDetailsWithQueryBuilder = (routes) => {\n  let isQueryBuilderAvailable = false;\n  // eslint-disable-next-line no-restricted-syntax\n  for (const route of routes) {\n    if (Object.prototype.hasOwnProperty.call(route, 'queryBuilder')) {\n      if (route.queryBuilder.length) {\n        isQueryBuilderAvailable = true;\n        const modelGroup = [...new Set(route.queryBuilder.map((item) => item.model))];\n        route.cq_model = modelGroup.filter(Boolean);\n        // eslint-disable-next-line no-restricted-syntax\n        for (const queryBuilder of route.queryBuilder) {\n          if (queryBuilder.queryMode === 'find') {\n            if (Object.prototype.hasOwnProperty.call(queryBuilder, 'select')) {\n              queryBuilder.select = (queryBuilder.select).join(' ');\n            }\n            if (Object.prototype.hasOwnProperty.call(queryBuilder, 'populate')) {\n              queryBuilder.populate = transformSelect(queryBuilder.populate);\n            }\n          }\n          if (!queryBuilder.outputVariable || queryBuilder.outputVariable === '') {\n            queryBuilder.outputVariable = `outputVar_${getRandomIntByMax(10000)}`;\n          }\n          queryBuilder.queryVarName = `query_${getRandomIntByMax(10000)}`;\n        }\n      }\n    }\n  }\n  return {\n    routes,\n    isQueryBuilderAvailable,\n  };\n};\nconst shouldCopyQueryService = (customRoutes) => {\n  customRoutes = removeQueryBuilderWithoutQueryMode(customRoutes, 'queryBuilder');\n  const transformedRoutes = transformControllerDetailsWithQueryBuilder(customRoutes);\n  return transformedRoutes.isQueryBuilderAvailable;\n};\nconst uniqRolesFromRolePermissions = (rolePermission) => {\n  let roles = [];\n  forEach(rolePermission, (platformObj) => {\n    forEach(platformObj, (modelObj) => {\n      forEach(modelObj, (methods) => {\n        roles = [...roles, ...methods];\n      });\n    });\n  });\n  return uniq(roles);\n};\n\nconst getRouteNameAndMethod = (method) => {\n  const routeWithMethod = {};\n  switch (method) {\n  case 'create':\n    routeWithMethod.path = 'create';\n    routeWithMethod.method = 'POST';\n    break;\n  case 'createBulk':\n    routeWithMethod.path = 'addBulk';\n    routeWithMethod.method = 'POST';\n    break;\n  case 'delete':\n    routeWithMethod.path = 'delete/:id';\n    routeWithMethod.method = 'DELETE';\n    break;\n  case 'deleteMany':\n    routeWithMethod.path = 'deleteMany';\n    routeWithMethod.method = 'DELETE';\n    break;\n  case 'softDelete':\n    routeWithMethod.path = 'softDelete/:id';\n    routeWithMethod.method = 'PUT';\n    break;\n  case 'softDeleteMany':\n    routeWithMethod.path = 'softDeleteMany';\n    routeWithMethod.method = 'PUT';\n    break;\n  case 'findAll':\n    routeWithMethod.path = 'list';\n    routeWithMethod.method = 'POST';\n    break;\n  case 'count':\n    routeWithMethod.path = 'count';\n    routeWithMethod.method = 'POST';\n    break;\n  case 'findById':\n    routeWithMethod.path = ':id';\n    routeWithMethod.method = 'GET';\n    break;\n  case 'update':\n    routeWithMethod.path = 'update/:id';\n    routeWithMethod.method = 'PUT';\n    break;\n  case 'partialUpdate':\n    routeWithMethod.path = 'partial-update/:id';\n    routeWithMethod.method = 'PUT';\n    break;\n  case 'bulkUpdate':\n    routeWithMethod.path = 'updateBulk';\n    routeWithMethod.method = 'PUT';\n    break;\n  default:\n    break;\n  }\n  return routeWithMethod;\n};\nconst getRouteRoleArray = (rolePermission) => {\n  const routeRoleArray = [];\n  forEach(rolePermission, (platformObj, platformName) => {\n    forEach(platformObj, (modelObj, modelName) => {\n      let route = '';\n      if (platformName !== 'admin') {\n        route = `/${platformName}/api/v1/${modelName}/`;\n      } else {\n        route = `/${platformName}/${modelName}/`;\n      }\n      forEach(modelObj, (roleArray, methodName) => {\n        const pathAndMethod = getRouteNameAndMethod(methodName);\n        if (!isEmpty(pathAndMethod)) {\n          let routeWithMethod = `${route}${pathAndMethod.path}`;\n          forEach(roleArray, (role) => {\n            const routeRoleObj = { route: routeWithMethod.toLowerCase() };\n            routeRoleObj.role = role;\n            routeRoleObj.method = pathAndMethod.method;\n            routeRoleArray.push(routeRoleObj);\n          });\n          routeWithMethod = '';\n        }\n      });\n    });\n  });\n  return routeRoleArray;\n};\n\nconst removeGivenKeyFromObject = (obj, keysToRemove) => {\n  forEach(keysToRemove, (key) => {\n    if (has(obj, key)) {\n      delete obj[key];\n    }\n  });\n  return obj;\n};\n\nconst createReadMeFile = (readmeObj) => {\n  const readMeEjs = writeOperations.loadTemplate(`${readmeObj.templateFolderName}/README`);\n  // eslint-disable-next-line prefer-destructuring\n  readMeEjs.locals.IS_AUTH = readmeObj.auth.isAuth;\n  if (readmeObj.auth.isAuth && !isEmpty(readmeObj.credentials)) {\n    readMeEjs.locals.ROLE_WISE_CREDENTIALS = readmeObj.credentials;\n    readMeEjs.locals.CREDENTIALS = readmeObj.credentials;\n    readMeEjs.locals.USER_FIELD = readmeObj.auth.userLoginWith.username ? readmeObj.auth.userLoginWith.username[0] : readmeObj.auth.emailField;\n    readMeEjs.locals.PASSWORD_FIELD = readmeObj.auth.userLoginWith.password;\n    readMeEjs.locals.USERNAME = readmeObj.auth.userLoginWith.username[0] ? readmeObj.credentials[readmeObj.auth.userLoginWith.username[0]] : readmeObj.auth.emailField;\n    readMeEjs.locals.PASSWORD = readmeObj.credentials[readmeObj.auth.userLoginWith.password];\n  }\n  return readMeEjs;\n};\n\nconst createRelativePathFromAbsolutePath = (currentFilePath, absolutePath) => {\n  let relativePath = '';\n  let currentFilePathAsArray = currentFilePath.split('/');\n  let absolutePathAsArray = absolutePath.split('/');\n\n  currentFilePathAsArray = currentFilePathAsArray.filter((item) => item);\n  absolutePathAsArray = absolutePathAsArray.filter((item) => item);\n\n  const currentPathLength = currentFilePathAsArray.length;\n  const absolutePathLength = absolutePathAsArray.length;\n\n  if (currentPathLength <= absolutePathLength) {\n    let i = 0;\n    while (i <= absolutePathLength) {\n      if (absolutePathAsArray[i] !== currentFilePathAsArray[i]) {\n        break;\n      }\n      i += 1;\n    }\n\n    if (currentFilePathAsArray[i] === last(currentFilePathAsArray)) {\n      const rel = './';\n      const remain = absolutePathAsArray.slice(i, absolutePathAsArray.length);\n      relativePath = rel + remain.join('/');\n    } else {\n      const cRemainLen = currentFilePathAsArray.slice(i, currentFilePathAsArray.length).length;\n      let rel = '';\n      for (let j = 1; j < cRemainLen; j += 1) {\n        rel += '../';\n      }\n      const remain = absolutePathAsArray.slice(i, absolutePathAsArray.length);\n      relativePath = rel + remain.join('/');\n    }\n  } else if (currentPathLength > absolutePathLength) {\n    let i = 0;\n    while (i <= currentPathLength) {\n      if (absolutePathAsArray[i] !== currentFilePathAsArray[i]) {\n        break;\n      }\n      i += 1;\n    }\n    const remain = currentFilePathAsArray.slice(i, currentFilePathAsArray.length);\n    if (remain.length > 1) {\n      let rel = '';\n      for (let j = 1; j < remain.length; j += 1) {\n        rel += '../';\n      }\n      const aRemain = absolutePathAsArray.slice(i, absolutePathAsArray.length);\n      relativePath = rel + aRemain.join('/');\n    }\n  }\n  return relativePath;\n};\n\nconst getRelativePaths = (fileNames, filePath, pathToBeIncludedInFilePath, destinationDirectory) => {\n  const fullPath = `${destinationDirectory}${filePath}`;\n  const relativePaths = {};\n  forEach(fileNames, (fileName) => {\n    const fileFullPath = `${fullPath}${fileName}`;\n    const destinationPath = `${destinationDirectory}${pathToBeIncludedInFilePath}`;\n    /*\n     * console.log(fileFullPath);\n     * console.log(destinationPath);\n     * console.log(`relative path -> ${createRelativePathFromAbsolutePath(destinationPath, fileFullPath)}`);\n     */\n    const path = createRelativePathFromAbsolutePath(destinationPath, fileFullPath);\n    Object.assign(relativePaths, { [fileName]: path });\n  });\n  return relativePaths;\n};\n\nmodule.exports = {\n  identifyPlatform,\n  identifyPlatformNew,\n  getFilterLoggedUser,\n  getRandomIntByMax,\n  getTemplateByName,\n  getUniqModelsFromTasks,\n  removeQueryBuilderWithoutQueryMode,\n  transformSelect,\n  doesArrayContainSearchArray,\n  getImportPath,\n  getPlatformWiseAPIOfCustomRoutes,\n  getPolicyForCustomRoutes,\n  transformControllerDetailsWithQueryBuilder,\n  shouldCopyQueryService,\n  uniqRolesFromRolePermissions,\n  getRouteRoleArray,\n  removeGivenKeyFromObject,\n  createReadMeFile,\n  createRelativePathFromAbsolutePath,\n  getRelativePaths,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/generator.js",
    "content": "/* eslint-disable no-console */\n/* global _ */\nconst fs = require('fs');\nconst {\n  PROJECT_TYPE, DB_ADAPTER,\n} = require('./constants/constant');\n\nglobal.__basedir = __dirname;\nconst CodeGenerator = require('./codeGenerator');\n\nfunction trimModelNameFromInput (models) {\n  const oldModelNames = _.keys(models);\n  let newModelNames = [];\n  _.forEach(models, (model, modelName) => {\n    newModelNames.push(_.trim(modelName));\n  });\n  newModelNames = _.uniq(newModelNames);\n  if (_.isEqual(oldModelNames, newModelNames)) { return models; }\n  throw new Error('modelName should not contain spaces');\n}\n\nasync function main (inputFilepath, isReBuild) {\n  let projectPath;\n  try {\n    const inputData = fs.readFileSync(inputFilepath, { encoding: 'utf8' });\n    const jsonData = JSON.parse(inputData);\n    const {\n      config, id,\n    } = jsonData;\n    jsonData.models = trimModelNameFromInput(jsonData.models);\n    projectPath = `${config.path}/${id}`;\n    if (jsonData.adapter && jsonData.ORM) {\n      if (jsonData.ORM !== 'mongoose') {\n        jsonData.projectType = `${jsonData.projectType}_${(jsonData.ORM).toUpperCase()}`;\n      }\n    }\n    const codeGenerator = new CodeGenerator(jsonData.projectType || PROJECT_TYPE.MVC, jsonData.adapter || DB_ADAPTER.MONGODB);\n    console.time();\n    await codeGenerator.createApp({\n      directory: projectPath,\n      projectName: config.projectName,\n      jsonData,\n      isReBuild,\n    });\n  } catch (err) {\n    console.log(err);\n    throw new Error(err);\n  }\n}\n\nmodule.exports = main;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/settings/index.js",
    "content": "const {\n  PROJECT_TYPE, PROJECT_CREATION_STEP, DB_ADAPTER,\n} = require('../constants/constant');\n\nfunction getProjectSteps (type) {\n  if (type === PROJECT_TYPE.MVC) {\n    return [\n      PROJECT_CREATION_STEP.INPUT_PARSER,\n      PROJECT_CREATION_STEP.CREATE_ROOT_DIRECTORY,\n      PROJECT_CREATION_STEP.SCHEMA_VALIDATION,\n      PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_MVC,\n      PROJECT_CREATION_STEP.CREATE_MODELS,\n      PROJECT_CREATION_STEP.CREATE_ROUTES,\n      PROJECT_CREATION_STEP.MODEL_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_CONSTANT,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE,\n      PROJECT_CREATION_STEP.CREATE_DB_CONNECTION,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLERS,\n      PROJECT_CREATION_STEP.IDENTIFY_AUTH,\n      PROJECT_CREATION_STEP.SETUP_ENV_FILE,\n      PROJECT_CREATION_STEP.CREATE_VALIDATION_FILE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_POLICY,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_POSTMAN,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_FILES,\n      PROJECT_CREATION_STEP.ADD_SOCIAL_LOGIN,\n      PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_MVC,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENCY_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_SERVICE,\n      PROJECT_CREATION_STEP.ADD_ROLE_PERMISSION,\n      PROJECT_CREATION_STEP.ADD_SEEDER_MONGOOSE,\n      PROJECT_CREATION_STEP.GENERATE_TEST_CASES,\n      PROJECT_CREATION_STEP.RENDER_EJS, // must be last step\n      PROJECT_CREATION_STEP.APPLY_ESLINT,\n      PROJECT_CREATION_STEP.CREATE_APP_FILE,\n    ];\n  }\n  if (type === PROJECT_TYPE.CLEAN_CODE) {\n    return [\n      PROJECT_CREATION_STEP.INPUT_PARSER,\n      PROJECT_CREATION_STEP.CREATE_ROOT_DIRECTORY,\n      PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_CC,\n      PROJECT_CREATION_STEP.SCHEMA_VALIDATION,\n      PROJECT_CREATION_STEP.CREATE_MODELS,\n      PROJECT_CREATION_STEP.CREATE_ENTITY,\n      PROJECT_CREATION_STEP.IDENTIFY_AUTH,\n      PROJECT_CREATION_STEP.CREATE_CONSTANT,\n      PROJECT_CREATION_STEP.SETUP_ENV_FILE,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE,\n      PROJECT_CREATION_STEP.CREATE_DB_CONNECTION,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLERS,\n      PROJECT_CREATION_STEP.CREATE_AUTH_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_ROUTES,\n      PROJECT_CREATION_STEP.MODEL_SERVICE,\n      PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_CC,\n      PROJECT_CREATION_STEP.CREATE_POSTMAN,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_FILES,\n      PROJECT_CREATION_STEP.CREATE_FIE_UPLOAD_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_USECASE,\n      PROJECT_CREATION_STEP.ADD_SOCIAL_LOGIN,\n      PROJECT_CREATION_STEP.CREATE_VALIDATION_FILE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_POLICY,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_INDEX_FILES_OF_CONTROLLER_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENCY_SERVICE,\n      PROJECT_CREATION_STEP.ADD_ROLE_PERMISSION,\n      PROJECT_CREATION_STEP.ADD_SEEDER_MONGOOSE,\n      PROJECT_CREATION_STEP.GENERATE_TEST_CASES,\n      PROJECT_CREATION_STEP.RENDER_EJS, // must be the last step\n      PROJECT_CREATION_STEP.APPLY_ESLINT,\n      PROJECT_CREATION_STEP.CREATE_APP_FILE,\n      PROJECT_CREATION_STEP.CREATE_DATA_ACCESS_FILES,\n      PROJECT_CREATION_STEP.CREATE_USECASE_FILES,\n      PROJECT_CREATION_STEP.CREATE_COMMON_USE_CASE_FILES,\n      PROJECT_CREATION_STEP.CREATE_MIDDLEWARE_INDEX,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_USECASE,\n\n    ];\n  }\n  if (type === PROJECT_TYPE.MVC_SEQUELIZE) {\n    return [\n      PROJECT_CREATION_STEP.INPUT_PARSER_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_ROOT_DIRECTORY,\n      PROJECT_CREATION_STEP.SEQUELIZE_SCHEMA_VALIDATION,\n      PROJECT_CREATION_STEP.SEQUELIZE_TYPE_CONVERSION,\n      PROJECT_CREATION_STEP.SEQUELIZE_TYPE_VALIDATION,\n      PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_MVC,\n      PROJECT_CREATION_STEP.CONVERT_HOOK_NAMES,\n      PROJECT_CREATION_STEP.CREATE_SEQUELIZE_MODELS,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLERS,\n      PROJECT_CREATION_STEP.CREATE_ROUTES,\n      PROJECT_CREATION_STEP.MODEL_SERVICE,\n      PROJECT_CREATION_STEP.SEQUELIZE_DB_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_CONSTANT,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_DB_CONNECTION_SEQUELIZE,\n      PROJECT_CREATION_STEP.IDENTIFY_AUTH,\n      PROJECT_CREATION_STEP.SETUP_ENV_FILE_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_SEQUELIZE_VALIDATION_FILE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_POLICY,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_POSTMAN_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_FILES,\n      PROJECT_CREATION_STEP.ADD_SOCIAL_LOGIN,\n      PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_MVC_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENCY_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_SERVICE,\n      PROJECT_CREATION_STEP.QUERY_BUILDER_PARSE_SEQUELIZE,\n      PROJECT_CREATION_STEP.ADD_ROLE_PERMISSION,\n      PROJECT_CREATION_STEP.ADD_SEEDER_SEQUELIZE,\n      PROJECT_CREATION_STEP.GENERATE_TEST_CASES_SEQUELIZE,\n      PROJECT_CREATION_STEP.RENDER_EJS, // must be last step\n      PROJECT_CREATION_STEP.APPLY_ESLINT,\n      PROJECT_CREATION_STEP.CREATE_APP_FILE,\n    ];\n  }\n  if (type === PROJECT_TYPE.CC_SEQUELIZE) {\n    return [\n      PROJECT_CREATION_STEP.INPUT_PARSER_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_ROOT_DIRECTORY,\n      PROJECT_CREATION_STEP.CREATE_BLANK_DIRECTORY_CC,\n      PROJECT_CREATION_STEP.SEQUELIZE_SCHEMA_VALIDATION,\n      PROJECT_CREATION_STEP.SEQUELIZE_TYPE_CONVERSION,\n      PROJECT_CREATION_STEP.SEQUELIZE_TYPE_VALIDATION,\n      PROJECT_CREATION_STEP.CONVERT_HOOK_NAMES,\n      PROJECT_CREATION_STEP.CREATE_SEQUELIZE_MODELS,\n      PROJECT_CREATION_STEP.CREATE_ENTITY,\n      PROJECT_CREATION_STEP.IDENTIFY_AUTH,\n      PROJECT_CREATION_STEP.CREATE_CONSTANT,\n      PROJECT_CREATION_STEP.SETUP_ENV_FILE_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENT_FILE_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_DB_CONNECTION_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_CONTROLLERS,\n      PROJECT_CREATION_STEP.CREATE_AUTH_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_ROUTES,\n      PROJECT_CREATION_STEP.MODEL_SERVICE,\n      PROJECT_CREATION_STEP.GENERATE_STATIC_FILES_CC_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_POSTMAN_SEQUELIZE,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_FILES,\n      PROJECT_CREATION_STEP.CREATE_FIE_UPLOAD_CONTROLLER_INDEX,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_FILE_UPLOAD_USECASE,\n      PROJECT_CREATION_STEP.ADD_SOCIAL_LOGIN,\n      PROJECT_CREATION_STEP.CREATE_SEQUELIZE_VALIDATION_FILE,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_POLICY,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_INDEX_FILES_OF_CONTROLLER_CUSTOM_ROUTES,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_SERVICE,\n      PROJECT_CREATION_STEP.CREATE_DEPENDENCY_SERVICE,\n      PROJECT_CREATION_STEP.ADD_ROLE_PERMISSION,\n      PROJECT_CREATION_STEP.ADD_SEEDER_SEQUELIZE,\n      PROJECT_CREATION_STEP.GENERATE_TEST_CASES_SEQUELIZE,\n      PROJECT_CREATION_STEP.EXTERNAL_EMAIL_SERVICE_PROVIDER,\n      PROJECT_CREATION_STEP.RENDER_EJS, // must be the last step\n      PROJECT_CREATION_STEP.APPLY_ESLINT,\n      PROJECT_CREATION_STEP.CREATE_APP_FILE,\n      PROJECT_CREATION_STEP.CREATE_DATA_ACCESS_FILES,\n      PROJECT_CREATION_STEP.CREATE_USECASE_FILES,\n      PROJECT_CREATION_STEP.CREATE_COMMON_USE_CASE_FILES,\n      PROJECT_CREATION_STEP.CREATE_MIDDLEWARE_INDEX,\n      PROJECT_CREATION_STEP.CREATE_CUSTOM_ROUTES_USECASE,\n    ];\n  }\n  return [];\n}\n\nmodule.exports = {\n  setup: (projectType, databaseAdapter) => {\n    let modelPathAccordingORM = '/model';\n    let dbConnectionFilePathAccordingORM = '/config/db.js';\n    let dbServiceFilePathAccordingORM = '/service/dbService.js';\n\n    if (projectType === PROJECT_TYPE.CLEAN_CODE && (databaseAdapter === DB_ADAPTER.MONGODB)) {\n      modelPathAccordingORM = '/db/mongoDB/models';\n      dbConnectionFilePathAccordingORM = '/db/mongoDB/connection.js';\n      dbServiceFilePathAccordingORM = '/db/mongoDB/dbService.js';\n    } else if (projectType === PROJECT_TYPE.CC_SEQUELIZE && ([DB_ADAPTER.POSTGRESQL, DB_ADAPTER.MYSQL, DB_ADAPTER.MSSQL].includes(databaseAdapter))) {\n      modelPathAccordingORM = '/db/sequelize/models';\n      dbConnectionFilePathAccordingORM = '/db/sequelize/connection.js';\n      dbServiceFilePathAccordingORM = '/db/sequelize/dbService.js';\n    }\n\n    let settingJson = {};\n\n    settingJson = {\n      // ? MVC Settings.\n      [PROJECT_TYPE.MVC]: {\n        templateFolderName: 'mvc',\n        templateRegistry: {\n          modelFolderPath: '/models',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controllers',\n          routesFolderPath: '/routes',\n          serviceFolderPath: '/services',\n          individualRoutesFolderPath: '/individualRoutes',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/utils/validation',\n          viewsFolderPath: '/views',\n          middlewareFolderPath: '/middleware',\n          // From Here\n          testCaseTemplatePath: '/__test__',\n          smsServiceTemplateName: '/services/smsService.js',\n          emailServiceTemplateName: '/services/emailService.js',\n          pushNotificationPath: '/services/pushNotification',\n          seedersPath: '/seeders',\n        },\n        userDirectoryStructure: {\n          modelFolderPath: '/model',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controller',\n          routesFolderPath: '/routes',\n          serviceFolderPath: '/services',\n          constantFolderPath: '/constants',\n          mainJSFilePath: '/app.js',\n          publicFolderPath: 'public',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/utils/validation',\n          viewsFolderPath: '/views',\n          middlewareFolderPath: '/middleware',\n          generatedControllerPath: '/controller/{{ platform }}/{{ model }}Controller.js',\n          authControllerPath: '/controller/{{ platform }}',\n          fileUploadControllerPath: '/controller/{{ platform }}',\n          adminFileUploadControllerPath: 'controller/{{ platform }}',\n          generatedCustomRouteControllerPath: 'controller/{{ platform }}/{{ controller }}Controller.js',\n          dbConnectionFolderPath: '/config/db.js',\n          generatedTestCasePath: '/__test__/{{ platform }}/{{ model }}.test.js',\n          testCasePath: '/__test__',\n          seedersPath: '/seeders',\n          envFilePath: '.env',\n        },\n        steps: getProjectSteps(projectType),\n      },\n      // ? Clean Code Settings.\n      [PROJECT_TYPE.CLEAN_CODE]: {\n        templateFolderName: 'cleanCode',\n        templateRegistry: {\n          entityFolderPath: '/entity',\n          modelFolderPath: '/models',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controllers',\n          routesFolderPath: '/routes',\n          middlewareFolderPath: '/middleware',\n          viewsFolderPath: '/views',\n          serviceFolderPath: '/services',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/validation',\n          individualRoutesFolderPath: '/individualRoutes',\n          testCaseTemplatePath: '/__test__',\n          smsServiceTemplateName: '/services/smsService.js',\n          emailServiceTemplateName: '/services/emailService.js',\n          pushNotificationPath: '/services/pushNotification',\n          seedersPath: '/seeders',\n          dataAccessFolderPath: '/data-access',\n          useCaseFolderPath: '/use-case',\n          useCaseFilePath: '/use-case/{{ model }}/{{ fileName }}.js',\n        },\n        userDirectoryStructure: {\n          mainJSFilePath: '/app.js',\n          entityFolderPath: '/entities',\n          modelFolderPath: modelPathAccordingORM,\n          configFolderPath: '/config',\n          controllerFolderPath: '/controller',\n          routesFolderPath: '/routes',\n          middlewareFolderPath: '/middleware',\n          viewsFolderPath: '/views',\n          serviceFolderPath: '/services',\n          publicFolderPath: '/public',\n          helperFolderPath: '/helpers',\n          constantFolderPath: '/constants',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/validation',\n          generatedCustomRouteControllerPath: 'controller/{{ platform }}/{{ controller }}/{{ controller }}.js',\n          generatedIndexForNewPlatformPath: '/{{ platform }}/',\n          generatedControllerPath: '/controller/{{ platform }}/{{ model }}/{{ model }}.js',\n          authControllerPath: '/controller/{{ platform }}/authentication',\n          fileUploadControllerPath: '/controller/{{ platform }}/fileUpload',\n          adminFileUploadControllerPath: 'controller/{{ platform }}',\n          dbConnectionFolderPath: dbConnectionFilePathAccordingORM,\n          generatedTestCasePath: '/__test__/{{ platform }}/{{ model }}.test.js',\n          testCasePath: '/__test__',\n          seedersPath: '/seeders',\n          envFilePath: '.env',\n          dataAccessFolderPath: '/data-access',\n          dbServiceFilePath: dbServiceFilePathAccordingORM,\n          useCaseFolderPath: '/use-case',\n          useCaseFilePath: '/use-case/{{ model }}/{{ fileName }}.js',\n        },\n        steps: getProjectSteps(projectType),\n      },\n      // ? MVC Sequelize Settings.\n      [PROJECT_TYPE.MVC_SEQUELIZE]: {\n        templateFolderName: 'mvcSequelize',\n        templateRegistry: {\n          modelFolderPath: '/models',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controllers',\n          routesFolderPath: '/routes',\n          serviceFolderPath: '/services',\n          individualRoutesFolderPath: '/individualRoutes',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/utils/validation',\n          viewsFolderPath: '/views',\n          middlewareFolderPath: '/middleware',\n          testCaseTemplatePath: '/__test__',\n          smsServiceTemplateName: '/services/smsService.js',\n          emailServiceTemplateName: '/services/emailService.js',\n          pushNotificationPath: '/services/pushNotification',\n          seedersPath: '/seeders',\n        },\n        userDirectoryStructure: {\n          mainJSFilePath: '/app.js',\n          modelFolderPath: '/model',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controller',\n          routesFolderPath: '/routes',\n          serviceFolderPath: '/services',\n          constantFolderPath: '/constants',\n          individualRoutesFolderPath: '/individualRoutes',\n          utilsFolderPath: '/utils',\n          publicFolderPath: '/public',\n          validationFolderPath: '/utils/validation',\n          viewsFolderPath: '/views',\n          middlewareFolderPath: '/middleware',\n          generatedControllerPath: '/controller/{{ platform }}/{{ model }}Controller.js',\n          authControllerPath: '/controller/{{ platform }}',\n          fileUploadControllerPath: '/controller/{{ platform }}',\n          adminFileUploadControllerPath: 'controller/{{ platform }}',\n          generatedCustomRouteControllerPath: 'controller/{{ platform }}/{{ controller }}Controller.js',\n          dbConnectionFolderPath: '/config/db.js',\n          generatedTestCasePath: '/__test__/{{ platform }}/{{ model }}.test.js',\n          testCasePath: '/__test__',\n          seedersPath: '/seeders',\n          envFilePath: '.env',\n        },\n        steps: getProjectSteps(projectType),\n      },\n\n      [PROJECT_TYPE.CC_SEQUELIZE]: {\n        templateFolderName: 'cleanCodeSequelize',\n        templateRegistry: {\n          entityFolderPath: '/entity',\n          modelFolderPath: '/models',\n          configFolderPath: '/config',\n          controllerFolderPath: '/controllers',\n          routesFolderPath: '/routes',\n          middlewareFolderPath: '/middleware',\n          viewsFolderPath: '/views',\n          serviceFolderPath: '/services',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/validation',\n          individualRoutesFolderPath: '/individualRoutes',\n          testCaseTemplatePath: '/__test__',\n          smsServiceTemplateName: '/services/smsService.js',\n          emailServiceTemplateName: '/services/emailService.js',\n          pushNotificationPath: '/services/pushNotification',\n          seedersPath: '/seeders',\n          dataAccessFolderPath: '/data-access',\n          useCaseFolderPath: '/use-case',\n          useCaseFilePath: '/use-case/{{ model }}/{{ fileName }}.js',\n        },\n        userDirectoryStructure: {\n          mainJSFilePath: '/app.js',\n          entityFolderPath: '/entities',\n          modelFolderPath: modelPathAccordingORM,\n          configFolderPath: '/config',\n          controllerFolderPath: '/controller',\n          routesFolderPath: '/routes',\n          middlewareFolderPath: '/middleware',\n          viewsFolderPath: '/views',\n          serviceFolderPath: '/services',\n          publicFolderPath: '/public',\n          helperFolderPath: '/helpers',\n          constantFolderPath: '/constants',\n          utilsFolderPath: '/utils',\n          validationFolderPath: '/validation',\n          generatedCustomRouteControllerPath: 'controller/{{ platform }}/{{ controller }}/{{ controller }}.js',\n          generatedIndexForNewPlatformPath: '/{{ platform }}/',\n          generatedControllerPath: '/controller/{{ platform }}/{{ model }}/{{ model }}.js',\n          authControllerPath: '/controller/{{ platform }}/authentication',\n          fileUploadControllerPath: '/controller/{{ platform }}/fileUpload',\n          adminFileUploadControllerPath: '/controller/{{ platform }}',\n          dbConnectionFolderPath: dbConnectionFilePathAccordingORM,\n          generatedTestCasePath: '/__test__/{{ platform }}/{{ model }}.test.js',\n          testCasePath: '/__test__',\n          seedersPath: '/seeders',\n          envFilePath: '.env',\n          dataAccessFolderPath: '/data-access',\n          dbServiceFilePath: dbServiceFilePathAccordingORM,\n          useCaseFolderPath: '/use-case',\n          useCaseFilePath: '/use-case/{{ model }}/{{ fileName }}.js',\n        },\n        steps: getProjectSteps(projectType),\n      },\n    };\n\n    return settingJson;\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/app.js",
    "content": "/* eslint-disable global-require */\nconst fs = require('fs');\nconst ejs = require('ejs');\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\n\nfunction loadTemplate (name) {\n  const util = require('util');\n  const contents = fs.readFileSync(path.join(__dirname, 'templates', (`${name}.ejs`)), 'utf-8');\n  const locals = Object.create(null);\n  function render () {\n    return ejs.render(contents, locals, { escape: util.inspect });\n  }\n  return {\n    locals,\n    render,\n  };\n}\nfunction generateSocialLoginForMVC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service.js');\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.MODEL = jsonData.model;\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/facebook-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/facebook-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/facebook/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/facebook/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/facebook-login-routes.js`, route.render());\n  } catch (error) {\n    throw new Error(error.message);\n  }\n}\n\nfunction generateSocialLoginForCC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc.js');\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.MODEL = jsonData.model;\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/facebook-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/facebook-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/facebook/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/facebook/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/facebook-login-routes.js`, route.render());\n  } catch (error) {\n    throw new Error(error.message);\n  }\n}\n\nfunction generateSocialLoginForCCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc-sequelize.js');\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.MODEL = jsonData.model;\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/facebook-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/facebook-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/facebook/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/facebook/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/facebook-login-routes.js`, route.render());\n  } catch (error) {\n    throw new Error(error.message);\n  }\n}\n\nfunction generateSocialLoginForMVCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-sequelize.js');\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.MODEL = jsonData.model;\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/facebook-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/facebook-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/facebook/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/facebook/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/facebook-login-routes.js`, route.render());\n  } catch (error) {\n    throw new Error(error.message);\n  }\n}\n\nfunction main (jsonData) {\n  try {\n    const { projectType } = jsonData;\n    switch (projectType) {\n    case 'mvc':\n      generateSocialLoginForMVC(jsonData);\n      break;\n    case 'clean-code':\n      generateSocialLoginForCC(jsonData);\n      break;\n    case 'mvc_sequelize':\n      generateSocialLoginForMVCSequelize(jsonData);\n      break;\n    case 'cc_sequelize':\n      generateSocialLoginForCCSequelize(jsonData);\n      break;\n    default:\n      // console.log('Invalid Project Type');\n      break;\n    }\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nmodule.exports = main;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/routes/facebook-login-routes-cc.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst { facebookStrategy,loginUser } = require('../services/facebook-login-service');\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\n\n//facebook\nfacebookStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n    secret: 'my-secret',\n    resave:true,\n    saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n    cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n    cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n    let result = response.badRequest({message:'Login Failed'});\n    responseHandler(res,result);\n})\n\nrouter.get(\"/auth/facebook\",passport.authenticate('facebook', {scope: ['profile'],session:false}));\n\nrouter.get(\"<%-CALLBACK_URL%>\",\n    passport.authenticate('facebook', {\n        failureRedirect: '<%-ERROR_URL%>'\n    }),\n    function(req,res){\n        loginUser(req.user.email,req.session.platform).then(user=>{\n            if(user.flag){\n                let result = response.success({message:'Login Successful',data:user.data});\n                responseHandler(res,result);\n            }\n            else{\n                let result = response.badRequest({message:user.data});\n                responseHandler(res,result);\n            }\n        })\n        .catch(error=>{\n            let result = response.internalServerError();\n            responseHandler(res,result);\n        })\n    }\n);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/routes/facebook-login-routes.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  facebookStrategy,loginUser \n} = require('../services/facebook-login-service');\n\n//facebook\nfacebookStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave:true,\n  saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  return res.badRequest();\n});\n\nrouter.get('/auth/facebook', passport.authenticate('facebook', { scope: ['profile'] }));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('facebook', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req,res){\n    loginUser(req.user.email,req.session.platform).then(result=>{\n      if (result.flag){\n        return res.badRequest({message:result.data});\n      }\n      return res.success({data:result.data});\n    })\n      .catch(error=>{\n        return res.internalServerError();\n      });\n  }\n);\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/service-cc-sequelize.js.ejs",
    "content": "const FacebookStrategy = require('passport-facebook').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  facebookStrategy: passport => {\n    passport.use(new FacebookStrategy({\n      clientID: process.env.FACEBOOK_CLIENTID,\n      clientSecret: process.env.FACEBOOK_CLIENTSECRET,\n      callbackURL: process.env.FACEBOOK_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'facebookId': profile.id,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj);\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"facebookId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:{ tokenExpiredTime: { $gt: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn}\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/service-cc.js.ejs",
    "content": "const FacebookStrategy = require('passport-facebook').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\");\nconst userTokensDb = require(\"../data-access/userTokensDb\");\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  facebookStrategy: passport => {\n    passport.use(new FacebookStrategy({\n      clientID: process.env.FACEBOOK_CLIENTID,\n      clientSecret: process.env.FACEBOOK_CLIENTSECRET,\n      callbackURL: process.env.FACEBOOK_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'facebookId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj)\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"sso_auth.facebookId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({ userId: user.id, token: token,tokenExpiredTime: expire });                              \n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/service-sequelize.js.ejs",
    "content": "const FacebookStrategy = require('passport-facebook').Strategy;\nconst jwt = require(\"jsonwebtoken\");\n<%_if(RESTRICTION){_%>\nconst {Op} = require('sequelize');\n<%_}_%>\nconst dayjs = require('dayjs');\n\nconst model = require(\"../model/index\")\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  facebookStrategy: passport => {\n    passport.use(new FacebookStrategy({\n      clientID: process.env.FACEBOOK_CLIENTID,\n      clientSecret: process.env.FACEBOOK_CLIENTSECRET,\n      callbackURL: process.env.FACEBOOK_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'facebookId': profile.id ,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.findOne(model.<%-MODEL%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateByPk(model.<%-MODEL%>, id, userObj);\n        }\n        else {\n          await dbService.createOne(model.<%-MODEL%>, userObj)\n        }\n        let user = await dbService.findOne(model.<%-MODEL%>,{ \"facebookId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.findOne(model.<%-MODEL%>,{email});\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.count(model.userTokens,{ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createOne(model.userTokens,{\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/facebook/templates/js/service.js.ejs",
    "content": "const FacebookStrategy = require('passport-facebook').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL_FC%> = require('../model/<%-MODEL%>'); \nconst dbService = require('../utils/dbService');\nconst userTokens = require(\"../model/userTokens\");\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  facebookStrategy: passport => {\n    passport.use(new FacebookStrategy({\n      clientID: process.env.FACEBOOK_CLIENTID,\n      clientSecret: process.env.FACEBOOK_CLIENTSECRET,\n      callbackURL: process.env.FACEBOOK_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'facebookId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateDocument(<%-MODEL_FC%>, id, userObj);\n        }\n        else {\n          await dbService.createDocument(<%-MODEL_FC%>, userObj)\n        }\n        let user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"sso_auth.facebookId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{email});\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.countDocument(userTokens, { $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createDocument(userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/app.js",
    "content": "/* eslint-disable global-require */\nconst fs = require('fs');\nconst ejs = require('ejs');\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\n\nfunction loadTemplate (name) {\n  const util = require('util');\n  const contents = fs.readFileSync(path.join(__dirname, 'templates', (`${name}.ejs`)), 'utf-8');\n  const locals = Object.create(null);\n  function render () {\n    return ejs.render(contents, locals, { escape: util.inspect });\n  }\n  return {\n    locals,\n    render,\n  };\n}\nfunction generateSocialLoginForMVC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/github-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/github-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/github/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/github/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/github-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nfunction generateSocialLoginForCC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/github-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/github-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/github/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/github/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/github-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nfunction generateSocialLoginForMVCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-sequelize.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/github-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/github-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/github/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/github/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/github-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nfunction generateSocialLoginForCCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc-sequelize.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/github-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/github-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/github/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/github/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/github-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nasync function main (jsonData) {\n  try {\n    const { projectType } = jsonData;\n    switch (projectType) {\n    case 'mvc':\n      generateSocialLoginForMVC(jsonData);\n      break;\n    case 'clean-code':\n      generateSocialLoginForCC(jsonData);\n      break;\n    case 'mvc_sequelize':\n      generateSocialLoginForMVCSequelize(jsonData);\n      break;\n    case 'cc_sequelize':\n      generateSocialLoginForCCSequelize(jsonData);\n      break;\n    default:\n      // console.log('Invalid Project Type');\n      break;\n    }\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nmodule.exports = main;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/routes/github-login-routes-cc.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  githubStrategy, loginUser \n} = require('../services/github-login-service');\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\n\n//github\ngithubStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave:true,\n  saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  let result = response.badRequest({message:'Login Failed'});\n  sendResponse(res,result);\n});\n\nrouter.get('/auth/github',passport.authenticate('github', { \n  scope: ['profile', 'email'],\n  session:false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('github', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req,res){\n    loginUser(req.user.email,req.session.platform).then(user=>{\n      if (!user.flag){\n        let result = response.success({message:'Login Successful',data:user.data});\n        sendResponse(res,result);\n      }\n      else {\n        let result = response.badRequest({message:user.data});\n        sendResponse(res,result);\n      }\n            \n    })\n      .catch(error=>{\n        let result = response.internalServerError();\n        sendResponse(res,result);\n      });\n  }\n);\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/routes/github-login-routes.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\nconst session = require('express-session');\nconst passport = require('passport');\n\nconst {\n  githubStrategy, loginUser \n} = require('../services/github-login-service');\n\n//github\ngithubStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave: true,\n  saveUninitialized: false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  return res.badRequest();\n});\n\nrouter.get('/auth/github', passport.authenticate('github', {\n  scope: ['public_profile', 'email'],\n  session: false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('github', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req, res) {\n    loginUser(req.user.email,req.session.platform).then(result=>{\n      if (result.flag){\n        return res.badRequest({message:result.data});\n      }\n      return res.success({data:result.data});\n    })\n      .catch(error=>{\n        return res.internalServerError();\n      });\n  });\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/service-cc-sequelize.js.ejs",
    "content": "const GithubStrategy = require('passport-github2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\n<%_if(RESTRICTION){_%>\nconst {Op} = require('sequelize');\n<%_}_%>\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n    githubStrategy: passport => {\n    passport.use(new GithubStrategy({\n      clientID: process.env.GITHUB_CLIENTID,\n      clientSecret: process.env.GITHUB_CLIENTSECRET,\n      callbackURL: process.env.GITHUB_CALLBACKURL,\n      scope: ['public_profile', 'email']\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n           'githubId': profile.id,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj);\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"githubId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokenService.count({ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokenService.create({\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn}\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/service-cc.js.ejs",
    "content": "require('dotenv').config();\nconst GithubStrategy = require('passport-github2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n    githubStrategy: passport => {\n    passport.use(new GithubStrategy({\n      clientID: process.env.GITHUB_CLIENTID,\n      clientSecret: process.env.GITHUB_CLIENTSECRET,\n      callbackURL: process.env.GITHUB_CALLBACKURL,\n      scope: ['public_profile', 'email']\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'githubId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj)\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"sso_auth.githubId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({ email });\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please Login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokenService.create({ userId: user.id, token: token,tokenExpiredTime: expire });                              \n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true,data:'Email not exists'}\n      }\n    } catch (e) {\n      console.log(e);\n      throw new Error(e);\n    }\n\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/service-sequelize.js.ejs",
    "content": "const GithubStrategy = require('passport-github2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\n<%_if(RESTRICTION){_%>\nconst {Op} = require('sequelize');\n<%_}_%>\nconst dayjs = require('dayjs');\n\nconst model = require(\"../model/index\")\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  githubStrategy: passport => {\n    passport.use(new GithubStrategy({\n      clientID: process.env.GITHUB_CLIENTID,\n      clientSecret: process.env.GITHUB_CLIENTSECRET,\n      callbackURL: process.env.GITHUB_CALLBACKURL,\n      scope: ['public_profile', 'email']\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.username, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'githubId': profile.id ,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.findOne(model.<%-MODEL%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateByPk(model.<%-MODEL%>, id, userObj);\n        }\n        else {\n          await dbService.createOne(model.<%-MODEL%>, userObj)\n        }\n        let user = await dbService.findOne(model.<%-MODEL%>,{ \"githubId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.findOne(model.<%-MODEL%>,{email});\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.count(model.userTokens,{ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createOne(model.userTokens,{\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/github/templates/js/service.js.ejs",
    "content": "const GithubStrategy = require('passport-github2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL_FC%> = require('../model/<%-MODEL%>');\nconst userTokens = require(\"../model/userTokens\"); \nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  githubStrategy: passport => {\n    passport.use(new GithubStrategy({\n      clientID: process.env.GITHUB_CLIENTID,\n      clientSecret: process.env.GITHUB_CLIENTSECRET,\n      callbackURL: process.env.GITHUB_CALLBACKURL,\n      scope: ['public_profile', 'email']\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.username, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'githubId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"email\":userObj.email });\n        if(found){\n          const id = found.id;\n          await dbService.updateDocument(<%-MODEL_FC%>,id,userObj);\n        }\n        else{\n          await dbService.createDocument(<%-MODEL_FC%>,userObj)\n        }\n        let user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"sso_auth.githubId\":profile.id });\n        return done(null, user);\n      }\n      return done(null,null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ email });\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.countDocument(userTokens, { $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please Login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createDocument(userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true,data:'Email not exists'}\n      }\n    } catch (e) {\n      console.log(e);\n      throw new Error(e);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/app.js",
    "content": "/* eslint-disable global-require */\nconst fs = require('fs');\nconst ejs = require('ejs');\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\n\nfunction loadTemplate (name) {\n  const util = require('util');\n  const contents = fs.readFileSync(path.join(__dirname, 'templates', (`${name}.ejs`)), 'utf-8');\n  const locals = Object.create(null);\n  function render () {\n    return ejs.render(contents, locals, { escape: util.inspect });\n  }\n  return {\n    locals,\n    render,\n  };\n}\n\nfunction generateSocialLoginForMVC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service.js');\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.MODEL = jsonData.model;\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/google-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/google-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/google/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/google/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/google-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nfunction generateSocialLoginForCC (jsonData) {\n  const { config } = jsonData;\n  const projectId = jsonData.id;\n  const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n  if (!fs.existsSync(`${projectPath}/services`)) {\n    fs.mkdirSync(`${projectPath}/services`);\n  }\n  if (!fs.existsSync(`${projectPath}/routes`)) {\n    fs.mkdirSync(`${projectPath}/routes`);\n  }\n  const model = loadTemplate('js/service-cc.js');\n  model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n  model.locals.MODEL = jsonData.model;\n  model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n  model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n  if (jsonData.keys) {\n    model.locals.KEYS = jsonData.keys;\n  }\n  writeOperations.write(`${projectPath}/services/google-login-service.js`, model.render());\n  const route = loadTemplate('js/routes/google-login-routes-cc.js');\n  if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n    jsonData.credentials.callbackUrl = '/auth/google/callback';\n  }\n  if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n    jsonData.credentials.errorUrl = '/auth/google/error';\n  }\n  route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n  route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n  writeOperations.write(`${projectPath}/routes/google-login-routes.js`, route.render());\n}\n\nfunction generateSocialLoginForCCSequelize (jsonData) {\n  const { config } = jsonData;\n  const projectId = jsonData.id;\n  const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n  if (!fs.existsSync(`${projectPath}/services`)) {\n    fs.mkdirSync(`${projectPath}/services`);\n  }\n  if (!fs.existsSync(`${projectPath}/routes`)) {\n    fs.mkdirSync(`${projectPath}/routes`);\n  }\n  const model = loadTemplate('js/service-cc-sequelize.js');\n  model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n  model.locals.MODEL = jsonData.model;\n  model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n  model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n  if (jsonData.keys) {\n    model.locals.KEYS = jsonData.keys;\n  }\n  writeOperations.write(`${projectPath}/services/google-login-service.js`, model.render());\n  const route = loadTemplate('js/routes/google-login-routes-cc.js');\n  if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n    jsonData.credentials.callbackUrl = '/auth/google/callback';\n  }\n  if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n    jsonData.credentials.errorUrl = '/auth/google/error';\n  }\n  route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n  route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n  writeOperations.write(`${projectPath}/routes/google-login-routes.js`, route.render());\n}\n\nfunction generateSocialLoginForMVCSequelize (jsonData) {\n  const { config } = jsonData;\n  const projectId = jsonData.id;\n  const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n  if (!fs.existsSync(`${projectPath}/services`)) {\n    fs.mkdirSync(`${projectPath}/services`);\n  }\n  if (!fs.existsSync(`${projectPath}/routes`)) {\n    fs.mkdirSync(`${projectPath}/routes`);\n  }\n  const model = loadTemplate('js/service-sequelize.js');\n  model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n  model.locals.MODEL = jsonData.model;\n  model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n  model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n  if (jsonData.keys) {\n    model.locals.KEYS = jsonData.keys;\n  }\n  writeOperations.write(`${projectPath}/services/google-login-service.js`, model.render());\n  const route = loadTemplate('js/routes/google-login-routes.js');\n  if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n    jsonData.credentials.callbackUrl = '/auth/google/callback';\n  }\n  if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n    jsonData.credentials.errorUrl = '/auth/google/error';\n  }\n  route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n  route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n  writeOperations.write(`${projectPath}/routes/google-login-routes.js`, route.render());\n}\n\nasync function main (jsonData) {\n  try {\n    const { projectType } = jsonData;\n    switch (projectType) {\n    case 'mvc':\n      generateSocialLoginForMVC(jsonData);\n      break;\n    case 'clean-code':\n      generateSocialLoginForCC(jsonData);\n      break;\n    case 'mvc_sequelize':\n      generateSocialLoginForMVCSequelize(jsonData);\n      break;\n    case 'cc_sequelize':\n      generateSocialLoginForCCSequelize(jsonData);\n      break;\n    default:\n      // console.log('Invalid Project Type');\n      break;\n    }\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nmodule.exports = main;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/routes/google-login-routes-cc.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  googleStrategy,loginUser \n} = require('../services/google-login-service');\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\n\n//google\ngoogleStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave:true,\n  saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  let result = response.badRequest({message:'Login Failed'});\n  responseHandler(res,result);\n});\n\nrouter.get('/auth/google',passport.authenticate('google', { \n  scope: ['profile', 'email'],\n  session:false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('google', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req,res){\n    loginUser(req.user.email,req.session.platform).then(user=>{\n      if (!user.flag){\n        let result = response.success({message:'Login Successful',data:user.data});\n        responseHandler(res,result);\n      }\n      else {\n        let result = response.badRequest({message:user.data});\n        responseHandler(res,result);\n      }     \n    })\n      .catch(error=>{\n        let result = response.internalServerError();\n        responseHandler(res,result);\n      });\n  }\n);\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/routes/google-login-routes.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  googleStrategy,loginUser \n} = require('../services/google-login-service');\n\n//google\ngoogleStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave:true,\n  saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  return res.badRequest();\n});\n\nrouter.get('/auth/google',passport.authenticate('google', { \n  scope: ['profile', 'email'],\n  session:false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('google', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req,res){\n    loginUser(req.user.email,req.session.platform).then(result=>{\n      if (result.flag){\n        return res.badRequest({message:result.data});\n      }\n      return res.success({data:result.data});\n    })\n      .catch(error=>{\n        return res.internalServerError();\n      });\n  }\n);\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/service-cc-sequelize.js.ejs",
    "content": "const GoogleStrategy = require('passport-google-oauth20').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  googleStrategy: passport => {\n    passport.use(new GoogleStrategy({\n      clientID: process.env.GOOGLE_CLIENTID,\n      clientSecret: process.env.GOOGLE_CLIENTSECRET,\n      callbackURL: process.env.GOOGLE_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'googleId': profile.id ,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj);\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"googleId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:{ tokenExpiredTime: { $gt: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn}\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/service-cc.js.ejs",
    "content": "const GoogleStrategy = require('passport-google-oauth20').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  googleStrategy: passport => {\n    passport.use(new GoogleStrategy({\n      clientID: process.env.GOOGLE_CLIENTID,\n      clientSecret: process.env.GOOGLE_CLIENTSECRET,\n      callbackURL: process.env.GOOGLE_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'googleId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj)\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"sso_auth.googleId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({ userId: user.id, token: token,tokenExpiredTime: expire });                              \n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/service-sequelize.js.ejs",
    "content": "const GoogleStrategy = require('passport-google-oauth20').Strategy;\nconst jwt = require(\"jsonwebtoken\");\n<%_if(RESTRICTION){_%>\nconst {Op} = require('sequelize');\n<%_}_%>\nconst dayjs = require('dayjs');\n\nconst model = require(\"../model/index\")\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  googleStrategy: passport => {\n    passport.use(new GoogleStrategy({\n      clientID: process.env.GOOGLE_CLIENTID,\n      clientSecret: process.env.GOOGLE_CLIENTSECRET,\n      callbackURL: process.env.GOOGLE_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'googleId': profile.id ,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.findOne(model.<%-MODEL%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateByPk(model.<%-MODEL%>, id, userObj);\n        }\n        else {\n          await dbService.createOne(model.<%-MODEL%>, userObj)\n        }\n        let user = await dbService.findOne(model.<%-MODEL%>,{ \"googleId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.findOne(model.<%-MODEL%>,{email});\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.count(model.userTokens,{ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createOne(model.userTokens,{\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/google/templates/js/service.js.ejs",
    "content": "const GoogleStrategy = require('passport-google-oauth20').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL_FC%> = require('../model/<%-MODEL%>'); \nconst userTokens = require(\"../model/userTokens\");\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\n\nmodule.exports = {\n  googleStrategy: passport => {\n    passport.use(new GoogleStrategy({\n      clientID: process.env.GOOGLE_CLIENTID,\n      clientSecret: process.env.GOOGLE_CLIENTSECRET,\n      callbackURL: process.env.GOOGLE_CALLBACKURL\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'googleId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateDocument(<%-MODEL_FC%>, id, userObj);\n        }\n        else {\n          await dbService.createDocument(<%-MODEL_FC%>, userObj)\n        }\n        let user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"sso_auth.googleId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{email});\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.countDocument(userTokens, { $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createDocument(userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/app.js",
    "content": "/* eslint-disable global-require */\nconst fs = require('fs');\nconst ejs = require('ejs');\nconst path = require('path');\nconst writeOperations = require('../../writeOperations');\n\nfunction loadTemplate (name) {\n  const util = require('util');\n  const contents = fs.readFileSync(path.join(__dirname, 'templates', (`${name}.ejs`)), 'utf-8');\n  const locals = Object.create(null);\n  function render () {\n    return ejs.render(contents, locals, { escape: util.inspect });\n  }\n  return {\n    locals,\n    render,\n  };\n}\n\nfunction generateSocialLoginForMVC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/linkedin-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/linkedin-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/linkedin/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/linkedin/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/linkedin-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err.message);\n  }\n}\n\nfunction generateSocialLoginForCC (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n\n    writeOperations.write(`${projectPath}/services/linkedin-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/linkedin-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/linkedin/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/linkedin/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/linkedin-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err.message);\n  }\n}\n\nfunction generateSocialLoginForMVCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-sequelize.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n\n    writeOperations.write(`${projectPath}/services/linkedin-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/linkedin-login-routes.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/linkedin/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/linkedin/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/linkedin-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err.message);\n  }\n}\n\nfunction generateSocialLoginForCCSequelize (jsonData) {\n  try {\n    const { config } = jsonData;\n    const projectId = jsonData.id;\n    const projectPath = `${config.path}/${projectId}/${config.projectName}`;\n    if (!fs.existsSync(`${projectPath}/services`)) {\n      fs.mkdirSync(`${projectPath}/services`);\n    }\n    if (!fs.existsSync(`${projectPath}/routes`)) {\n      fs.mkdirSync(`${projectPath}/routes`);\n    }\n    const model = loadTemplate('js/service-cc-sequelize.js');\n    model.locals.MODEL = jsonData.model;\n    model.locals.MODEL_FC = jsonData.model.charAt(0).toUpperCase() + jsonData.model.slice(1);\n    model.locals.RESTRICTION = jsonData.deviceRestriction ? jsonData.deviceRestriction : false;\n    model.locals.PLATFORMS = jsonData.platforms ? jsonData.platforms : [];\n    if (jsonData.keys) {\n      model.locals.KEYS = jsonData.keys;\n    }\n    writeOperations.write(`${projectPath}/services/linkedin-login-service.js`, model.render());\n    const route = loadTemplate('js/routes/linkedin-login-routes-cc.js');\n    if (!jsonData.credentials.callbackUrl || jsonData.credentials.callbackUrl === '') {\n      jsonData.credentials.callbackUrl = '/auth/linkedin/callback';\n    }\n    if (!jsonData.credentials.errorUrl || jsonData.credentials.errorUrl === '') {\n      jsonData.credentials.errorUrl = '/auth/linkedin/error';\n    }\n    route.locals.CALLBACK_URL = jsonData.credentials.callbackUrl;\n    route.locals.ERROR_URL = jsonData.credentials.errorUrl;\n    writeOperations.write(`${projectPath}/routes/linkedin-login-routes.js`, route.render());\n  } catch (err) {\n    throw new Error(err.message);\n  }\n}\n\nasync function main (jsonData) {\n  try {\n    const { projectType } = jsonData;\n    switch (projectType) {\n    case 'mvc':\n      generateSocialLoginForMVC(jsonData);\n      break;\n    case 'clean-code':\n      generateSocialLoginForCC(jsonData);\n      break;\n    case 'mvc_sequelize':\n      generateSocialLoginForMVCSequelize(jsonData);\n      break;\n    case 'cc_sequelize':\n      generateSocialLoginForCCSequelize(jsonData);\n      break;\n    default:\n      // console.log('Invalid Project Type');\n      break;\n    }\n  } catch (err) {\n    throw new Error(err);\n  }\n}\n\nmodule.exports = main;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/routes/linkedin-login-routes-cc.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  linkedInStrategy,loginUser \n} = require('../services/linkedin-login-service');\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\n\n//linedin\nlinkedInStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave:true,\n  saveUninitialized:false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  let result = response.badRequest({message:'Login Failed'});\n  sendResponse(res,result);\n});\n\nrouter.get('/auth/linkedin',passport.authenticate('linkedin', { \n  scope: ['r_emailaddress', 'r_liteprofile'],\n  session:false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('linkedin', { failureRedirect: '/error' }),\n  function (req,res){\n    loginUser(req.user.email,req.session.platform).then(user=>{\n      if (!user.flag){\n        let result = response.success({message:'Login Successful',data:user.data});\n        sendResponse(res,result);\n      }\n      else {\n        let result = response.badRequest({message:user.data});\n        sendResponse(res,result);\n      }  \n    })\n      .catch(error=>{\n        let result = response.internalServerError();\n        sendResponse(res,result);\n      });\n  }\n);\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/routes/linkedin-login-routes.js.ejs",
    "content": "const express = require('express');\nconst session = require('express-session');\nconst router = express.Router();\nconst passport = require('passport');\n\nconst {\n  linkedInStrategy, loginUser \n} = require('../services/linkedin-login-service');\n\n//linkedin\nlinkedInStrategy(passport);\n\nrouter.use(passport.initialize());\n\nrouter.use(session({\n  secret: 'my-secret',\n  resave: true,\n  saveUninitialized: false\n}));\n\npassport.serializeUser(function (user, cb) {\n  cb(null, user);\n});\n\npassport.deserializeUser(function (user, cb) {\n  cb(null, user);\n});\n\nrouter.get('<%-ERROR_URL%>', (req, res) => {\n  return res.badRequest();\n});\n\nrouter.get('/auth/linkedin', passport.authenticate('linkedin', {\n  scope: ['r_emailaddress', 'r_liteprofile'],\n  session: false \n}));\n\nrouter.get('<%-CALLBACK_URL%>',\n  passport.authenticate('linkedin', { failureRedirect: '<%-ERROR_URL%>' }),\n  function (req, res) {\n    loginUser(req.user.email,req.session.platform).then(result=>{\n      if (result.flag){\n        return res.badRequest({message:result.data});\n      }\n      return res.success({data:result.data});\n    })\n      .catch(error=>{\n        return res.internalServerError();\n      });\n  }\n);\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/service-cc-sequelize.js.ejs",
    "content": "const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\")\nconst userTokensDb = require(\"../data-access/userTokensDb\")\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n    linkedInStrategy: passport => {\n    passport.use(new LinkedInStrategy({\n      clientID: process.env.LINKEDIN_CLIENTID,\n      clientSecret: process.env.LINKEDIN_CLIENTSECRET,\n      callbackURL: process.env.LINKEDIN_CALLBACKURL,\n      scope: ['r_emailaddress', 'r_liteprofile'],\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'linkedinId': profile.id,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj);\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"linkedinId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:{ tokenExpiredTime: { $gt: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true,data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/service-cc.js.ejs",
    "content": "const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL.toLowerCase()%>Db = require(\"../data-access/<%-MODEL%>Db\");\nconst userTokensDb = require(\"../data-access/userTokensDb\");\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n    linkedInStrategy: passport => {\n    passport.use(new LinkedInStrategy({\n      clientID: process.env.LINKEDIN_CLIENTID,\n      clientSecret: process.env.LINKEDIN_CLIENTSECRET,\n      callbackURL: process.env.LINKEDIN_CALLBACKURL,\n      scope: ['r_emailaddress', 'r_liteprofile'],\n    }, async function (accessToken, refreshToken, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'linkedinId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await <%-MODEL.toLowerCase()%>Db.findOne({\"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await <%-MODEL.toLowerCase()%>Db.updateOne(id, userObj);\n        }\n        else {\n          await <%-MODEL.toLowerCase()%>Db.create(userObj)\n        }\n        let user = await <%-MODEL.toLowerCase()%>Db.findOne({ \"sso_auth.linkedinId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await <%-MODEL.toLowerCase()%>Db.findOne({email });\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({ userId: user.id, token: token,tokenExpiredTime: expire });                              \n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true,data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/service-sequelize.js.ejs",
    "content": "const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\n<%_if(RESTRICTION){_%>\nconst {Op} = require('sequelize');\n<%_}_%>\nconst dayjs = require('dayjs');\n\nconst model = require(\"../model/index\")\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  linkedInStrategy: passport => {\n    passport.use(new LinkedInStrategy({\n      clientID: process.env.LINKEDIN_CLIENTID,\n      clientSecret: process.env.LINKEDIN_CLIENTSECRET,\n      callbackURL: process.env.LINKEDIN_CALLBACKURL,\n      scope: ['r_emailaddress', 'r_liteprofile'],\n    }, async function (token, tokenSecret, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'linkedinId': profile.id ,\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.findOne(model.<%-MODEL%>,{ \"email\": userObj.email });\n        if (found) {\n          const id = found.id;\n          await dbService.updateByPk(model.<%-MODEL%>, id, userObj);\n        }\n        else {\n          await dbService.createOne(model.<%-MODEL%>, userObj)\n        }\n        let user = await dbService.findOne(model.<%-MODEL%>,{ \"linkedinId\":profile.id });\n        return done(null, user);\n      }\n      return done(null, null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.findOne(model.<%-MODEL%>,{email});\n      if (user && user.email) {\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.count(model.userTokens,{ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId: user.id} } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createOne(model.userTokens,{\n            userId: user.id,\n            token: token,\n            tokenExpiredTime: expire \n        });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true, data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n  }\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/social/linkedin/templates/js/service.js.ejs",
    "content": "const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;\nconst jwt = require(\"jsonwebtoken\");\nconst dayjs = require('dayjs');\n\nconst <%-MODEL_FC%> = require('../model/<%-MODEL%>'); \nconst userTokens = require(\"../model/userTokens\");\nconst dbService = require('../utils/dbService');\nconst { JWT,LOGIN_ACCESS,USER_ROLE,PLATFORM<%_if(RESTRICTION){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\")\n\nmodule.exports = {\n  linkedInStrategy: passport => {\n    passport.use(new LinkedInStrategy({\n      clientID: process.env.LINKEDIN_CLIENTID,\n      clientSecret: process.env.LINKEDIN_CLIENTSECRET,\n      callbackURL: process.env.LINKEDIN_CALLBACKURL,\n      scope: ['r_emailaddress', 'r_liteprofile'],\n    }, async function (token, tokenSecret, profile, done) {\n      if(profile){\n        let userObj = {\n          <%_ if(KEYS !== undefined) { \n            Object.keys(KEYS).forEach((k)=>{ _%>\n            <%_ if(k == \"username\") {_%> <%=KEYS[k]%>:profile.displayName, <%_ } _%>\n            <%_ if(k == \"firstName\") {_%> <%=KEYS[k]%>:profile.name.givenName, <%_ } _%>\n            <%_ if(k == \"lastName\") {_%> <%=KEYS[k]%>:profile.name.familyName, <%_ } _%>\n            <%_ if(k == \"image\") {_%> <%=KEYS[k]%>:profile.photos !== undefined ? profile.photos[0].value : '', <%_ } _%>\n          <%_ })} _%>\n          'sso_auth': { 'linkedinId': profile.id },\n          'email': profile.emails !== undefined ? profile.emails[0].value : '',\n          'password':'',\n          'role':USER_ROLE.User\n        }\n        let found = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"email\":userObj.email });\n        if(found){\n          const id = found.id;\n          await dbService.updateDocument(<%-MODEL_FC%>,id,userObj);\n        }\n        else{\n          await dbService.createDocument(<%-MODEL_FC%>,userObj)\n        }\n        let user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ \"sso_auth.linkedinId\":profile.id });\n        return done(null, user);\n      }\n      return done(null,null);\n    }\n    ));\n  },\n  loginUser: async (email, platform) => {\n    try {\n      const user = await dbService.getDocumentByQuery(<%-MODEL_FC%>,{ email});\n      if (user && user.email) {\n        <%_if(RESTRICTION){_%>\n        const userToken = await dbService.countDocument(userTokens, { $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n        if(userToken >= NO_OF_DEVICE_ALLOWED){\n            return {\n                flag: true,\n                data: \"You have reached your device limit\"\n            }\n        }\n        <%_}_%>\n        const { ...userData } = user.toJSON();\n        let token;\n        if (!user.role) {\n          return {flag:true, data:'You have not been assigned any role'}\n        }\n        if(platform == undefined){\n          return {flag:true, data:'Please login through Platform'}\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n        <%_if(i===0){_%>\n        if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}else{_%>\n        else if(platform == '<%-PLATFORMS[i]%>'){\n            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                return {flag:true, data:'you are unable to access this platform'}\n            }\n            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n        }\n        <%_}_%>\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await dbService.createDocument(userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n        const userToReturn = { ...userData, token };\n        return {flag:false,data:userToReturn};\n      }\n      else {\n        return {flag:true,data:'Email not exists'}\n      }\n    } catch (error) {\n      throw new Error(error.message);\n    }\n\n  }\n\n}\n\nasync function generateToken(user,secret){\n  return jwt.sign( {id:user.id,email:user.email,username: user.username || user.email}, secret, {\n      expiresIn: JWT.EXPIRES_IN\n  });\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  parserOptions: {\n    ecmaVersion: 12,\n    sourceType: 'module',\n  },\n  rules: {\n    semi: ['error', 'always'],\n    indent: ['error', 2],\n    'no-irregular-whitespace': ['error', {\n      skipStrings: true,\n      skipComments: true,\n      skipRegExps: true,\n      skipTemplates: true,\n    }],\n    'multiline-comment-style': ['error', 'starred-block'],\n    'object-property-newline': ['error', {\n      allowAllPropertiesOnSameLine: false,\n      allowMultiplePropertiesPerLine: false,\n    }],\n    'object-curly-newline': ['error', {\n      minProperties: 2,\n      multiline: true,\n    }],\n    'no-multiple-empty-lines': ['error', {\n      max: 1,\n      maxEOF: 0,\n    }],\n    'no-param-reassign': 'off',\n    'no-underscore-dangle': 'off',\n    'class-methods-use-this': 'off',\n    'max-len': [2, {\n      code: 1000,\n      ignorePattern: '^import .*',\n    }],\n    'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],\n    'space-infix-ops': ['error', { int32Hint: false }],\n    'space-before-function-paren': ['error', {\n      anonymous: 'always',\n      named: 'always',\n      asyncArrow: 'always',\n    }],\n    'keyword-spacing': ['error', {\n      before: true,\n      after: true,\n    }],\n    'object-curly-spacing': ['error', 'always'],\n    quotes: ['error', 'single', { allowTemplateLiterals: true }],\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/.gitignore",
    "content": "node_modules\n.dhiwise"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/README.ejs",
    "content": "# NodeJS, Mongoose, Express Project in Clean-Code Architecture\n\n**supported version of nodejs > 12**,\n**supported version of mongoose-4.0**\n\n- This is a Web application, developed using MVC pattern with Node.js, ExpressJS, and Mongoose ODM. \n- Basic boilerplate for web applications, built on Express.js using the clean-code architecture\n- A MongoDB database is used for data storage, with object modeling provided by Mongoose.\n\n## Initial\n- Configure a basic server in app.js.\n- Organize the routes with Express Router.\n- Use the mainRoutes in app as middleware.\n- Set a final use after the routes, to display a 404 message for the unhandled requests.\n1. Install needed Node.js modules:\n     ```$ npm install```\n2. execute server:\n     ```$ npm start```\n\t<%_if(IS_AUTH){_%>\n3. When the app will run successfully,\n<%_if(ROLE_WISE_CREDENTIALS){_%>\n<%_for (let i in ROLE_WISE_CREDENTIALS){_%>\n       \n\t   - One user with <%-i%> role,\n\t\t# Default <%-i%> credentials\n\t\t**username** : <%-ROLE_WISE_CREDENTIALS[i][USER_FIELD]%>\n\t\t**password** : <%-ROLE_WISE_CREDENTIALS[i][PASSWORD_FIELD]%>\n\t\t\n<%_}_%> \n<%_}_%>\t \n<%_}_%>\n\n\n## Default Folder structure:\n\n\t--project_folder\n\t\t--config\n\t\t--constants\n\t\t--controller\n\t\t--entity\n\t\t--helpers\n\t\t--logs\n\t\t--middleware\n\t\t--model\n\t\t--postman\n\t\t--public\n\t\t--routes\n\t\t--services\n\t\t--utils\n\t\t--validation\n\t\t--views\n\t\t--app.js\n\t\t--.env\n\t\t--.gitignore\n\t\t--.eslintrc.js\n## app.js\n- Entry point of application.\n\n## config\n- Passport strategy for all platforms.\n- Based on Auth Model - authentication files has been generated.\n- Used .env file and configure the db connection string to use in the project.\n\n## constants\n- Contains files of constants\n\n## controller\n- Includes controller files per model\n- Controllers are separated per Platform\n\n     \t  -controller\n     \t        -admin\n     \t            -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -device\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -desktop\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -client\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n\n## entity\n- These are the business objects of your application. These should not be affected by any change external to them, and these should be the most stable code within your application. These can be POJOs, objects with methods, or even data structures.\n\n## helper\n- a helper function is used to assist in providing some functionality, which isn't the main goal of the application or class in which it is used.\n\n## logs\n- Log file\n\n## middleware\n- User authentication Middleware based on Roles and permission for Routes' access\n- Custom Policy files\n\n## model\n- Mongoose Models, as per user defined schema \n\n## postman\n- Postman collection File for Platform based APIs that are generated.\n- Import this JSON in Postman to test the APIs.\n\n## public \n- You can add static files like like images, pdf etc.\n\n## routes\n- Based on platform,separate folder is generated,within those folders model wise route files are that has model crud APIs' routes.\n- index.js file, main file which includes all platform routes.\n- Added index files in app.js to access the routes of the application.\n\n## services\n     \t-auth.js\n       \t\t-Logic for JWT Tokenization for user to login into Application using username and password along with otp if required.\n       \t-mongoDbService.js\n       \t    - Database related operations\n       \t     -common Database functionalities\n     \t  \t -getAllDocuments(find all documents)\n     \t  \t -updateDocuments(update single documents in db)\n     \t  \t -deleteDocuments(delete single documents in db)\n     \t  \t -createDocuments(create single documents in db)\n     \t  \t -getDocumentByQuery(find single document)\n\t\t\t -getSingleDocumentById(find by id)\n     \t  \t -softDelete\n     \t  \t -findExistData\n     \t  \t -bulkInsert(insert multiple documents in db)\n     \t  \t -bulkUpdate(update multiple documents in db)\n     \t  \t -countDocument\n\t\t\t -Aggregation\n       \t    \n## utils\n     \t-common.js\n       \t\t-converted object to enum function.\n     \t-messages.js\n  \t\t    -static messages that are sent with response - contains status and Data\n\t    -responseCode.js\n  \t\t    -codes for responses\n\t    -validateRequest.js\n  \t\t    -validate schema based on joi validation\n\n## validation\n- Joi validations files.\n- Files are separated by models.\n\n## views\n- Add ejs files\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/__test__/auth.test.js.ejs",
    "content": "<%_\nif(typeof(AUTH_MODEL_JSON) !== 'undefined'){\n  Object.keys(AUTH_MODEL_JSON).forEach(function(field){\n    if(AUTH_MODEL_JSON[field].type === 'Schema.Types.ObjectId' && AUTH_MODEL_JSON[field].ref !== undefined){\n      var newString = new String()\n      newString=JSON.stringify(AUTH_MODEL_JSON[field].ref);\n      newString = newString.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\" );\n      newString = newString.charAt(0).toUpperCase() + newString.slice(1);\n      FAKE_DATA_OF_AUTH[field] = `@@inserted${newString}.insertedId@@`\n    }  \n  })\n}\n_%>\n\nconst dotenv = require('dotenv');\ndotenv.config();\nprocess.env.NODE_ENV = 'test';\nconst db = require('mongoose');\nconst request = require('supertest');\nconst { MongoClient, ObjectId } = require('mongodb');\nconst app = require('../../app.js');\nconst authConstant=require('../../constants/authConstant');\nconst uri = 'mongodb://127.0.0.1:27017';\n\nconst client = new MongoClient(uri, {\n  useUnifiedTopology: true,\n  useNewUrlParser: true\n});\n\n<%_if(typeof(MODELS) !== 'undefined'){_%>\n<%_ Object.keys(MODELS).forEach(function(model) { _%>\nlet inserted<%-MODELS[model].charAt(0).toUpperCase() + MODELS[model].slice(1);%> = {};\n<%_ }); _%> \n<%_}_%>\n\nbeforeAll(async function(){\n  try {\n    await client.connect();\n    const db = client.db(<%=DB_NAME%>);\n\n    <%_if(typeof(FAKE_DATA) !== 'undefined'){_%>\n    <%_ Object.keys(FAKE_DATA).forEach(function(model){_%>\n    const <%-model%> = db.collection(<%=model%>);\n    inserted<%-model.charAt(0).toUpperCase() + model.slice(1); %> = await <%-model%>.insertOne(<%=JSON.parse(JSON.stringify(FAKE_DATA[model]))%>)\n    <%_})_%>\n    <%_}_%>\n  }\n  catch (err) {\n      console.error(`we encountered ${err}`);\n  }\n  finally {\n      client.close();\n  }\n})\n\ndescribe('POST /register -> if email and username is given', () => {\n  test('should register a <%-AUTH_MODEL%>', async () => {\n    let registeredUser = await request(app)\n      .post('/<%-PLATFORM%>/auth/register')\n      <%_var finalStr=new String(); \n      FAKE_DATA_OF_AUTH.role=`@@authConstant.USER_ROLE.${ROLE}@@`;\n        finalStr=JSON.stringify(FAKE_DATA_OF_AUTH); \n        finalStr=finalStr.replace(/@@\"/g, \"\" ).replace(/\"@@/g, \"\" ); \n      _%>\n      .send(<%-finalStr%>);\n    expect(registeredUser.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(registeredUser.body.status).toBe('SUCCESS');\n    expect(registeredUser.body.data).toMatchObject({\n      id: expect.any(String)\n    });\n    expect(registeredUser.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username and password is correct', () => {\n  test('should return <%-AUTH_MODEL%> with authentication token', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n      expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n      expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n      expect(<%-AUTH_MODEL%>.body.data).toMatchObject({\n          id: expect.any(String),\n          token: expect.any(String)\n      }); \n      expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username is incorrect', () => {\n  test('should return unauthorized status and <%-AUTH_MODEL%> not exists', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: 'wrong.username',\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if password is incorrect', () => {\n  test('should return unauthorized status and incorrect password', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: 'wrong@password'\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if username or password is empty string or has not passed in body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Insufficient parameters');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('POST /forgot-password -> if email has not passed from request body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ email: '' });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Insufficient parameters');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is not available in database ', () => {\n  test('should return record not found status', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': 'unavailable.email@hotmail.com', });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('RECORD_NOT_FOUND');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Record not found with specified criteria.');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is valid and OTP sent successfully', () => {\n  test('should return success message', async () => {\n    const expectedOutputMessages = [\n      'otp successfully send.',\n      'otp successfully send to your email.',\n      'otp successfully send to your mobile number.'\n    ];\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': <%_if(FAKE_DATA_OF_AUTH['email'] !== undefined) {_%><%=FAKE_DATA_OF_AUTH['email']%><%_}else{_%>'valid.mail@hotmail.com'<%_}_%>_%>, });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n    expect(expectedOutputMessages).toContain(<%-AUTH_MODEL%>.body.message);\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /validate-otp -> otp is sent in request body and OTP is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .post('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'otp': foundUser.body.data.resetPasswordLink.code, }).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('POST /validate-otp -> if OTP is incorrect or OTP has expired', () => {\n  test('should return invalid OTP', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({ 'otp': '12334' });\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid OTP');\n  });\n});\n\ndescribe('POST /validate-otp -> if request body is empty or otp has not been sent in body', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('PUT /reset-password -> code is sent in request body and code is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .put('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'code': foundUser.body.data.resetPasswordLink.code, 'newPassword':'newPassword'}).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('PUT /reset-password -> if request body is empty or code/newPassword is not given', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM.toLowerCase()%>/auth/reset-password')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('PUT /reset-password -> if code is invalid', () => {\n  test('should return invalid code', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM.toLowerCase()%>/auth/reset-password')\n      .send({\n        'code': '123',\n        'newPassword': 'testPassword'\n      });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid Code');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\nafterAll(function (done) {\n  db.connection.db.dropDatabase(function () {\n      db.connection.close(function () {\n          done();\n      });\n  });\n});\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/app.js.ejs",
    "content": "const express = require('express');\nconst cors = require('cors');\nconst path = require('path');\nconst dotenv = require('dotenv');\ndotenv.config();\nglobal.__basedir = __dirname;\n<%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\nconst listEndpoints = require('express-list-endpoints')\n<%_}_%>\n<% Object.keys(modules).sort().forEach(function (variable) { -%>\nlet <%- variable %> = require('<%- modules[variable] %>');\n<% }); -%>\n<% Object.keys(localModules).sort().forEach(function (variable) { -%>\nconst <%- variable %> = require('<%- localModules[variable] %>');\n<% }); -%>\n<%_ if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){ _%>\nconst passport = require(\"passport\")\n<%_ } _%>\n\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\nconst {<%-platform.toLowerCase()%>PassportStrategy} = require('./middleware');\n<%_ } _%>\n<%_ } _%>\n\nconst app = express();\nconst corsOptions = {\n    origin: process.env.ALLOW_ORIGIN,\n}\napp.use(cors(corsOptions));\n\n//template engine\napp.set('view engine', 'ejs'); \napp.set('views', path.join(__dirname, 'views'));\n\n<%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\nconst routes =  require(\"./routes/index\")\n<%_ } _%>\n\n<% uses.forEach(function (use) { -%>\napp.use(<%- use %>);\n<% }); -%>\n<%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\napp.use(routes)\n<%_ } _%>\n\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\n<%-platform.toLowerCase()%>PassportStrategy(passport);\n<%_ } _%>\n<%_ } _%>\n\n<% mounts.forEach(function (mount) { -%>\napp.use(<%= mount.path %>, <%- mount.code %>);\n<% }); -%>\n\napp.get('/', (req, res) => {\n  res.render('index');\n})\n\nif (process.env.NODE_ENV !== 'test' ) {\n    <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    const seeder = require('./seeders');\n    const allRegisterRoutes = listEndpoints(app);\n    seeder(allRegisterRoutes).then(()=>{console.log('Seeding done.')});\n    <%_}else if(typeof SEEDER !== \"undefined\" && SEEDER){_%>\n    const seeder = require('./seeders');\n    seeder().then(()=>{console.log('Seeding done.')});\n    <%_}_%>\n    app.listen(process.env.PORT,()=>{\n        console.log(`your application is running on ${process.env.PORT}`)\n    });\n} else {\n    module.exports = app;\n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/config/constant.js.ejs",
    "content": "const JWT={\n    <%_ PLATFORM.forEach(function (plt,index) { _%>\n        <%- plt.toUpperCase() %>_SECRET:\"myjwt<%- plt.toLowerCase() %>secret\",\n    <%_ }); _%>    \n    EXPIRES_IN: <%-TOKEN_EXPIRE_TIME%>\n}\n\nconst USER_ROLE ={  \n    <%_ USER_ROLE.forEach(function (role,index) { _%>\n        <%- role %>:<%- index+=1 %>,\n    <%_ }); _%>\n}\n\nconst PLATFORM = {\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>:<%- index+1 %>,\n<%_ }); _%>    \n}\n\nlet LOGIN_ACCESS ={\n<% Object.keys(LOGIN_ACCESS).map(function (key,index) { -%>\n    [USER_ROLE.<%- key %>]:<%_ let Arr=[]; LOGIN_ACCESS[key].forEach(function(plt,index){ _%>\n    <%_Arr.push(`PLATFORM.${plt.toUpperCase()}`);_%>\n<%_ }) _%><%-JSON.stringify(Arr).toString().replace(/\"/g, \"\");%>,           \n<% }); -%>\n}\n\nconst DEFAULT_ROLE= 1\n\n<%_if(LOGIN_RETRY_LIMIT){_%>\nconst MAX_LOGIN_RETRY_LIMIT = <%=LOGIN_RETRY_LIMIT.max%>;\nconst LOGIN_REACTIVE_TIME = <%=LOGIN_RETRY_LIMIT.reActiveTime%>;\n<%_}_%>    \n\n<%_if(RESET_PASSWORD){_%>\nconst FORGOT_PASSWORD_WITH = <%-RESET_PASSWORD%>\n<%_}_%>\n\n<%_if(DEVICE_ALLOWED_REQUIRED){_%>\nconst NO_OF_DEVICE_ALLOWED = <%-NO_OF_DEVICE%>\n<%_}_%>\n\nmodule.exports = {\n    JWT,\n    USER_ROLE,\n    DEFAULT_ROLE,\n    PLATFORM,\n    <%_if(LOGIN_RETRY_LIMIT){_%>\n    MAX_LOGIN_RETRY_LIMIT,\n    LOGIN_REACTIVE_TIME,\n    <%_}_%>\n    <%_if(RESET_PASSWORD){_%>\n    FORGOT_PASSWORD_WITH,\n    <%_}_%>\n    LOGIN_ACCESS,\n    <%_if(DEVICE_ALLOWED_REQUIRED){_%>\n    NO_OF_DEVICE_ALLOWED,\n    <%_}_%>\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/config/db.js.ejs",
    "content": "/*\n * Database connection file.\n */\nconst mongoose = require(\"mongoose\")\nconst uri = process.env.NODE_ENV === 'test' ? process.env.DB_TEST_URL : process.env.DB_URL;\nmongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true})\nvar db = mongoose.connection\n\ndb.once(\"open\", () => {\n    console.log(\"Connection Successful\")\n})\n\ndb.on(\"error\", () => {\n    console.log(\"Error in mongodb connection\")\n})\n\nmodule.exports = mongoose"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/config/passport.js.ejs",
    "content": "\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\nconst db = require(\"./db\");\nconst <%-MODEL%>  =require(\"../model/<%-MODEL%>\")(db)\n\nmodule.exports = {\n    <%- STRATEGY.toLowerCase() %>PassportStrategy: passport => {\n        const options = {};\n        options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); \n        options.secretOrKey = JWT.<%- STRATEGY.toUpperCase() %>_SECRET\n        passport.use('<%- STRATEGY.toLowerCase() %>-rule',\n            new Strategy(options, (payload, done) => {\n                <%-MODEL%>.findOne({ _id: payload.id }, (err, user) => {\n                    if (err) {\n                        // console.log(err)\n                        return done(err, false);\n                    }\n                    if (user) {\n                        return done(null, {\n                            ...user.toJSON()\n                        });\n                    }\n                    return done('No User Found', {});\n                });\n            })\n        );\n    }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/config/requestConstant.js.ejs",
    "content": "module.exports=<%=JSON.parse(CONSTANTS)%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/authController.js.ejs",
    "content": "const authConstant = require(\"../../../constants/authConstant\");\nconst response = require('../../../utils/response'); \nconst responseHandler = require('../../../utils/response/responseHandler');  \n\nconst register = (registerUsecase) => async (req,res) => {\n    try{\n        let result = await registerUsecase(req.body);\n        return responseHandler(res,result);\n    }catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nconst forgotPassword = (forgotPasswordUsecase) => async (req,res) => {\n    try{\n        let result = await forgotPasswordUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n    \nconst validateResetPasswordOtp = (validateResetPasswordOtpUsecase) => async (req,res) => {\n    try{\n        let result = await validateResetPasswordOtpUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n \nconst resetPassword = (resetPasswordUsecase) => async (req,res) => {\n    try {\n        let result = await resetPasswordUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nconst authentication = (authenticationUsecase) => async (req,res)=>{\n    try {\n        let result = await authenticationUsecase(req.body,authConstant.PLATFORM.<%-PLATFORM_NAME.toUpperCase()%>);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nconst logout = (logoutUsecase) => async (req,res) => {\n    try {\n        let user = req.user;\n        let token = req.headers.authorization.token.replace('Bearer ', '');\n        let result = await logoutUsecase(user, token);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nmodule.exports={\n    register,\n    authentication,\n    forgotPassword,\n    resetPassword,\n    validateResetPasswordOtp,\n    logout\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/authControllerIndex.js.ejs",
    "content": "let  <%-MODEL %>Db = require('../../../data-access/<%-MODEL %>Db');\nconst userTokensDb = require(\"../../../data-access/userTokensDb\");\n\nconst <%-MODEL %>Schema = require('../../../validation/schema/<%-MODEL %>');\nconst createValidation = require('../../../validation')(<%-MODEL %>Schema.createSchema);\n\nconst authController = require('./authController');\n\nconst registerUsecase = require('../../../use-case/authentication/register')({ \n        <%-MODEL %>Db, \n        createValidation, \n});\nconst authenticationUsecase = require('../../../use-case/authentication/authentication')({ <%-MODEL %>Db, userTokensDb});\nconst forgotPasswordUsecase = require('../../../use-case/authentication/forgotPassword')({ <%-MODEL %>Db});\nconst resetPasswordUsecase = require('../../../use-case/authentication/resetPassword')({ <%-MODEL %>Db});\nconst validateResetPasswordOtpUsecase = require('../../../use-case/authentication/validateResetPasswordOtp')({ <%-MODEL %>Db});\nconst logoutUsecase = require('../../../use-case/authentication/logout')({userTokensDb});\nconst register = authController.register(registerUsecase);\nconst authentication = authController.authentication(authenticationUsecase);\nconst forgotPassword = authController.forgotPassword(forgotPasswordUsecase);\nconst resetPassword = authController.resetPassword(resetPasswordUsecase);\nconst validateResetPasswordOtp = authController.validateResetPasswordOtp(validateResetPasswordOtpUsecase);\nconst logout = authController.logout(logoutUsecase);\n\nmodule.exports={\n    register,\n    authentication,\n    forgotPassword,\n    resetPassword,\n    validateResetPasswordOtp,\n    logout\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/controller.js.ejs",
    "content": "const response = require('../../../utils/response');\nconst responseHandler = require('../../../utils/response/responseHandler'); \n\n<%_ var methods = [] _%>\n<%_for(let i=0;i< SUPPORT_API.length;i++){_%>\n<%_ if(SUPPORT_API[i].method==\"create\") {_%>\n    <%_methods.push('add'+DB_MODEL_FC) _%> \n    const add<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            let dataToCreate = {...req.body || {} };\n            <%_ if(SUPPORT_API[i].isLogin){ _%>\n            dataToCreate.<%-SUPPORT_API[i].addedBy%> = req.user.id;\n            <%_ } _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(dataToCreate);\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            <%_SUPPORT_API[i].fields.push(\"id\")_%>\n            result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n            <%_}_%>\n            return responseHandler(res,result);\n        }catch(error){\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n    <%_methods.push('bulkInsert'+DB_MODEL_FC) _%>\n    const bulkInsert<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            let dataToCreate = req.body && req.body.data ? [...req.body.data] : [];\n            <%_ if(SUPPORT_API[i].isLogin){ _%>\n            dataToCreate.map((item) => { item.<%-SUPPORT_API[i].addedBy%> = req.user.id; return item });\n            <%_ } _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(dataToCreate);\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(result.data.length){\n                for(let i=0;i< result.data.length; i++){\n                result.data[i] = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data[i]);\n                }\n            }\n            <%_}_%>\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"update\") {_%>\n    <%_methods.push('update'+DB_MODEL_FC) _%>\n    const update<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) =>{\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let dataToUpdate = { ...req.body || {} };\n            let query = { _id: req.params.id};\n            <%_ if(SUPPORT_API[i].isLogin){ _%>\n            delete dataToUpdate.addedBy;\n            dataToUpdate.<%-SUPPORT_API[i].updatedBy%>=req.user.id\n            <%_ } _%>\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = { ...query, ...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(Object.keys(result.data).length){\n                result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n            }\n            <%_}_%>\n            return responseHandler(res,result);\n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"bulkUpdate\") {_%>\n    <%_methods.push('bulkUpdate'+DB_MODEL_FC) _%>\n    const bulkUpdate<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            let dataToUpdate = { ...req.body.data || {} };\n            let query = { ...req.body.filter || {} };\n            <%_ if(SUPPORT_API[i].isLogin){ _%>\n            delete dataToUpdate.<%-SUPPORT_API[i].addedBy%>;\n            dataToUpdate.<%-SUPPORT_API[i].updatedBy%>=req.user.id\n            <%_ } _%>\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = { ...query, ...<%=JSON.parse(element.filter)%>}           \n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\") {_%>\n    <%_methods.push('findAll'+DB_MODEL_FC) _%>\n    const findAll<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            let query= req.body && req.body.query ? {...req.body.query} : {};\n            let options= req.body && req.body.options ? {...req.body.options} : {};\n            <%_         \n                nestedCalls={}\n                if(SUPPORT_API[i].IS_NESTED_CALL){\n                    nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                    if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                        for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                            query = { ...query, ...<%=JSON.parse(element.filter)%>}\n                        <%_}}\n                    }                \n                }\n            _%>\n            <%_if(typeof VIRTUAL !== \"undefined\"){\n            let populate = [];\n            for(let v of VIRTUAL){\n                populate.push({\n                    path:v.fieldName\n                })\n            }\n            _%>\n            if (!options.populate) options.populate = [];\n            options.populate = options.populate.concat(<%= populate %>);\n            <%_}_%>\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(options.select && options.select.length){\n                options.select = <%=SUPPORT_API[i].fields%>.concat(options.select);\n            }else{\n                options.select=<%=SUPPORT_API[i].fields%>\n            }\n            <%_}_%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,options,isCountOnly:req.body.isCountOnly || false});\n            return responseHandler(res,result);\n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"partialUpdate\") {_%>\n    <%_methods.push('partialUpdate'+DB_MODEL_FC) _%>\nconst partialUpdate<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n    try {\n        if(!req.params.id){\n            return responseHandler(res,response.badRequest());\n        }\n        let query = { _id: req.params.id};\n        let dataToUpdate = {...req.body || {}};\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        delete dataToUpdate[\"addedBy\"]\n        dataToUpdate.<%-SUPPORT_API[i].updatedBy%>=req.user.id\n        <%_ } _%> \n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        if(Object.keys(result.data).length){\n            result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n        }\n        <%_}_%>\n        return responseHandler(res,result);\n    } catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC) _%>\n    const get<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) =>{\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let query = { _id: req.params.id};\n            let options = {};\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            options.select = getSelectObject(<%=SUPPORT_API[i].fields%>)\n            <%_}_%>\n            <%_if(typeof VIRTUAL !== \"undefined\"){\n                let populate = [];\n                for(let v of VIRTUAL){\n                    populate.push({\n                        path:v.fieldName\n                    })\n                }\n                _%>\n                options.populate = <%-JSON.stringify(populate)%>;\n            <%_}_%>\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query, options});\n            return responseHandler(res,result);\n        } catch(error){\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%> \n<%_ if(SUPPORT_API[i].method==\"count\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC+'Count') _%>\n    const get<%-DB_MODEL_FC%>Count = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try {\n            let where = {...req.body.where || {} };\n            <%_         \n                nestedCalls={}\n                if(SUPPORT_API[i].IS_NESTED_CALL){\n                    nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                    if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                        for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                            where= {...where,...<%=JSON.parse(element.filter)%>}                      \n                        <%_}}\n                    }                \n                }\n                _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(where); \n            return responseHandler(res,result); \n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"delete\") {_%>\n    <%_methods.push('delete'+DB_MODEL_FC) _%>\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const delete<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let query = {_id:req.params.id};\n            <%_         \n                nestedCalls={}\n                if(SUPPORT_API[i].IS_NESTED_CALL){\n                    nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                    if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                        for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                            query= {...query,...<%=JSON.parse(element.filter)%>}\n                        <%_}}\n                    }                \n                }\n                _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,isWarning:req.body.isWarning || false});\n            return responseHandler(res,result);\n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } else { _%>\n    const delete<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let query = {_id:req.params.id};\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>};\n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query});\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>  \n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"deleteMany\") {_%>\n    <%_methods.push('deleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = { _id : { $in:ids } };\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n        _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({ query,isWarning:req.body.isWarning || false},req,res);\n        return responseHandler(res,result);\n    } catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n<%_ } else { _%>\nconst deleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = { _id : { $in:ids } };\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n        _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query},req,res);\n        return responseHandler(res,result);\n    } catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n<%_ } _%>\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"softDelete\") {_%>\n    <%_methods.push('softDelete'+DB_MODEL_FC) _%>\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const softDelete<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let query = { _id: req.params.id};\n            let dataToUpdate = {\n                isDeleted: true,\n                <%_if(SUPPORT_API[i].isAuth){ _%>\n                <%-SUPPORT_API[i].updatedBy%>: req.user.id,\n                <%_}_%>\n            }\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate,isWarning:req.body.isWarning || false},req,res);\n            return responseHandler(res,result);\n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n    <%_ } else { _%>\n    const softDelete<%-DB_MODEL_FC%> =  (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res)=>{\n        try{\n            if(!req.params.id){\n                return responseHandler(res,response.badRequest());\n            }\n            let query = { _id: req.params.id};\n            let dataToUpdate = {\n                isDeleted: true,\n                <%_if(SUPPORT_API[i].isAuth){ _%>\n                <%-SUPPORT_API[i].updatedBy%>: req.user.id,\n                <%_}_%>\n            }\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n            _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate},req,res);\n            return responseHandler(res,result);\n        }catch(error){\n             return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"softDeleteMany\") {_%>\n    <%_methods.push('softDeleteMany'+DB_MODEL_FC) _%>\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst softDeleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = { _id : { $in:ids } };\n        let dataToUpdate = {\n            isDeleted: true,\n            <%_if(SUPPORT_API[i].isLogin){ _%>\n            <%-SUPPORT_API[i].updatedBy%>: req.user.id,\n            <%_}_%>\n        }\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n        _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate,isWarning:req.body.isWarning || false},req,res);\n        return responseHandler(res,result);\n    }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n<%_ } else { _%>\nconst softDeleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = { _id : { $in:ids } };\n        let dataToUpdate = {\n            isDeleted: true,\n            <%_if(SUPPORT_API[i].isLogin){ _%>\n            <%-SUPPORT_API[i].updatedBy%>: req.user.id,\n            <%_}_%>\n        }\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n        _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate},req,res);\n        return responseHandler(res,result);\n    }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n<%_ } _%>\n<%_ } _%>\n<%_ } _%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\n<%_methods.push('changePassword') _%>\n<%_methods.push('updateProfile') _%>\n<%_methods.push('getLoggedInUserInfo') _%>\n    const changePassword = (changePasswordUsecase) => async (req,res) => {\n        try{\n            let result = await changePasswordUsecase(req.body);\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    };\n\n    const updateProfile = (updateProfileUsecase) => async (req,res) => {\n        try{\n            let result = await updateProfileUsecase(req.body,req.params.id);\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }   \n    };\n\n    const getLoggedInUserInfo = (get<%-DB_MODEL_FC%>Usecase) => async (req,res) =>{\n        try {\n            if(!req.user){\n                return responseHandler(res,response.badRequest());\n            }\n            const query = {\n                _id : req.user.id,\n                isDeleted: false,\n                isActive:true\n            };\n            let result = await get<%-DB_MODEL_FC%>Usecase({query,options:{}});\n            return responseHandler(res,result);\n        } catch (error) {\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    };\n\n<%_}_%>\n\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{ methods.push(v.functionName)_%>\n  const <%-v.functionName%> = (<%-v.functionName%>Usecase) => async(req,res) =>{\n    try{\n      let result = await <%-v.functionName%>Usecase(req,res);\n      return responseHandler(res,result);\n    }catch(error){\n      return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n  }\n  <%_});_%>\n<%_}_%>\n\nmodule.exports = {\n   <%-methods.join()%>\n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/controllerIndex.js.ejs",
    "content": "<%_ let usedDb = []; _%>\n<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%> \n    const <%-model%>Db = require('../../../data-access/<%-model %>Db');\n<%_ usedDb.push(model);  }); _%>\n\n<%_ if(!usedDb.includes(DB_MODEL)){_%>\nconst <%-DB_MODEL %>Db = require('../../../data-access/<%-DB_MODEL %>Db');\n<%_ } _%>\n\nconst <%-DB_MODEL %>Schema = require('../../../validation/schema/<%-DB_MODEL %>');\n\nconst createValidation = require('../../../validation')(<%-DB_MODEL %>Schema.createSchema);\nconst updateValidation = require('../../../validation')(<%-DB_MODEL %>Schema.updateSchema);\n\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/create')({ <%-DB_MODEL %>Db,createValidation });\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/update')({ <%-DB_MODEL %>Db, updateValidation });\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/deleteOne')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/findById')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/findAll')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/count')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n        <%_ if(controllerMethod === 'createBulk'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/createBulk')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/updateBulk')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/deleteMany')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/softDelete')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/softDeleteMany')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/partialUpdate')({ <%-DB_MODEL %>Db,updateValidation});\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\nconst changePasswordUsecase = require('../../../use-case/<%-DB_MODEL %>/changePassword')({ <%-DB_MODEL %>Db});\nconst updateProfileUsecase = require('../../../use-case/<%-DB_MODEL %>/updateProfile')({ <%-DB_MODEL %>Db,updateValidation});\nconst get<%-DB_MODEL_FC%>Usecase = require('../../../use-case/<%-DB_MODEL %>/findById')({ <%-DB_MODEL %>Db})\n<%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    const <%-v.functionName%>Usecase = require('../../../use-case/<%-DB_MODEL %>/<%-v.functionName%>')({ <%-v.model%>Db});\n  <%_});_%>\n<%_}_%>\n\nconst <%-DB_MODEL %>Controller = require('./<%-DB_MODEL %>');\n\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        const add<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.add<%-DB_MODEL_FC %>(<%-controllerMethod +DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        const update<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.update<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        const delete<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.delete<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        const get<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.get<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        const findAll<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.findAll<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        const get<%-DB_MODEL_FC %>Count = <%-DB_MODEL %>Controller.get<%-DB_MODEL_FC %>Count(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n        <%_ if(controllerMethod === 'createBulk'){ _%>\n        const bulkInsert<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.bulkInsert<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        const bulkUpdate<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.bulkUpdate<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        const deleteMany<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.deleteMany<%-DB_MODEL_FC %>(<%-controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        const softDelete<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.softDelete<%-DB_MODEL_FC %>(<%-controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        const softDeleteMany<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.softDeleteMany<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        const partialUpdate<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.partialUpdate<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\nconst changePassword = <%-DB_MODEL %>Controller.changePassword(changePasswordUsecase);\nconst updateProfile = <%-DB_MODEL %>Controller.updateProfile(updateProfileUsecase);\nconst getLoggedInUserInfo = <%-DB_MODEL %>Controller.getLoggedInUserInfo(get<%-DB_MODEL_FC%>Usecase);\n<%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    const <%-v.functionName%> = <%-DB_MODEL %>Controller.<%-v.functionName%>(<%-v.functionName%>Usecase);\n  <%_});_%>\n<%_}_%>\n\nmodule.exports = {\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        add<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        update<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        delete<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        get<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        findAll<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        get<%-DB_MODEL_FC %>Count,\n    <%_}_%>\n    <%_ if(controllerMethod === 'createBulk'){ _%>\n        bulkInsert<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        bulkUpdate<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        deleteMany<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        softDelete<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        softDeleteMany<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        partialUpdate<%-DB_MODEL_FC %>,\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\n    changePassword,\n    updateProfile,\n    getLoggedInUserInfo,\n    <%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    <%-v.functionName%>,\n  <%_});_%>\n<%_}_%>\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/fileUploadController.js.ejs",
    "content": "const response = require('../../../utils/response');\nconst responseHandler = require('../../../utils/response/responseHandler'); \n\nconst upload = (fileUploadUsecase) => async (req,res) => {\n  try {\n    let result = await fileUploadUsecase(req,res);\n    return responseHandler(res,result);\n  } catch (error) {\n    return responseHandler(res,response.internalServerError({ message:error.message }));\n  }\n};\n\nmodule.exports = {upload}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/controllers/fileUploadControllerIndex.js.ejs",
    "content": "const fileUploadUsecase = require('<%-USECASE_PATH%>/fileUpload/upload');\nconst fileUploadController = require('./fileUploadController');\n\nconst upload = fileUploadController.upload(fileUploadUsecase);\n\nmodule.exports = { upload };"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/customEnv.ejs",
    "content": "<%_for(const [key,value] of Object.entries(CUSTOM_ENV)) {_%>\n<%-key%>=<%-value%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/data-access/dbFile.js.ejs",
    "content": "let <%-MODEL_NAME_FC-%> = require('../db/mongoDB/models/<%-MODEL_NAME-%>');\nlet { create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,\n    upsert } = require('../db/mongoDB/dbService')(<%-MODEL_NAME_FC-%>);\n\nmodule.exports = {\n    create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,\n    upsert\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/data-access/dbService.js",
    "content": "/* eslint-disable */\nmodule.exports = function mongoDbService(Model) {\n  const create = async (data) => Model.create(data);\n\n  const createMany = async (data, options = {}) => Model.create(data, options);\n\n  const updateOne = async (filter, data, options = { new: true }) => Model.findOneAndUpdate(filter, data, options);\n\n  const updateMany = async (filter, data, options = {}) => Model.updateMany(filter, data, options);\n\n  const deleteOne = async (filter, options = {}) => Model.findOneAndDelete(filter, options);\n\n  const deleteMany = async (filter, options = {}) => Model.deleteMany(filter, options);\n\n  const softDelete = async (filter, data) => Model.updateOne(filter, data);\n\n  const softDeleteMany = async (filter, data) => Model.updateMany(filter, data);\n\n  const findOne = async (filter, options = {}) => {\n    let projection = options.projection ? options.projection : null;\n    return Model.findOne(filter, projection, options);\n  }\n\n  const findMany = async (filter, options = {}) => {\n    let projection = options.projection ? options.projection : null;\n    return Model.find(filter, projection, options);\n  };\n\n  const paginate = async (filter, options = {}) => Model.paginate(filter, options);\n\n  const count = async (filter) => Model.countDocuments(filter);\n\n  const upsert = async (filter, data, options = {}) => Model.updateMany(filter, data, {\n    ...options,\n    upsert: true,\n  });\n\n  return Object.freeze({\n    create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,\n    upsert,\n  });\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/data-access/sequenceDb.js.ejs",
    "content": "let Sequence = require('../db/mongoDB/models/sequence');\nlet {\n  create,\n  createMany,\n  updateOne,\n  updateMany,\n  deleteOne,\n  deleteMany,\n  softDelete,\n  softDeleteMany,\n  findOne,\n  findMany,\n  paginate,\n  count,\n} = require('../db/mongoDB/dbService')(Sequence);\n\nmodule.exports = {\n  create,\n  createMany,\n  updateOne,\n  updateMany,\n  deleteOne,\n  deleteMany,\n  softDelete,\n  softDeleteMany,\n  findOne,\n  findMany,\n  paginate,\n  count,\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/entity/entity.js.ejs",
    "content": "module.exports = (<%-ENTITY_NAME-%>) => {\n\n    let new<%-ENTITY_NAME_FC-%> = { \n        <%_ for(const key of ENTITY_KEYS){ _%>\n                <%-key%>: <%-ENTITY_NAME-%>.<%-key%>,\n        <%_} _%>  \n    };\n\n    // remove undefined values\n    if(new<%-ENTITY_NAME_FC-%>.id){\n        Object.keys(new<%-ENTITY_NAME_FC-%>).forEach(key =>{\n            if(new<%-ENTITY_NAME_FC-%>[key] === undefined) return new<%-ENTITY_NAME_FC-%>[key]=null\n        });\n    }else{\n        Object.keys(new<%-ENTITY_NAME_FC-%>).forEach(key => new<%-ENTITY_NAME_FC-%>[key] === undefined && delete new<%-ENTITY_NAME_FC-%>[key]);\n    }\n\n    // To validate Entity uncomment this block\n\n    /* const validate = (new<%-ENTITY_NAME_FC-%>) => {\n         if (!new<%-ENTITY_NAME_FC-%>.field) {\n             throw new Error(\"this field is required\");\n         }\n    }\n    \n    validate(new<%-ENTITY_NAME_FC-%>) */\n    return Object.freeze(new<%-ENTITY_NAME_FC-%>);\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/helpers/date.js",
    "content": "const getDifferenceOfTwoDatesInTime = (currentDate, toDate) => {\n  const hours = toDate.diff(currentDate, 'hour');\n  currentDate = currentDate.add(hours, 'hour');\n  const minutes = toDate.diff(currentDate, 'minute');\n  currentDate = currentDate.add(minutes, 'minute');\n  const seconds = toDate.diff(currentDate, 'second');\n  currentDate = currentDate.add(seconds, 'second');\n  if (hours) {\n    return `${hours} hour, ${minutes} minute and ${seconds} second`;\n  }\n  return `${minutes} minute and ${seconds} second`;\n};\n\nmodule.exports = { getDifferenceOfTwoDatesInTime };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/controller.js.ejs",
    "content": "const response = require('../../../utils/response'); \nconst responseHandler = require('../../../utils/response/responseHandler');\n\n<%_ROUTES.forEach((v,i)=>{_%>\n  const <%-v.functionName%> = (<%-v.functionName%>Usecase) => async(req,res) =>{\n      try{\n        return await <%-v.functionName%>Usecase(req,res);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n  }\n<%_})_%>\n\nmodule.exports = {\n  <%_ROUTES.forEach((v,i)=>{_%>\n  <%-v.functionName%>,\n  <%_})_%>\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/controllerIndex.js.ejs",
    "content": "<%_\nlet models = UNIQ_TASK_MODELS\nlet modelFC=\"\"\nif(models){ _%>\n  <%_ for(const model of models){ _%>\n    const <%-model%>Db = require(\"<%-DATA_ACCESS_PATH%>/<%-model%>Db\")\n  <%_ } _%> \n<%_ }_%> \n\n\n<%_ ROUTES.forEach((v,i)=>{ _%>\n  <%_if(typeof(v.model) !== 'undefined' && v.model !== null){_%>\n  const <%-v.functionName%>Usecase = require('<%-USECASE_PATH%>/<%-v.model%>/<%-v.functionName%>')({<%_ if(v.cq_model && v.cq_model.length) { for( let i=0;i< v.cq_model.length;i++) { _%> <%- v.cq_model[i] %>Db, <%_ } }_%>});\n  <%_}else{_%>\n  const <%-v.functionName%>Usecase = require('<%-USECASE_PATH%>/customRoutes/<%-v.functionName%>')({<%_ if(v.cq_model && v.cq_model.length) { for( let i=0;i< v.cq_model.length;i++) { _%> <%- v.cq_model[i] %>Db, <%_ } }_%>});\n  <%_}_%>\n<%_})_%>\n\nconst <%-SERVICE_NAME %>Controller = require('./<%-SERVICE_NAME %>');\n\n<%_ ROUTES.forEach((v,i)=>{_%>\n  const <%-v.functionName%> = <%-SERVICE_NAME %>Controller.<%-v.functionName%>(<%-v.functionName%>Usecase);\n<%_})_%>\n\nmodule.exports = {<%_ROUTES.forEach((v,i)=>{_%>\n  <%-v.functionName%>,\n<%_})_%>}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/existIndexRoute.js.ejs",
    "content": "<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/<%-v%>\",require(\"./<%-v%>/index\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/indexRoutes.js.ejs",
    "content": "\n<%_ ROUTES.forEach(function(route){ _%>\n    router.use(\"/<%-route%>\",require(\"./<%-route%>Routes\"))\n<%_ })_%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/platformIndexRoutes.js.ejs",
    "content": "const express = require(\"express\")\nconst router =  express.Router()\n\n<%_ CONTROLLERS.forEach(function(controller){ _%>\nrouter.use(\"/\",require(\"./<%-controller%>Routes\"))\n<%_ })_%>\n\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/route.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\nconst <%- SERVICE_NAME%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-SERVICE_NAME%>\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_\nif(POLICIES && POLICIES.length){\n POLICIES.forEach((policy)=>{_%>\nconst <%-policy%> = require(\"../../middleware/<%-policy%>\")\n<%_}) }_%>\n<%_\nif(typeof(CONTROLLER_IMPORTS) !== 'undefined' ){\nObject.keys(CONTROLLER_IMPORTS).forEach(function(key) { _%>\nconst <%-key%> = require(\"<%-CONTROLLER_IMPORTS[key]%>\")\n<%_ }); } _%> \n\n<%_ ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>( <%_if(v.policies && v.policies.length){_%>\n  <%_v.policies.forEach((policy)=>{_%>\n  <%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n  <%_}else{_%>\n  <%-policy%>,<%_}_%>\n  <%_})_%><%_}_%><%-v.controller%>Controller.<%- v.functionName %>);\n<%_})_%>\n    \nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/individualRoutes/service.js.ejs",
    "content": "<%_ROUTES.forEach((v,i)=>{_%>\n/* \n* <%-v.descriptions%>\n*/\nconst <%-v.functionName%>=()=>{\n    try {\n        console.log(\"<%-v.functionName%> service called\")\n        return true;\n    } catch (error) {\n        throw error;\n    }\n}    \n<%_ })_%>\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: middleware that checks authentication and authorization of user\n */\n\nconst { LOGIN_ACCESS,PLATFORM } = require('../constants/authConstant');\nconst responseHandler = require('../utils/response/responseHandler');\nconst { unAuthorized } = require('../utils/response');\n\n\nconst verifyCallback = (userTokensDb, req, resolve, reject, platform) => async (error, user, info) => {\n    if (error || info || !user) {\n        return reject(\"Unauthorized User\");\n    }\n    req.user = user;\n    if (!user.isActive) {\n        return reject(\"User is deactivated\");\n    }\n    let userToken = await userTokensDb.findOne({token:(req.headers.authorization).replace('Bearer ',''),userId:user.id});\n    if (!userToken){\n        return reject('Token not found');\n    }\n    if (userToken.isTokenExpired){\n        return reject('Token is Expired');\n    }\n    if (user.role) {\n        let allowedPlatforms = LOGIN_ACCESS[user.role] ? LOGIN_ACCESS[user.role] : [];\n        if (!allowedPlatforms.includes(platform)) {\n            return reject('Unauthorized user');\n        }\n    }\n    resolve();\n};\n\nconst auth = ({passport, userTokensDb}) => (platform) => async (req, res, next) => {\n<% var c = 0; %>\n    <% PLATFORM.forEach((v)=>{ c++;  %>\n        <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                return new Promise((resolve, reject) => {\n                    passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(userTokensDb,req, resolve, reject, platform))(\n                        req,\n                        res,\n                        next\n                    );\n                })\n                .then(() => next())\n                .catch((error) => {\n                    responseHandler(res,unAuthorized());\n                 });\n            }\n        <%_ }else{ _%>\n            else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                return new Promise((resolve, reject) => {\n                    passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(userTokensDb,req, resolve, reject, platform))(\n                        req,\n                        res,\n                        next\n                    );\n                })\n                .then(() => next())\n                .catch((error) => {\n                    responseHandler(res,unAuthorized())\n                 });\n            }\n        <%_ } _%> \n    <%  }) %>\n   \n};\n\nmodule.exports = auth;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/checkRolePermission.js.ejs",
    "content": "/**\n * checkRolePermission.js\n * @description :: middleware that checks access of APIs of logged-in user\n */\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\nconst db = require('mongoose');\n\nconst checkRolePermission = ({userRoleDb, routeRoleDb,projectRouteDb}) =>async (req, res, next) => {\n  if (!req.user) { \n    return responseHandler(res, response.unAuthorized());\n  }\n    const loggedInUserId = req.user.id;\n    let rolesOfUser = await userRoleDb.findMany({ userId: loggedInUserId, isActive: true, isDeleted: false }, {\n      roleId: 1,\n      _id: 0,\n    });\n\n    if (rolesOfUser && rolesOfUser.length) {\n      rolesOfUser = rolesOfUser.map((role) => db.Types.ObjectId(role.roleId));\n      const route = await projectRouteDb.findOne({\n        route_name: replaceAll((req.route.path.toLowerCase()).substring(1), '/', '_'),\n        uri: req.route.path.toLowerCase(),\n      });\n\n      if (route) { \n        const allowedRoute = await routeRoleDb.findMany({\n          routeId: route._id,\n          roleId: { $in: rolesOfUser },\n          isActive: true,\n          isDeleted: false,\n        });\n        if (allowedRoute && allowedRoute.length) {\n          next();\n        } else {\n          return responseHandler(res, response.unAuthorized());\n        }\n\n      }else{\n        next();\n      }\n    }else{\n      next();\n    } \n}\n\n\nfunction replaceAll(string, search, replace) {\n  return string.split(search).join(replace);\n};\n\nmodule.exports = checkRolePermission;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/index.js.ejs",
    "content": "let <%-USER_MODEL%>Db = require('../data-access/<%-USER_MODEL%>Db');\nlet userTokensDb = require('../data-access/userTokensDb');\nlet userRoleDb = require('../data-access/userRoleDb');\nlet routeRoleDb = require('../data-access/routeRoleDb');\nlet projectRouteDb = require('../data-access/projectRouteDb');\nconst passport = require('passport');\n\nconst auth = require('./auth')({ passport, userTokensDb });\nconst checkRolePermission = require('./checkRolePermission')({ userRoleDb, routeRoleDb,projectRouteDb});\n\n<%_for(let platform of PLATFORMS){_%>  \nconst <%-platform%>PassportStrategy = require('./<%-platform%>PassportStrategy')({ <%-USER_MODEL%>Db });\n<%_}_%>   \n\nmodule.exports = {\n  auth,\n  checkRolePermission,\n  <%_for(let platform of PLATFORMS){_%>  \n  <%-platform%>PassportStrategy,\n<%_}_%> \n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/loginUser.js.ejs",
    "content": "const jwt = require(\"jsonwebtoken\");\nconst response = require(\"../utils/response\");\nconst responseHandler = require(\"../utils/response/responseHandler\");\n<%_ PLATFORM.forEach((v)=>{ _%>\nconst <%-v%>Secret = require(\"../constants/authConstant\").JWT.<%-v.toUpperCase()%>_SECRET;\n<%_ }) _%>  \nconst {PLATFORM} = require(\"../constants/authConstant\");\n\nconst authenticateJWT = (platform) => (req, res, next) => {\n    const authHeader = req.headers.authorization;\n    if (authHeader) {\n        const token = authHeader.split(' ')[1];\n        let secret = '';\n        <%_ var c = 0; PLATFORM.forEach((v)=>{ c++;  _%>\n            <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>)){\n                secret = <%-v%>Secret;\n            }\n            <%_ }else{ _%>\n            else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                secret = <%-v%>Secret;\n            }\n            <%_ } _%> \n        <%_  }) _%>\n        jwt.verify(token,secret, (err, user) => {\n            if (err) {\n                responseHandler(res,response.unAuthorized());\n            }\n            req.user = user;\n            next();\n        });\n    } else {\n        responseHandler(res,response.unAuthorized());\n    }\n};\nmodule.exports = authenticateJWT"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/passport.js.ejs",
    "content": "\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\n\nconst <%- STRATEGY.toLowerCase() %>PassportStrategy = ({ userDb }) => async (passport) => {\n    const options = {};\n    options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); \n    options.secretOrKey = JWT.<%- STRATEGY.toUpperCase() %>_SECRET;\n\n    passport.use('<%- STRATEGY.toLowerCase() %>-rule',\n        new Strategy(options, async (payload, done) => {\n           try {\n            const user = await userDb.findOne({ _id: payload.id });\n              if (user) {\n                return done(null, { ...user.toJSON() });\n              }\n              return done('No User Found', {});\n            } catch (error) {\n              return done(error,{});\n            }\n        })\n    );\n}\nmodule.exports = <%- STRATEGY.toLowerCase() %>PassportStrategy;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/middleware/sampleMiddleware.js.ejs",
    "content": "<%_if(POLICY.code){_%>\n<%-POLICY.code%>\n<%_}else{_%>\nconst <%-POLICY.functionName%>=(req,res,next)=>{\n    try {\n        next();\n    } catch (error) {\n        throw error;\n    }\n}\n    \nmodule.exports=<%-POLICY.functionName%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/models/model.js.ejs",
    "content": "let mongoose = require('../connection');\nconst mongoosePaginate = require('mongoose-paginate-v2');\n<%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n    <%_if(typeof FLAG !== \"undefined\"){_%>    \n    const dayjs = require('dayjs');\n    <%_}_%>\n<%_}_%>   \nconst idvalidator = require('mongoose-id-validator');\n<%_ if(ATTRS_WITH_SEQ){ _%>\n    const autoIncrement = require('mongoose-sequence')(mongoose);\n<%_ } _%>\n<%_ if(DB_UNIQUE) { _%>\n    const uniqueValidator = require('mongoose-unique-validator');\n<%_ } _%>\n<%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH!==\"undefined\")){ _%>\n    <%_if(IS_AUTH && USER){_%>\n        const {convertObjectToEnum} = require(\"../../../utils/common\")\n        const{USER_ROLE} =  require(\"../../../constants/authConstant\");\n    <%_}_%>\n    <%_if(USER){_%>\n        const bcrypt = require(\"bcrypt\");\n    <%_}_%>\n<%_}_%>\n<%_if(MODEL_ENUM){_%>\n    <%_let a=[]_%>    \n    <%_for(let i in MODEL_ENUM){_%>\n        <%_for(let j in MODEL_ENUM[i]){_%>    \n            <%_if(typeof (MODEL_ENUM[i][j])==='object'){_%>\n                <%_if(!a.includes(MODEL_ENUM[i][j].enumFile)){_%>\n                    <%_a.push(MODEL_ENUM[i][j].enumFile)_%>\n                    const <%-MODEL_ENUM[i][j].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i][j].enumFile%>\")\n                <%_}_%>    \n            <%_}else{_%>\n                <%_if(!a.includes(MODEL_ENUM[i].enumFile)){_%>\n                    <%_a.push(MODEL_ENUM[i].enumFile)_%>\n                    const <%-MODEL_ENUM[i].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i].enumFile%>\")\n                <%_}_%>        \n            <%_}_%>        \n        <%_}_%>   \n    <%_}_%>\n<%_}_%>\nconst myCustomLabels = {\n    totalDocs: 'itemCount',\n    docs: 'data',\n    limit: 'perPage',\n    page: 'currentPage',\n    nextPage: 'next',\n    prevPage: 'prev',\n    totalPages: 'pageCount',\n    pagingCounter: 'slNo',\n    meta: 'paginator',\n};\nmongoosePaginate.paginate.options = {\n    customLabels: myCustomLabels\n};\nconst Schema = mongoose.Schema;\nconst schema = new Schema(\n    <%_ var model = DB_SCHEMA _%>\n    <%_ var modelArr = Object.keys(model)_%>\n    {\n        <%_ for(let v in model){ _%>\n            <%_if(COMMENT && COMMENT.attributeComment && COMMENT.attributeComment[v]){_%>\n                // <%-COMMENT.attributeComment[v].comment%>\n            <%_}else{_%>\n            <%_}_%>\n            <%_ let jsonStr = JSON.stringify(model[v]);\n            var finalStr = new String();\n            finalStr = jsonStr.toString().replace(/\"/g, \"\");\n            finalStr = finalStr.replace(/@@/g, '\"');\n            _%>\n            <%_ if(modelArr[modelArr.length-1]!==v){ _%>\n                <%-v%>:<%-finalStr%>,\n            <%_}else{_%>\n                <%-v%>:<%-finalStr%>\n            <%_ } _%>\n        <%_ } _%>\n    },\n    { timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } }\n);\n<%_ if(ATTRS_WITH_SEQ){\n    for(const [attributeName, value] of Object.entries(ATTRS_WITH_SEQ) ){\n        if(value.isAutoIncrement){ _%>\n            schema.plugin(autoIncrement, {\n                inc_field: \"<%-attributeName%>\",\n                id:\"<%-DB_MODEL%>_<%-attributeName%>_sequence\",\n                inc_amount: 1, \n                start_seq: 1,\n                prefix: \"\",\n                suffix: \"\",\n                length: 6\n            });\n        <%_}\n    } \n} _%>\n<%_if(INDEXES && INDEXES.length){_%>\n    <%_for(const index of INDEXES){ _%>\n        <%_if(index.indexFields && JSON.stringify(index.indexFields)!=='{}'){ _%>\n            schema.index(<%-JSON.stringify(index.indexFields)%><%_if(index.options && JSON.stringify(index.options)!=='{}'){_%>,<%-JSON.stringify(index.options)%><%_}_%>)\n        <%_}\n    }_%>\n<%_}_%>      \n<%_if(VIRTUAL_RELATION && VIRTUAL_RELATION.length>0){_%>\n    <%_for(const VIRTUAL_REL of VIRTUAL_RELATION){ _%>\n    schema.virtual(<%= VIRTUAL_REL.fieldName %>, {\n        ref: <%= VIRTUAL_REL.ref %>,\n        localField: <%= VIRTUAL_REL.localField %>,\n        foreignField: <%= VIRTUAL_REL.foreignField %>,\n        justOne: <%= VIRTUAL_REL.justOne %>\n    });\n<%_}\n}\n_%>\n<%_if(HOOKS!=='null' && HOOKS){_%>\n<%_if(HOOKS['pre']!==undefined){_%>   \n<%HOOKS['pre'].forEach(function (variable) { -%>\n<%_if(variable['operation']!=='init'){_%>\nschema.pre('<%-variable['operation']%>',async function(next){\n    <%-variable['code']%>\n    next();\n});\n<%_}else{_%>\nschema.pre('init',async function(docs,next){\n    <%-variable['code']%>\n});\n<%_}_%>        \n<% }); -%>\n        \n<%_}if(HOOKS['post']!==undefined){_%>   \n<%HOOKS['post'].forEach(function (variable) { -%>\n<%_if(variable['operation']!=='init'){_%>\nschema.post('<%-variable['operation']%>',async function(docs,next){\n    <%-variable['code']%>\n    next();\n});\n<%_}else{_%>\nschema.post('init',async function(docs,next){\n    <%-variable['code']%>\n});\n<%_}_%>\n<% }); -%>    \n<%_}_%>\n<%_}_%>\n    \nschema.pre('save', async function(next) {\n    this.isDeleted = false;\n    this.isActive = true;\n    <%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH!==\"undefined\") && (USER && IS_AUTH)){ _%>\n    if(this.<%-PASSWORD%>){\n        this.<%-PASSWORD%> = await bcrypt.hash(this.<%-PASSWORD%>, 8);\n    }\n    <%_ } _%>\n    next();\n});\n\nschema.pre('insertMany', async function (next, docs) {\n  if (docs && docs.length){\n    for (let index = 0; index < docs.length; index++) {\n      const element = docs[index];\n      element.isDeleted = false;\n      element.isActive = true;\n    }\n  }\n  next();\n});\n\n<%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH!==\"undefined\") && (USER && IS_AUTH)){ %>\nschema.methods.isPasswordMatch = async function (password) {\n    const user = this;\n    return bcrypt.compare(password, user.<%-PASSWORD%>);\n};\n<%_ } _%>\nschema.method(\"toJSON\", function () {\n    const { _id, __v, ...object } = this.toObject({virtuals:true});\n    object.id = _id;\n    <%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n    <%_for(index of CONCAT_HOOK){_%>\n    <%_for(formateIndex in index){_%>\n    <%_if(typeof (index[formateIndex])==='object'){_%>\n    if(object.<%-formateIndex%>){\n        object.<%-formateIndex%>=<%=index[formateIndex].true%>;\n    }else{\n        object.<%-formateIndex%>=<%=index[formateIndex].false%>;\n    }\n    <%_}else{_%> \n    <%_if(index[formateIndex].includes('concat')){_%>\n    if(object.<%-STRING_ATT[0]%> && object.<%-STRING_ATT[1]%>){\n        object.<%-formateIndex%>=<%-index[formateIndex]%>;\n    }\n    <%STRING_ATT.shift()%>\n    <%STRING_ATT.shift()%>\n    <%_}else{_%>        \n    object.<%-formateIndex%>=<%-index[formateIndex]%>;\n    <%_}_%>\n    <%_}_%>\n    <%_}_%>   \n    <%_}_%>   \n    <%_}_%>     \n    <%_if(IS_PRIVATE_ATTR !== null && IS_PRIVATE_ATTR === true) {_%>\n        <%_if(PRIVATE_ATTRS !== null && PRIVATE_ATTRS) {_%>\n            <%_Object.keys(PRIVATE_ATTRS).map((t) => {_%>            \n                <%_if(PRIVATE_ATTRS[t]) {_%>            \n                    delete object.<%-t%>\n                <%_}_%>        \n            <%_});_%>        \n        <%_}_%>    \n    <%_}_%>\n    <%_if(IS_PRIVATE_ARRAY_PROPERTY !== null && IS_PRIVATE_ARRAY_PROPERTY === true) {_%>\n        <%_if(ARRAY_PRIVATE_PROPERTY !== null && ARRAY_PRIVATE_PROPERTY) {_%>\n            <%_if(Object.keys(ARRAY_PRIVATE_PROPERTY).length > 0) {_%>\n                <%_Object.keys(ARRAY_PRIVATE_PROPERTY).map((k) => {_%>\n                    if (object.<%-k%>.length > 0){\n                        let _<%-k%> = object.<%-k%>.filter(data => {\n                            delete data.<%-ARRAY_PRIVATE_PROPERTY[k]%>;\n                            return data;\n                        });\n                        object.<%-k%> = _<%-k%>;\n                    }\n                <%_});_%>\n            <%_}_%>    \n        <%_}_%>\n    <%_}_%>\n    return object;\n});\nschema.plugin(mongoosePaginate);\nschema.plugin(idvalidator);\n\n<%if (DB_UNIQUE) { %>\nschema.plugin(uniqueValidator);\n<% } %>\n\nconst <%-DB_MODEL %> = mongoose.model(\"<%- DB_MODEL %>\",schema,\"<%- DB_MODEL %>\");\nmodule.exports = <%-DB_MODEL %>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/auth.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\n<%_if(SOCIAL_PLATFORMS.length){ _%>\nconst session = require('express-session');\n<%_}_%>\nconst {auth} = require('../../middleware');\nconst authController = require(\"../../controller/<%-PLATFORM%>/authentication\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\nrouter.post(\"/register\",authController.register);\nrouter.post('/login',authController.authentication);\nrouter.post(\"/forgot-password\",authController.forgotPassword);\nrouter.post(\"/validate-otp\",authController.validateResetPasswordOtp);\nrouter.put(\"/reset-password\",authController.resetPassword);\n<%_if(SOCIAL_PLATFORMS.length) { \n  SOCIAL_PLATFORMS.forEach(s=>{ _%>\nrouter.get(\"/<%-s.toLowerCase()%>\",(req,res)=>{\nreq.session.platform = <%=PLATFORM%>\nres.redirect(`http://localhost:${process.env.PORT}/auth/<%-s.toLowerCase()%>`);\n})\n<%_})_%>\n<%_}_%>\nrouter.post('/logout',auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),authController.logout);\n  \nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/commonIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n\n<%_PLATFORM.forEach((p) =>{ _%>\nrouter.use(require(\"./<%-p%>Routes\"));\n<%_ }) _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/index.js.ejs",
    "content": "const express = require(\"express\")\nconst router =  express.Router()\n<%_ if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimit=require('express-rate-limit');\n<%_ } _%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimiter=rateLimit({\n    windowMs:<%-REACTIVE_TIME%> *60 *1000,\n    max:<%-LOGIN_RATE%>,\n    message: \"Rate limit exceeded, please try again after <%=REACTIVE_TIME%> minutes\"\n});\n<%_}_%>\n\n<%_for(let module in PLATFORM){_%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nrouter.use(rateLimiter,require(\"./<%-module%>/index\"));  \n<%_} else {_%> \nrouter.use(require(\"./<%-module%>/index\"));\n<%_}_%>\n<%_}_%>\n\nmodule.exports =router\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/modelRoutes.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\nconst <%-DB_MODEL%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-DB_MODEL%>\");\n<%_ if(CONTROLLERS_TO_IMPORT && CONTROLLERS_TO_IMPORT.length){ _%>\n<%_ for(let i=0;i < CONTROLLERS_TO_IMPORT.length;i++){ \n    if(CONTROLLERS_TO_IMPORT[i] != DB_MODEL){ _%>\nconst <%-CONTROLLERS_TO_IMPORT[i]-%>Controller = require('../../controller/<%-CONTROLLERS_TO_IMPORT[i]-%>');\n<%_ } }_%>\n<%_ } _%>\n<%_ if(CUSTOM_POLICY.length){ \n    if(CUSTOM_POLICY.includes('auth')){ let arrayIndex = CUSTOM_POLICY.indexOf('auth'); delete CUSTOM_POLICY[arrayIndex]; CUSTOM_POLICY =  CUSTOM_POLICY.filter(Boolean);}\n_%><%_ } _%>\n<%_ if(IS_AUTH){ _%>\nconst {auth, <%_for(let i=0;i < CUSTOM_POLICY.length;i++){_%><%-CUSTOM_POLICY[i]-%>,<%_}_%> } = require(\"../../middleware\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\"); \n<%_ }else{ _%>\n<%_ for(let i=0;i < CUSTOM_POLICY.length;i++){ _%>\nconst <%-CUSTOM_POLICY[i]-%> = require('../../middleware/<%-CUSTOM_POLICY[i]-%>');\n<%_ } _%> <%_ } _%> \n\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/me').get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.getLoggedInUserInfo);\n<%_ } _%>\n<%_ } _%>\n<%_ for(let i=0; i < SUPPORT_API.length; i++){ _%>\n<%_ if(SUPPORT_API[i].method==\"create\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/create').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/create').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/addBulk').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/addBulk').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\") {_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/list').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/list').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/:id').get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/:id').get(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"count\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){  _%>\nrouter.route('/<%-ROUTE_PREFIX%>/count').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/count').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ } _%><%_ } _%>\n<%_if(SUPPORT_API[i].method==\"update\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){  _%>\nrouter.route('/<%-ROUTE_PREFIX%>/update/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)   \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/update/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)  \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"partialUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/partial-update/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)   \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/partial-update/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)  \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"bulkUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/updateBulk').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>) \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/updateBulk').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"delete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/delete/:id').delete(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/delete/:id').delete(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"deleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/deleteMany').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/deleteMany').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDelete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){  _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDelete/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDelete/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDeleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDeleteMany').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDeleteMany').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_}_%>\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/change-password').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.changePassword);\nrouter.route('/<%-ROUTE_PREFIX%>/update-profile').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.updateProfile);\n<%_ } _%>\n<%_ } _%>\n<%_if(CUSTOM_ROUTES && CUSTOM_ROUTES.length){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n<%_}else{_%>\n<%-policy%>,<%_}_%>\n<%_})_%>\n<%_}_%><%-v.controller%>Controller.<%-v.functionName%>)\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/platformIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n<%_ if(IS_AUTH){ _%>\nrouter.use(\"/<%-PLATFORM_NAME.toLowerCase()%>/auth\",require(\"./auth\"));\n<%_ } _%>\n<%_ for(let i in PLATFORM){ _%>\nrouter.use(require(\"./<%-i%>Routes\"));\n<%_}_%>  \n<%_if(typeof ROUTES!==\"undefined\"){_%>\n<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.controller%>Routes\"));\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/routes/uploadRoutes.js.ejs",
    "content": "let express = require('express');\nlet router = express.Router();\nconst fileUploadController = require(\"../../controller/<%-PLATFORM%>/fileUpload\");\n<%_ if(IS_AUTH){ _%>\nconst auth = require(\"../../middleware/auth\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");  \n<%_ } _%>\n\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/upload\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.upload);\n<%_ }else{ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/upload\").post(fileUploadController.upload);\n<%_ } _%>\n<%_ if(S3_UPLOAD_PRIVATE){_%>\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.generatePreSignedURL);\n<%_ }else{ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\").post(fileUploadController.generatePreSignedURL);\n<%_ } _%>\n<%_ } _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/seeders/index.js.ejs",
    "content": "<%_if(IS_AUTH){_%>\n  const bcrypt = require('bcrypt')\n  const authConstant=require('../constants/authConstant');\n  const <%-AUTH_MODEL%>Db = require('../data-access/<%-AUTH_MODEL%>Db');\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    <%_for(const model of ROLE_PERMISSION_MODELS){ _%>\n      const <%-model%>Db = require('../data-access/<%-model%>Db');\n    <%_}_%>\n  <%_}_%>\n<%_}_%>\nconst { replaceAll } = require('../utils/common');\n\n<%_if(IS_AUTH){_%>\n  async function seedUser() {\n    try{\n      let userToBeInserted = {}\n      <%_for(let i in USER_EXIST_CONDITION){_%>\n        <%_var finalStr = new String();\n        USER[i].role=`@@authConstant.USER_ROLE.${ROLE_NAME[i]}@@`;\n        finalStr = JSON.stringify(USER[i]);\n        finalStr = finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\");\n        _%>\n        userToBeInserted = <%-finalStr%>\n        userToBeInserted.<%-PASSWORD_FIELD%> = await bcrypt.hash(userToBeInserted.<%-PASSWORD_FIELD%>, 8)\n        let <%-ROLE_NAME[i].toLowerCase()%> = await <%-AUTH_MODEL%>Db.upsert( <%-JSON.stringify(USER_EXIST_CONDITION[i])%>, userToBeInserted,  {\n          upsert: true,\n          new: true\n        })\n      <%_}_%>\n      console.info('Users seeded 🍺');\n    } catch(error){\n      console.log('User seeder failed due to ', error.message)\n    }\n  }\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    async function seedRole() {\n      try {\n        const roles = <%=ROLES%>;\n        const insertedRoles = await roleDb.findMany({ code: { '$in': roles.map(role => role.toUpperCase()) } });\n        const rolesToInsert = [];\n        roles.forEach(role => {\n          if (!insertedRoles.find(insertedRole => insertedRole.code === role.toUpperCase())) {\n            rolesToInsert.push({\n              name: role,\n              code: role.toUpperCase(),\n              weight: 1\n            });\n          }\n        });\n        if (rolesToInsert.length) {\n          const result = await roleDb.createMany(rolesToInsert);\n          if (result) console.log('Role seeded 🍺');\n          else console.log('Role seeder failed!');\n        } else {\n          console.log('Role is up to date 🍺');\n        }\n      } catch (error) {\n        console.log('Role seeder failed due to ', error.message);\n      }\n    }\n\n    async function seedProjectRoutes(routes) {\n      try {\n        if (routes && routes.length) {\n          let routeName = '';\n          const dbRoutes = await projectRouteDb.findMany({});\n          let routeArr = [];\n          let routeObj = {};\n          routes.forEach(route => {\n            routeName = `${replaceAll((route.path).toLowerCase(), '/', '_')}`;\n            route.methods.forEach(method => {\n              routeObj = dbRoutes.find(dbRoute => dbRoute.route_name === routeName && dbRoute.method === method);\n              if (!routeObj) {\n                routeArr.push({\n                  'uri': route.path.toLowerCase(),\n                  'method': method,\n                  'route_name': routeName,\n                });\n              }\n            });\n          });\n          if (routeArr.length) {\n            const result = await projectRouteDb.createMany(routeArr);\n            if (result) console.info('ProjectRoute model seeded 🍺');\n            else console.info('ProjectRoute seeder failed.');\n          } else {\n            console.info('ProjectRoute is up to date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('ProjectRoute seeder failed due to ', error.message);\n      }\n    }\n\n    async function seedRouteRole() {\n      try{\n        const routeRoles =[ \n          <%_for(let i=0;i<ROUTE_ROLE_ARRAY.length;i++){_%>\n          <%=ROUTE_ROLE_ARRAY[i]%>,\n          <%_}_%>\n\n        ];\n        if (routeRoles && routeRoles.length) {\n          const routes = [...new Set(routeRoles.map(routeRole => routeRole.route.toLowerCase()))];\n          const routeMethods = [...new Set(routeRoles.map(routeRole => routeRole.method))];\n          const roles = <%=ROLES%>;\n          const insertedProjectRoute = await projectRouteDb.findMany({\n            uri: { '$in': routes },\n            method: { '$in': routeMethods },\n            'isActive': true,\n            'isDeleted': false\n          });\n          const insertedRoles = await roleDb.findMany({\n            code: { '$in': roles.map(role => role.toUpperCase()) },\n            'isActive': true,\n            'isDeleted': false\n          });\n          let projectRouteId = '';\n          let roleId = '';\n          let createRouteRoles = routeRoles.map(routeRole => {\n            projectRouteId = insertedProjectRoute.find(pr => pr.uri === routeRole.route.toLowerCase() && pr.method === routeRole.method);\n            roleId = insertedRoles.find(r => r.code === routeRole.role.toUpperCase());\n            if (projectRouteId && roleId) {\n              return {\n                roleId: roleId.id,\n                routeId: projectRouteId.id\n              };\n            }\n          });\n          createRouteRoles = createRouteRoles.filter(Boolean);\n          const routeRolesToBeInserted = [];\n          let routeRoleObj = {};\n\n          await Promise.all(\n            createRouteRoles.map(async routeRole => {\n              routeRoleObj = await routeRoleDb.findOne({\n                routeId: routeRole.routeId,\n                roleId: routeRole.roleId,\n              });\n              if (!routeRoleObj) {\n                routeRolesToBeInserted.push({\n                  routeId: routeRole.routeId,\n                  roleId: routeRole.roleId,\n                });\n              }\n            })\n          );\n          if (routeRolesToBeInserted.length) {\n            const result = await routeRoleDb.createMany(routeRolesToBeInserted);\n            if (result) console.log('RouteRole seeded 🍺');\n            else console.log('RouteRole seeder failed!');\n          } else {\n            console.log('RouteRole is up to date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('RouteRole seeder failed due to ', error.message)\n      }\n    }\n\n    async function seedUserRole () {\n      try {\n        const userRoles = <%-JSON.stringify(USER_ROLE_ARRAY)%>;\n        const defaultRole = await roleDb.findOne({ code: <%=DEFAULT_ROLE%> });\n        const insertedUsers = await <%-AUTH_MODEL%>Db.findMany( { username: { '$in': userRoles.map(userRole => userRole.username) } });\n        let user = {};\n        const userRolesArr = [];\n        userRoles.map(userRole => {\n          user = insertedUsers.find(user => user.username === userRole.username && user.isPasswordMatch(userRole.password) && user.isActive && !user.isDeleted);\n          if (user) {\n            userRolesArr.push({\n              userId: user.id,\n              roleId: defaultRole.id\n            });\n          }\n        });\n        let userRoleObj = {};\n        const userRolesToBeInserted = [];\n        if (userRolesArr.length) {\n          await Promise.all(\n            userRolesArr.map(async userRole => {\n              userRoleObj = await userRoleDb.findOne({\n                userId: userRole.userId,\n                roleId: userRole.roleId\n              });\n              if (!userRoleObj) {\n                userRolesToBeInserted.push({\n                  userId: userRole.userId,\n                  roleId: userRole.roleId\n                });\n              }\n            })\n          );\n          if (userRolesToBeInserted.length) {\n            const result = await userRoleDb.createMany(userRolesToBeInserted);\n            if (result) console.log('UserRole seeded 🍺');\n            else console.log('UserRole seeder failed');\n          } else {\n            console.log('UserRole is up to date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('UserRole seeder failed due to ', error.message);\n      }\n    }\n  <%_}_%>\n<%_}_%>\n\nconst seedData = async (<%_if(IS_AUTH){_%>allRegisterRoutes<%_}_%>) => {\n<%_if(IS_AUTH){_%>\n  await seedUser();\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    await seedRole();\n    await seedProjectRoutes(allRegisterRoutes);\n    await seedRouteRole();\n    await seedUserRole();\n  <%_}_%>\n<%_}_%>\n}\nmodule.exports = seedData;\n\n\n\n\n\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/services/auth.js.ejs",
    "content": "const { JWT,LOGIN_ACCESS,\n    PLATFORM<%_if(LOGIN_RETRY_LIMIT){_%>,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME<%_}_%>\n    <%_if(RESET_PASSWORD){_%>,FORGOT_PASSWORD_WITH<%_}_%>\n    <%_if(MAX_DEVICE_ALLOWED){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\");\nconst jwt = require(\"jsonwebtoken\");\nconst common = require(\"../utils/common\");\nconst dayjs = require(\"dayjs\");\nconst emailService = require(\"./email/emailService\");\nconst smsService = require(\"./sms/smsService\");\n<%_if(FORGOT_WITH_LINK){_%>\nconst uuid = require(\"uuid\").v4;\n<%_}_%>\nconst bcrypt = require(\"bcrypt\");\n<%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS'){_%>\nconst ejs = require(\"ejs\");\n<%_}_%>\n\nasync function generateToken(user,secret){\n    return jwt.sign( {id:user.id,'<%-LOGIN_WITH[0]%>':user.<%-LOGIN_WITH[0]%>}, secret, {\n        expiresIn: JWT.EXPIRES_IN\n    });\n}\n\nfunction makeAuthService({model,<%-MODEL%>Service,userTokenService<%_if(ROLE_PERMISSION){_%>,userRoleService,routeRoleService<%_}_%>}) {\n    const loginUser = async(username,password,url<%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n        try {\n            <%_ if(LOGIN_WITH.length>1){ _%>\n            let where = <%-MULTIPLE_LOGIN%>\n            <%_ }else{_%>\n            let where ={'<%-LOGIN_WITH[0]%>':username}\n            <%_}_%>\n            let user = await model.findOne(where);\n            if (user) {\n                <%_if(MAX_DEVICE_ALLOWED){_%>\n                const userToken = await userTokenService.countDocument({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n                if(userToken >= NO_OF_DEVICE_ALLOWED){\n                    return {\n                        flag: true,\n                        data: \"You've reached your device limit\"\n                    }\n                }\n                <%_}_%>\n                <%_if(LOGIN_RETRY_LIMIT){_%>\n                if(user.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT){\n                    let now = dayjs();\n                    if (user.loginReactiveTime){\n                        let limitTime = dayjs(user.loginReactiveTime);\n                        if (limitTime > now){\n                          let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                          if (!(limitTime > expireTime)){\n                            return {\n                              flag:true,\n                              data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,limitTime)}.`\n                            }; \n                          }   \n                          await <%-MODEL%>Service.updateDocument(user.id,{\n                            loginReactiveTime:expireTime.toISOString(),\n                            <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1  \n                          });\n                          return {\n                            flag:true,\n                            data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                          }; \n                        }else {\n                            user = await <%-MODEL%>Service.findOneAndUpdateDocument({ _id:user.id },{\n                              loginReactiveTime:'',\n                              <%-LOGIN_RETRY_LIMIT.key%>:0\n                            },{ new:true });\n                        }\n                    } else {\n                        // send error\n                        let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                        await <%-MODEL%>Service.updateDocument(user.id,{\n                          loginReactiveTime:expireTime.toISOString(),\n                          <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1 \n                        });\n                        return {\n                          flag:true,\n                          data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                        }; \n                    } \n                }\n                <%_}_%>\n                const isPasswordMatched = await user.isPasswordMatch(password);\n                if (isPasswordMatched) {\n                    const userData=user.toJSON()\n                    let token;\n                    if (!user.role) {\n                        return {flag:true,data:\"You have not been assigned role.\"}\n                    }\n                    <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n                        <%_if(i===0){_%>\n                        if(url.includes('<%-PLATFORMS[i].toLowerCase()%>')){\n                            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                return {flag:true, data:'you are unable to access this platform'}\n                            }\n                            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                        }\n                        <%_}else{_%>\n                        else if(url.includes('<%-PLATFORMS[i].toLowerCase()%>')){\n                            if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                return {flag:true, data:'you are unable to access this platform'}\n                            }\n                            token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                        }\n                        <%_}_%>\n                    <%_}_%> \n                    <%_if(LOGIN_RETRY_LIMIT){_%>\n                    if(user.<%-LOGIN_RETRY_LIMIT.key%>){\n                        await <%-MODEL%>Service.updateDocument(user.id,{<%-LOGIN_RETRY_LIMIT.key%>:0,loginReactiveTime:''});\n                    }\n                    <%_}_%>\n                    let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n                    await userTokenService.createDocument({ userId: user.id, token: token,tokenExpiredTime: expire });                  \n                    let userToReturn = { ...userData, token };\n                    <%_if(ROLE_PERMISSION){_%>\n                    let roleAccessData = {};\n                    if (roleAccess){\n                        roleAccessData = await common.getRoleAccessData(userRoleService,routeRoleService,user.id);\n                        userToReturn = {\n                            ...userToReturn,\n                            roleAccess: roleAccessData\n                        };\n                    }\n                    <%_}_%>\n                    return {flag:false,data:userToReturn};\n                } else {\n                    <%_if(LOGIN_RETRY_LIMIT){_%>\n                    await <%-MODEL%>Service.updateDocument(user.id,{<%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                    <%_}_%>\n                    return {flag:true,data:\"incorrect password\"}\n                }\n            } else {\n                return {flag:true,data:\"User not exists\"}\n            }\n        } catch (error) {\n            throw new Error(error)\n        }\n    }\n    const changePassword = async (params) => {\n        try {\n            let password = params.newPassword;\n            let oldPassword = params.oldPassword;\n            let user = await <%-MODEL%>Service.getSingleDocumentById(params.userId);\n            if (user && user.id) {\n                let isPasswordMatch = await user.isPasswordMatch(oldPassword);\n                if(!isPasswordMatch){\n                    return {\n                        flag:true,\n                        data:'Incorrect old password'\n                    }\n                }\n                password = await bcrypt.hash(password, 8);\n                let updatedUser = <%-MODEL%>Service.updateDocument(user.id, { <%-PASSWORD%>:password });\n                if (updatedUser) {\n                    return {flag:false,data:'Password changed successfully.'};\n                }\n                return {flag:true,data:'Password not updated'};\n            }\n            return {flag:true,data:'User not found'};\n        } catch (error) {\n            throw new Error(error)\n        }\n    }\n\n    const sendResetPasswordNotification = async (user) => {\n        let resultOfEmail = false;\n        let resultOfSMS = false;\n        try {\n            <%_if(FORGOT_WITH_LINK){_%>\n            let token = uuid();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRETIME, \"minute\").toISOString();\n            await <%-MODEL%>Service.updateDocument(user.id,\n                { resetPasswordLink: { code: token, expireTime: expires } });\n            if(FORGOT_PASSWORD_WITH.LINK.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME &&  RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({_id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                };\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:updatedUser\n                };\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = \"Click on the link below to reset your password.\";\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/resetPassword\",\n                    data: {\n                        link: `http://localhost:${process.env.PORT}` + viewType + token,\n                        linkText: \"Reset Password\",\n                        message:msg\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail  = true;\n                }catch(error){\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.LINK.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE ==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({_id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                \n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = `Click on the link to reset your password.\n                http://localhost:${process.env.PORT}${viewType + token}`;\n                let smsObj = {\n                    to:user.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            <%_if(FORGOT_WITH_OTP){_%>\n            let otp = common.randomNumber();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRETIME, \"minute\").toISOString();\n            await <%-MODEL%>Service.updateDocument(user.id, { resetPasswordLink: { code: otp, expireTime: expires } });\n            if(FORGOT_PASSWORD_WITH.OTP.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({_id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>',    \n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                };\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>',\n                    data:updatedUser\n                };\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/resetPassword',\n                    data: {\n                        isWidth: true,\n                        name: \"username\",\n                        email: user.<%-EMAIL_FIELD%> || '-',\n                        message: otpMsg,\n                        otp: otp\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail  = true;\n                }catch(error){\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.OTP.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({_id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let smsObj = {\n                    message: otpMsg,\n                    to: user.<%-MOBILE_FIELD%>,\n                };\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            return { resultOfEmail, resultOfSMS };\n        } catch (error) {\n            console.log(error);\n            throw new Error(error);\n        }\n    }\n    \n    const resetPassword = async (user, newPassword) => {\n        try {\n            let where = { _id: user.id };   \n            const dbUser = await <%-MODEL%>Service.getSingleDocumentByQuery(where);\n            if (!dbUser) {\n                return {\n                    flag: true,\n                    data: \"user not found\",\n                };\n            }\n            newPassword = await bcrypt.hash(newPassword, 8);\n            await <%-MODEL%>Service.updateDocument(user.id, {\n                <%-PASSWORD%>: newPassword,\n                resetPasswordLink: null,\n                <%_if(LOGIN_RETRY_LIMIT){_%>\n                <%-LOGIN_RETRY_LIMIT.key%>:0\n                <%_}_%>\n            });\n            let mailObj = {\n                subject: 'Reset Password',\n                to: user.<%-EMAIL_FIELD%>,\n                template: '/views/successfullyResetPassword',\n                data: {\n                    isWidth: true,\n                    email: user.<%-EMAIL_FIELD%> || '-',\n                    message: \"Password Successfully Reset\"\n                }\n            };\n            await emailService.sendMail(mailObj);\n            return {\n                flag: false,\n                data: \"Password reset successfully\",\n            };\n        } catch (error) {\n            throw new Error(error)\n        }\n    }\n    return Object.freeze({\n        loginUser,\n        changePassword,\n        resetPassword,\n        sendResetPasswordNotification,\n    })\n}\n\nmodule.exports = makeAuthService;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/services/customQueryService.js.ejs",
    "content": "function makeMongoCustomQueryService(model){\n  const find = async ( { filter = {}, populate, skip, limit, select, sort }) => {\n    let query = model.find(filter)\n    if (select) {\n        query = query.select(select)\n    }\n    if (populate) {\n        query = query.populate(populate)\n    }\n    if (skip) {\n        query = query.skip(skip)\n    }\n    if (limit) {\n        query = query.limit(limit)\n    }\n    if (sort) {\n        query = query.sort(sort)\n    }\n    return await query.exec()\n  }\n  const create = async(data,options={})=>{\n    try {\n        if(data && data.length){\n            return await model.create(data,options)\n        }else{\n            return await model.create([data],options)\n        }\n    } catch (error) {\n        throw new Error(error.message)\n    }\n  }\n  const findOneAndUpdate = async(filter,data,options={new:true})=>{\n    try {\n        return await model.findOneAndUpdate(filter,data,options)        \n    } catch (error) {\n        throw new Error(error.message)\n    }\n  }\n  const findOneAndDelete = async(filter,options={})=>{\n    try {\n        return await model.findOneAndDelete(filter,options)        \n    } catch (error) {\n        throw new Error(error.message)\n    }\n  }\n  const updateMany = async(filter,data,options={})=>{\n    try {\n        const documentsToBeUpdate=await model.find(filter)\n        await model.updateMany(filter,data,options)    \n        return documentsToBeUpdate\n    } catch (error) {\n        throw new Error(error.message)\n    }\n  }\n  const deleteMany = async(filter,options={})=>{\n    try {\n        const documentsToBeDelete=await model.find(filter)\n        await model.deleteMany(filter,options)\n        return documentsToBeDelete\n    } catch (error) {\n        throw new Error(error.message)\n    }\n  }\n  const aggregate = async(queries)=>{\n        try {\n            return await model.aggregate(queries)\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n  return Object.freeze({\n    find,\n    findOneAndUpdate,\n    findOneAndDelete,\n    updateMany,\n    deleteMany,\n    create, \n    aggregate,   \n  })\n}\n\nmodule.exports = makeMongoCustomQueryService\n\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/services/emailService.js.ejs",
    "content": "const nodemailer = require('nodemailer');\nconst ejs = require(\"ejs\")\nmodule.exports = {\n    sendMail: async (obj) => {\n        let transporter = nodemailer.createTransport({\n            service: 'Mailgun',\n            auth: {\n                user: '',\n                pass: ''\n            }\n        });\n        if (!Array.isArray(obj.to)) {\n            obj.to = [obj.to];\n        }\n        const htmlText = await ejs.renderFile(`${__basedir}${obj.template}/html.ejs`, obj.data);\n\n        return await Promise.all(obj.to.map((emailId) => {\n            var mailOpts = {\n                from: obj.from || \"noreply@yoyo.co\",\n                to: emailId,\n                subject: obj.subject,\n                html: htmlText\n            };\n            transporter.sendMail(mailOpts, function (err, response) {\n                if (err) {\n                    //ret.message = \"Mail error.\";\n                } else {\n                    //ret.message = \"Mail send.\";\n                }\n            });\n        }));\n    }\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/services/fileUpload.js.ejs",
    "content": "const fs = require('fs');\nconst path = require('path');\n<%_if(S3_UPLOAD){_%>\n  const AWS = require('aws-sdk');\n  <%_if(S3_UPLOAD_PRIVATE){_%>\n    const AmazonS3URI = require('amazon-s3-uri');\n  <%_}_%> \n<%_}_%>\nconst makeDirectory = require('../../utils/makeDirectory');\n\n<%_if(S3_UPLOAD){_%>\n  let S3Config = {\n    AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n    AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n    AWS_S3_REGION: process.env.AWS_S3_REGION,\n    AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n  };\n<%_}_%>\n<%_if(LOCAL_UPLOAD){_%>\n  /**\n  * \n  * Function used to upload file in local storage.\n  * \n  * @param   {object}    file\n  * @param   {object}    fields\n  * @param   {integer}   fileCount\n  * @param   {array}     allowedFileTypes\n  * @param   {integer}   maxFileSize\n  * @param   {string}    defaultDirectory\n  * @returns {object}    { status, message, data}\n  * \n  */\n  async function uploadFilesOnLocalServer(file, fields, fileCount, allowedFileTypes, maxFileSize, defaultDirectory) {\n\n    let tempPath = file.path;\n\n    let extension = path.extname(file.name);\n    extension = extension.split('.').pop();\n\n    fileType = file.type; uploadFilesOnLocalServer;\n\n    //Check allowed extension;\n    if (allowedFileTypes.length) {\n      if (!allowedFileTypes.includes(extension)) {\n        return {\n          status: false,\n          message: 'Filetype not allowed.'\n        };\n      }\n    }\n\n    //Check File Size\n    const fileSize = ((file.size / 1024) / 1024);\n    if (maxFileSize < fileSize) {\n      return {\n        status: false,\n        message: `Allow file size upto ${maxFileSize} MB.`\n      };\n    }\n\n    //Create Directory if not exist.\n    await makeDirectory(defaultDirectory);\n\n    //Create New path\n    let newPath = defaultDirectory + '/' + new Date().getTime() + path.extname(file.name);\n\n    //Create requested directory,if given in request parameter.\n    if (fields && fields.folderName) {\n      let newDir = defaultDirectory + '/' + fields.folderName;\n\n      await makeDirectory(newDir);\n\n      if (fields.fileName) {\n        newPath = newDir + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n        fileName = fields.fileName;\n      }\n    } else if (fields && fields.fileName) {\n      newPath = defaultDirectory + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n      fileName = fields.fileName;\n    }\n\n    let data = fs.readFileSync(tempPath);\n    fs.writeFileSync(newPath, data);\n    fs.unlinkSync(tempPath);\n\n    return {\n      status: true,\n      message: 'File upload successfully.',\n      data: '/' + newPath\n    };\n  }\n<%_}_%>\n<%_if(S3_UPLOAD){_%>\n  async function uploadFilesOnS3(file, fields, fileCount, allowedFileTypes, maxFileSize) {\n    let extension = path.extname(file.name);\n    extension = extension.split('.').pop();\n\n    fileType = file.type;\n\n    if (allowedFileTypes.length) {\n      //Check allowed extension;\n      if (!allowedFileTypes.includes(extension)) {\n        return {\n          status: false,\n          message: 'Filetype not allowed.'\n        };\n      }\n    }\n\n    // Check File Size\n    const fileSize = ((file.size / 1024) / 1024);\n    if (maxFileSize < fileSize) {\n      return {\n        status: false,\n        message: `Allow file size upto ${maxFileSize} MB.`\n      };\n    }\n\n    let fileName = file.name;\n    //Create Requested Directory,if given in request parameter.\n    if (fields && fields.folderName) {\n      fileName = fields.folderName + '/' + fileName;\n    }\n    else if (fields && fields.fileName) {\n      fileName = fields.fileName + '-' + fileCount + path.extname(file.name);\n    }\n\n    const s3 = new AWS.S3({\n      region: S3Config.AWS_S3_REGION,\n      accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n      secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n    });\n\n    let params = {\n      Bucket: S3Config.AWS_S3_BUCKET_NAME,\n      Body: fs.createReadStream(file.path),\n      Key: fileName,\n    };\n\n    const response = await new Promise(async (resolve, reject) => {\n      s3.putObject(params, function (error, data) {\n        if (error) {\n          resolve({\n            status: false,\n            message: error.message\n          });\n        } else {\n          resolve({\n            status: true,\n            data: 'https://' + process.env.AWS_S3_BUCKET_NAME + '.s3.' + S3Config.AWS_S3_REGION + '.amazonaws.com/' + fileName\n          });\n        }\n      });\n    });\n\n    return response;\n  }\n<%_}_%>\n\n<%_if(S3_UPLOAD && S3_UPLOAD_PRIVATE){_%>\n  async function generatePreSignedURL (uri){\n    if (uri){\n      const s3 = new AWS.S3({\n        region: S3Config.AWS_S3_REGION,\n        accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n        secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n      });\n\n      const {\n        region, bucket, key \n      } = AmazonS3URI(uri);\n\n      let options = {\n        Bucket: bucket,\n        Key: key,\n        Expires: 1 * 60 * 60, // 1 hour\n      };\n\n      let response = await new Promise(async (resolve,reject)=>{\n        await s3.getSignedUrl('getObject', options, (error, url) => {\n          if (error) {\n            resolve({\n              status: false,\n              error: error,\n            });\n          } else {\n            resolve({\n              status: true,\n              path: url,\n            });\n          }\n        });\n      });\n      return response;\n    }\n    else {\n      return {\n        status:false,\n        error:'Please send Url'\n      };\n    }\n  }\n<%_}_%>  \n\nmodule.exports = {\n  <%_if(LOCAL_UPLOAD){_%>\n    uploadFilesOnLocalServer,\n  <%_}_%> \n  <%_if(S3_UPLOAD){_%>\n    uploadFilesOnS3,\n    <%_if(S3_UPLOAD_PRIVATE){_%>\n      generatePreSignedURL\n    <%_}_%>\n  <%_}_%> \n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/services/smsService.js.ejs",
    "content": "const axios = require('axios')\nconst sendSMS = async (obj) => {\n    console.log('SMS---', obj);\n    if (obj.to) {\n        obj.mobiles = obj.to;\n    }\n    let mobiles;\n    if (Array.isArray(obj.mobiles)) {\n        obj.mobiles = obj.mobiles.map((m) => {\n            let tmpNo = m.split('+');\n            return tmpNo[1] ? tmpNo[1] : tmpNo[0];\n        });\n        mobiles = obj.mobiles.join(',');\n    }\n    else {\n        let tmpNo = obj.mobiles.split('+');\n        mobiles = tmpNo[1] ? tmpNo[1] : tmpNo[0];\n    }\n    const message = obj.message\n    const userid = \"\"\n    const password = escape(\"yourPassword\")\n    const v = 1.1\n    const method = \"sendMessage\"\n    const msg_type = \"text\"\n    const send_to = mobiles\n    return await new Promise((resolve, reject) => {\n        axios(\n            {\n                url: `http://enterprise.smsgupshup.com/GatewayAPI/rest?msg=${message}&v=${v}&userid=${userid}&password=${password}&method=${method}&send_to=${send_to}&msg_type=${msg_type}`,\n                method: 'GET',\n            })\n            .then(function (response) {\n                let response1 = response.data.split('|');\n                console.log(response.data)\n                if (response1.length) {\n                    if (response1[0].trim() === 'error') {\n                        reject(response)\n                    } else {\n                        resolve(response)\n                    }\n                }\n            })\n            .catch(function (error) {\n                reject(error)\n            });\n    });\n}\nmodule.exports = {sendSMS}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/authentication.js.ejs",
    "content": "\nconst response = require('../../utils/response');\nconst makeLoginUser = require('../common/loginUser'); \n\n/**\n* @description : login with username and password\n* @param {Object} params : request body.\n* @param {Number} platform : platform identification.\n* @return {Object} : response of authentication {status, message, data}\n*/\nconst authentication = ({ <%-USER_MODEL-%>Db,userTokensDb}) => async (params, platform) => {\n    let username = params.username;\n    let password = params.password;\n    if(!username || !password){\n        return response.badRequest()\n    }\n    const loginUser = makeLoginUser({<%-USER_MODEL-%>Db,userTokensDb});\n    return await loginUser(username, platform, password);\n}\nmodule.exports = authentication;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/forgotPassword.js.ejs",
    "content": "\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\nconst MakeSendResetPasswordNotification = require('../common/sendResetPasswordNotification');\n\n/**\n* @description : send email or sms to user with OTP on forgot password\n* @param {Object} params : request body.\n* @return {Object} : response for forgotPassword {status, message, data}\n*/ \nconst forgotPassword = ({ <%-USER_MODEL-%>Db  }) => async (params) => {\n    if (!params.email) {\n        return response.validationError()\n    }\n    let where = { <%-EMAIL_FIELD%>: params.email };\n    params.email = params.email.toString().toLowerCase();\n    let <%-USER_MODEL-%> = await <%-USER_MODEL%>Db.findOne(where);\n    if (user) {\n        let sendResetPasswordNotification = MakeSendResetPasswordNotification({<%-USER_MODEL-%>Db});\n        let notificationResponse = await sendResetPasswordNotification(user);\n        if (notificationResponse.status == responseStatus.success) {\n            let {resultOfEmail, resultOfSMS} = notificationResponse.data;\n            if (resultOfEmail && resultOfSMS) {\n                return response.success({message :\"otp successfully send.\"});\n            } else if (resultOfEmail && !resultOfSMS) {\n                return response.success({message : \"otp successfully send to your email.\"});\n            } else if (!resultOfEmail && resultOfSMS) {\n                return response.success({message : \"otp successfully send to your mobile number.\"});\n            } else {\n                return response.failure({message :\"otp can not be sent due to some issue try again later\"});success\n            }\n        } else {\n            return response.failure();\n        }\n    } else {\n        return response.recordNotFound()\n    }\n    \n}\nmodule.exports = forgotPassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/logout.js.ejs",
    "content": "const response = require('../../utils/response');\n\n/**\n * @description : logout user\n * @param {Object} user : user information.\n * @param {String} token : token of user.\n * @return {Object} : response for logout {status, message, data}\n */\nconst logout = ({userTokensDb}) => async (user, token) => {\n    let userToken = await userTokensDb.findOne({ token:token ,userId:user.id });\n    let updatedDocument = {\n        isTokenExpired : true\n    }\n    await userTokensDb.updateOne( {_id:userToken.id},updatedDocument);\n    <%_if(typeof PUSH_NOTIFICATION !== 'undefined'){_%>\n        let found = await pushNotificationService.getSingleDocumentByQuery({ userId:req.user.id });\n        if(found){\n            await pushNotificationService.updateDocument(found.id,{isActive:false});\n        }\n    <%_}_%>\n    return response.success({message:\"Logged out Successfully\"});\n}\nmodule.exports = logout;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/register.js.ejs",
    "content": "const  <%-USER_MODEL-%>Entity = require('../../entities/<%-USER_MODEL-%>');\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\nconst authConstant = require(\"../../constants/authConstant\");\n<%_ if(NOTIFICATION_TYPE===\"SMS\"){ _%>\nconst {sendSMS} = require('../../services/sms/smsService');\n<%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\nconst {sendMail} = require('../../services/email/emailService');\n<%_}_%>\n\n/**\n * @description : user registration \n * @param {Object} params : request for register\n * @return {Object} : response for register {status, message, data}\n */\nconst register = ({ <%-USER_MODEL-%>Db, createValidation }) => async (params) => {\n    let validateSchema = await createValidation(params);\n    if (!validateSchema.isValid) {\n        return response.validationError({ message: validateSchema.message });\n    }\n    let newUser = <%-USER_MODEL-%>Entity(params);\n    let checkUniqueValidation = checkUnique({<%-USER_MODEL-%>Db}); //dependance injection\n    let unique = await checkUniqueValidation(params);    \n    if (unique.status != responseStatus.success ){\n        return response.badRequest({message : 'User Registration Failed, Duplicate data found'});\n    }\n    const result = await <%-USER_MODEL-%>Db.create(newUser);\n        <%_ if(NOTIFICATION_TYPE===\"SMS\"){ _%>\n        // send sms to user for successfully registered.\n        let renderData = {\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n            <%_}else{_%>\n            ...result\n            <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-REGISTER_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n            to:result.<%-MOBILE_FIELD%>,\n            message:msg\n        }\n        await sendSMS(smsObj);\n    <%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\n        // send email to user for successfully registered.\n        let mailObj = {\n            subject: \"Register User\",\n            to: result.<%-EMAIL_FIELD%>,\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:{\n                <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n                <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n            }\n            <%_}else if(!REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:result\n            <%_}_%>\n        };\n        await sendEmail(mailObj);\n    <%_}_%>\n    return response.success({data :result});\n}\n\nconst checkUnique =({ <%-USER_MODEL-%>Db }) => async (data) =>{\n    let filter = { $or:[] };\n    if (data && data['username']){\n      filter['$or'].push(\n        { 'username':data['username'] },\n        { 'email':data['username'] },\n      );\n    }\n    if (data && data['email']){\n      filter['$or'].push(\n        { 'username':data['email'] },\n        { 'email':data['email'] },\n      );\n    }\n    let found = await <%-USER_MODEL-%>Db.findOne(filter);\n    if (found){\n      return response.failure();\n    }\n    return response.success();\n  };\n\n\n\nmodule.exports = register;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/resetPassword.js.ejs",
    "content": "const dayjs = require(\"dayjs\");\nconst bcrypt = require('bcrypt');\nconst response = require('../../utils/response');\nconst emailService = require('../../services/email/emailService');\n\n/**\n* @description : reset password with code and new password\n* @param {Object} params : request body.\n* @return {Object} : response for resetPassword {status, message, data}\n*/\nconst resetPassword = ({ <%-USER_MODEL-%>Db }) => async (params) => {\n    if (!params.code || !params.newPassword) {\n        return response.badRequest()\n    }\n    let user = await <%-USER_MODEL-%>Db.findOne({ 'resetPasswordLink.code': params.code });\n\n    if (!user || !user.resetPasswordLink.expireTime) {\n        return response.badRequest({message :\"Invalid Code\"});\n    }\n    \n    if (dayjs(new Date()).isAfter(dayjs(user.resetPasswordLink.expireTime))) {\n        return response.badRequest({message:\"Your reset password link is expired.\"});\n    }\n    \n    let newPassword = await bcrypt.hash(params.newPassword, 8);\n    await <%-USER_MODEL%>Db.updateOne({_id : user.id}, {\n        <%-PASSWORD_FIELD%>: newPassword,\n        resetPasswordLink: null,\n        <%_if(LOGIN_RETRY_LIMIT){_%>\n        <%-LOGIN_RETRY_LIMIT.key%>:0\n        <%_}_%>\n    });\n    let mailObj = {\n        subject: 'Reset Password',\n        to: user.<%-EMAIL_FIELD%>,\n        template: '/views/successfullyResetPassword',\n        data: {\n            isWidth: true,\n            email: user.<%-EMAIL_FIELD%> || '-',\n            message: \"Password Successfully Reset\"\n        }\n    };\n    await emailService.sendMail(mailObj);\n    return response.success({message :\"Password reset successfully\"});\n}\nmodule.exports = resetPassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/authentication/validateResetPasswordOtp.js.ejs",
    "content": "const dayjs = require(\"dayjs\");\nconst response = require('../../utils/response');\n\n/**\n* @description : validate OTP\n* @param {Object} params : request body.\n* @return {Object} : response for validateResetPasswordOtp  {status, message, data}\n*/\nconst validateResetPasswordOtp = ({ <%-USER_MODEL-%>Db }) => async (params) => {\n    if (!params || !params.otp) {\n        return response.badRequest()\n    }\n    let user = await <%-USER_MODEL-%>Db.findOne({ 'resetPasswordLink.code': params.otp });\n    if (!user || !user.resetPasswordLink.expireTime) {\n        return response.badRequest({message : \"Invalid OTP\"});\n    }\n    if (dayjs(new Date()).isAfter(dayjs(user.resetPasswordLink.expireTime))) {\n        return response.badRequest({message:\"Your reset password link is expired.\"});\n    }\n    return response.success({message :'OTP Validated'});\n}\nmodule.exports = validateResetPasswordOtp;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/bulkUpdate.js.ejs",
    "content": "/**\n updateBulk.js\n */\n\nconst response = require('../../utils/response');\n\n/**\n * @description : update multiple records of <%-MODEL_NAME%> with data by filter.\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} params :  request body including query and data to update.\n * @return {object} : updated documents\n */\nconst bulkUpdate = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    const results = await <%-MODEL_NAME-%>Db.updateMany(params.query,params.dataToUpdate);\n    return response.success({ data:results });\n}\nmodule.exports = bulkUpdate;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/changePassword.js.ejs",
    "content": "/**\n changePassword.js\n */\nconst bcrypt = require(\"bcrypt\");\nconst response = require('../../utils/response');\n\n/**\n * @description : change password.\n * @param {Object} params : request body including passwords and user id.\n * @return {Object} : Status whether password is changed or not.\n */\n\nconst changePassword = ({<%-MODEL_NAME-%>Db}) => async (params) => {\n\n  if (!params.newPassword || !params.userId || !params.oldPassword) {\n    return response.validationError({message:'Please Provide userId and new Password and Old password'});\n  }\n  let password = params.newPassword;\n  let oldPassword = params.oldPassword;\n  let user = await <%-MODEL_NAME%>Db.findOne({_id :params.userId });\n  if(!user){\n    return response.badRequest({message:'User not found.'});\n  }\n  let isPasswordMatch = await user.isPasswordMatch(oldPassword);\n  if(!isPasswordMatch){\n    return response.badRequest({message:'Incorrect old password.'});\n  }\n  password = await bcrypt.hash(password, 8);\n  let updatedUser = <%-MODEL_NAME%>Db.updateOne({_id : user.id}, { <%-PASSWORD_FIELD%>:password });\n  if (!updatedUser) {\n    return response.badRequest({message : 'Password not updated.'});\n  }\n  return response.success({message : 'Password changed successfully.'});\n}\n\nmodule.exports = changePassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/common/getRoleAccess.js.ejs",
    "content": "const response = require('../../utils/response');\nconst mongoose = require('mongoose');\n\nconst getRoleAccess = ({userRoleDb,routeRoleDb })=> async(userId) => {\n  let userRole = await userRoleDb.findMany({ userId: userId },{pagination:false});\n  let routeRole = await routeRoleDb.findMany({ roleId: { $in: userRole ? userRole.map(u=>u.roleId) : [] } },{ populate:['roleId','routeId'],pagination:false });\n  let models = mongoose.modelNames();\n  let roles = routeRole ? routeRole.map(rr => rr.roleId && rr.roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (roles.length){\n    roles.map(role => {\n      roleAccess[role] = {};\n      models.forEach(model => {\n        if (routeRole && routeRole.length) {\n          routeRole.map(rr => {\n            if (rr.routeId && rr.routeId.uri.includes(`/${model.toLowerCase()}/`) && rr.roleId && rr.roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr.routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr.routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr.routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr.routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return response.success({ data: roleAccess });\n}\n\nmodule.exports = getRoleAccess;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/common/loginUser.js.ejs",
    "content": "const {\n  JWT,LOGIN_ACCESS,\n  PLATFORM,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME<%_if(MAX_DEVICE_ALLOWED){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>\n} = require('../../constants/authConstant');\nconst dayjs = require('dayjs');\nconst generateToken = require('../../utils/generateToken');\nconst {getDifferenceOfTwoDatesInTime} = require('../../helpers/date');\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\n\n<%_if(ROLE_PERMISSION){_%>\n    const makeGetRoleAccess = require('../common/getRoleAccess');\n<%_}_%>\n\nconst loginUser = ({ <%-USER_MODEL-%>Db,userTokensDb<%_if(ROLE_PERMISSION){_%>,userRoleDb,routeRoleDb<%_}_%> })=> async(username,platform,password = null <%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n\n    <%_ if(LOGIN_WITH.length>1){ _%>\n        let where = <%-MULTIPLE_LOGIN%>\n    <%_ }else{_%>\n        let where ={'<%-LOGIN_WITH[0]%>':username}\n    <%_}_%>\n    let user = await <%-USER_MODEL-%>Db.findOne(where);\n    if (user) {\n        <%_if(MAX_DEVICE_ALLOWED){_%>\n            const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n            if(userToken >= NO_OF_DEVICE_ALLOWED){\n                return response.badRequest({message : \"You have reached your device limit\"});\n            }\n        <%_}_%>\n        <%_if(LOGIN_RETRY_LIMIT){_%>\n            if(user.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT){\n                let now = dayjs();\n                if (user.loginReactiveTime){\n                    let limitTime = dayjs(user.loginReactiveTime);\n                    if (limitTime > now){\n                        let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                        if (!(limitTime > expireTime)){\n                        return response.badRequest({message :`you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,limitTime)}.`});\n                        }   \n                        await <%-USER_MODEL-%>Db.updateOne({_id :user.id},{\n                        loginReactiveTime:expireTime.toISOString(),\n                        <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1  \n                        });\n                        return response.badRequest({message : `you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,expireTime)}.`});\n                    }else {\n                        user = await <%-USER_MODEL-%>Db.updateOne({ _id:user.id },{\n                            loginReactiveTime:'',\n                            <%-LOGIN_RETRY_LIMIT.key%>:0\n                        },{ new:true });\n                    }\n                } else {\n                    // send error\n                    let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                    await <%-USER_MODEL-%>Db.updateOne(user.id,{\n                        loginReactiveTime:expireTime.toISOString(),\n                        <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1 \n                    });\n                    return response.badRequest({message :`you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,expireTime)}.`}); \n                } \n            }\n        <%_}_%>\n        if(password){\n            const isPasswordMatched = await <%-USER_MODEL-%>.isPasswordMatch(password);\n            if (!isPasswordMatched) {\n                <%_if(LOGIN_RETRY_LIMIT){_%>\n                    await <%-USER_MODEL-%>Db.updateOne({_id : user.id},{<%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                <%_}_%>\n                return response.badRequest({message : \"incorrect password\"});\n            }\n        }\n        \n        const userData=user.toJSON()\n        let token;\n        if (!user.role) {\n            return response.badRequest({message : \"You have not been assigned role.\" });\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n            <%_if(i===0){_%>\n            if(platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                    return response.badRequest({message : 'you are unable to access this platform'});\n                }\n                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n            }\n            <%_}else{_%>\n            else if(platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                    return response.badRequest({ message : 'you are unable to access this platform'});\n                }\n                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n            }\n            <%_}_%>\n        <%_}_%> \n        <%_if(LOGIN_RETRY_LIMIT){_%>\n            if(user.<%-LOGIN_RETRY_LIMIT.key%>){\n                await <%-USER_MODEL-%>Db.updateOne({_id :user.id},{<%-LOGIN_RETRY_LIMIT.key%>:0,loginReactiveTime:''});\n            }\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({ userId: user.id, token: token,tokenExpiredTime: expire });                  \n        let userToReturn = { ...userData, token };\n        <%_if(ROLE_PERMISSION){_%>\n            let roleAccessData = {};\n            if (roleAccess){\n                const getRoleAccessData = makeGetRoleAccess({userRoleDb,routeRoleDb}); //Dependency Injection\n                roleAccessData = await getRoleAccessData(user.id);\n\n                if(roleAccessData.status == responseStatus.success){\n                    userToReturn.roleAccess = roleAccessData.data\n                }\n                \n            }\n        <%_}_%>\n        return response.success({data:userToReturn, message : 'Login Successful'});\n    } else {\n        return response.badRequest({message :\"User not exists\"});\n    }\n}\n\nmodule.exports = loginUser;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/common/sendResetPasswordNotification.js.ejs",
    "content": "const dayjs = require('dayjs');\nconst uuid = require(\"uuid\").v4;\nconst {\nFORGOT_PASSWORD_WITH\n} = require('../../constants/authConstant');\nconst response = require('../../utils/response');\n\nconst {sendMail} = require('../../services/email/emailService');\nconst {sendSMS} = require('../../services/sms/smsService');\nconst generateRandomNumber = require('../../utils/generateRandomNumber');\n\nconst sendResetPasswordNotification = ({<%-USER_MODEL%>Db}) => async (user) => {\n  let resultOfEmail = false;\n  let resultOfSMS = false;\n  <%_if(FORGOT_WITH_LINK){_%>\n    let token = uuid();\n    let expires = dayjs();\n    expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n    await <%-USER_MODEL%>Db.updateOne({_id :user.id }, { resetPasswordLink: { code: token, expireTime: expires } });\n    if(FORGOT_PASSWORD_WITH.LINK.email){\n        <%_if(RESET_PASSWORD_TEMPLATE_NAME &&  RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n          let updatedUser= await <%-USER_MODEL%>Db.findOne({_id:user.id});\n        <%_}_%>\n\n        let mailObj = {\n          subject: \"Reset Password\",\n          to: user.<%-EMAIL_FIELD%>,\n        };\n        <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n          mailObj.template = \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\";\n          mailObj.data = {\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n          }\n        <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template =  \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\";\n        mailObj.data = updatedUser;\n        <%_}else{_%>\n          let viewType = \"/reset-password/\";\n          let msg = \"Click on the link below to reset your password.\";\n          mailObj.template = \"/views/resetPassword\";\n          mailObj.data = {\n              link: `http://localhost:${process.env.PORT}` + viewType + token,\n              linkText: \"Reset Password\",\n              message:msg\n          }\n        <%_}_%>\n        try {\n            await sendMail(mailObj);\n            resultOfEmail = true;\n        } catch (error) {\n            console.log(error);\n        }\n    }\n    if(FORGOT_PASSWORD_WITH.LINK.sms){\n      <%_if(RESET_PASSWORD_NOTIFICATION_TYPE ==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%>\n          let updatedUser= await <%-USER_MODEL%>Db.findOne({_id:user.id});\n          let renderData = {\n              <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                  <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n              <%_}else{_%>\n                ...updatedUser\n              <%_}_%>\n          }\n          const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n          let smsObj = {\n            to:updatedUser.<%-MOBILE_FIELD%>,\n            message:msg\n          }\n          try{\n            await sendSMS(smsObj);\n            resultOfSMS = true;\n          }catch(error){\n            console.log(error)\n          }\n\n      <%_}else{_%>\n        let viewType = \"/reset-password/\";\n        let msg = `Click on the link to reset your password. http://localhost:${process.env.PORT}${viewType + token}`;\n        let smsObj = {\n          to:user.<%-MOBILE_FIELD%>,\n          message:msg\n        }\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n      <%_}_%>\n    }\n  <%_}_%>\n  <%_if(FORGOT_WITH_OTP){_%>\n    let otp = generateRandomNumber();\n    let expires = dayjs();\n    expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n    await <%-USER_MODEL%>Db.updateOne({_id :user.id}, { resetPasswordLink: { code: otp, expireTime: expires } });\n    if(FORGOT_PASSWORD_WITH.OTP.email){\n      <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n        let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({_id:user.id});\n      <%_}_%>\n        let mailObj = {\n          subject: 'OTP to reset your password',\n          to: user.<%-EMAIL_FIELD%>\n        }\n      <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template =  '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>';    \n        mailObj.data = {\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n              <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n        }\n      <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template = '/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>';\n        mailObj.data = updatedUser;\n      <%_}else{_%>\n        mailObj.template = '/views/resetPassword';\n        mailObj.data: {\n          isWidth: true,\n          name: \"username\",\n          email: user.<%-EMAIL_FIELD%> || '-',\n          message: otpMsg,\n          otp: otp\n        }\n      <%_}_%>\n      try {\n          await sendMail(mailObj);\n          resultOfEmail = true;\n      } catch (error) {\n          console.log(error);\n      }\n    }\n    if(FORGOT_PASSWORD_WITH.OTP.sms){\n      <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%>\n        let updatedUser= await <%-USER_MODEL%>Db.findOne({_id:user.id});\n        let renderData = {\n          <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n              <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n          <%_}else{_%>\n          ...updatedUser\n          <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n          to:updatedUser.<%-MOBILE_FIELD%>,\n          message:msg\n        }\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n\n      <%_}else{_%>\n        let message = `OTP code for Reset password`;\n        let otpMsg = `${message}: ${otp}`;\n        let smsObj = {\n          message: otpMsg,\n          to: user.<%-MOBILE_FIELD%>,\n        };\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n      <%_}_%> \n    }\n  <%_}_%> \n  return response.success({ data :{ resultOfEmail, resultOfSMS } });\n};\nmodule.exports = sendResetPasswordNotification;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/count.js.ejs",
    "content": "/**\n count.js\n */\n\nconst response = require('../../utils/response');\n\n/**\n * @description : returns total number of documents of <%-MODEL_NAME%>\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} where : where conditions\n * @return {object} : no of documents.\n */\nconst count = ({ <%-MODEL_NAME-%>Db }) => async (where) => {\n    let totalRecords = await <%-MODEL_NAME-%>Db.count(where);\n    return response.success({data: { totalRecords }});\n}\nmodule.exports = count;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/create.js.ejs",
    "content": "/**\n * create.js\n */\nconst  <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n<%_if(typeof DEFAULT_USER_ROLE !== \"undefined\" && DEFAULT_USER_ROLE){ _%>\nconst authConstant = require('../../constants/authConstant');\n<%_}_%>\n\n/**\n * @description : create document of <%-MODEL_NAME-%> in mongodb collection\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} dataToCreate : data for creating a new document\n * @return {object} : created document\n */\nconst create = ({ <%-MODEL_NAME-%>Db,createValidation }) => async (dataToCreate) => {\n    const validateRequest = await createValidation(dataToCreate);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let <%-MODEL_NAME-%> = <%-MODEL_NAME-%>Entity(dataToCreate);\n    <%-MODEL_NAME-%> = await <%-MODEL_NAME-%>Db.create(<%-MODEL_NAME-%>);\n    return response.success({data:<%-MODEL_NAME-%>});\n}\nmodule.exports = create;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/createBulk.js.ejs",
    "content": "\n/**\n *createBulk.js\n */\n\nconst  <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n<%_if(typeof DEFAULT_USER_ROLE !== \"undefined\" && DEFAULT_USER_ROLE){ _%>\nconst authConstant = require('../../constants/authConstant');\n<%_}_%>\n\n/**\n * @description : create documents of <%-MODEL_NAME-%> in mongodb collection\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} dataToCreate : data to create in database\n * @return {object} : response of create. {status, message, data}\n */\nconst createBulk = ({ <%-MODEL_NAME-%>Db,createValidation }) => async (dataToCreate) => {\n    let <%-MODEL_NAME.toLowerCase()-%>Entities = dataToCreate.map(item => <%-MODEL_NAME-%>Entity(item))\n    let results = await <%-MODEL_NAME-%>Db.createMany(<%-MODEL_NAME.toLowerCase()-%>Entities);\n    return response.success({data:results});\n}\nmodule.exports = createBulk;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/customRouteOfModel.js.ejs",
    "content": "\n/**\n *<%-FUNCTION_NAME%>.js\n */\nconst response = require('../../utils/response');\n\nconst <%-FUNCTION_NAME%> = ({<%-MODELS.join()%>}) => async (req,res) => {\n  let combinedOutput = {};\n  <%_ for(let i=0;i< QUERY.length;i++){ _%>\n  combinedOutput.<%-QUERY[i].outputVariable%> = await <%-QUERY[i].model%>Db.findOne(<%-QUERY[i].filter%>); \n  <%_}_%>\n  return response.success({data:combinedOutput});\n}; \n\nmodule.exports = <%-FUNCTION_NAME %>;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/delete.js.ejs",
    "content": "\n/**\n deleteOne.js\n */\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeDeleteWithDependency = require('./deleteDependent').deleteWithDependency;\n<%_ } _%>\n\n/**\n* @description : delete record of <%-MODEL_NAME_FC%> from database.\n* @param {Object} params : request body including query.\n* @return {Object} : deleted <%-MODEL_NAME_FC%>. {status, message, data}\n*/\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteOne = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let { query,isWarning } = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const deleteWithDependency = makeDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})\n        return await deleteWithDependency(query);\n    }\n}\n<%_ } else { _%>\nconst deleteOne = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME-%>Db.deleteOne(params.query);\n    return response.success({data: result});\n}\n<%_ } _%>\n\nmodule.exports = deleteOne;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/deleteMany.js.ejs",
    "content": "/**\n deleteMany.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeDeleteWithDependency = require('./deleteDependent').deleteWithDependency;\n<%_ } _%>\n\n/**\n* @description : delete records of <%-MODEL_NAME_FC%> from database by using ids.\n* @param {Object} params : params including query to delete documents.\n* @return {Object} : no of documents deleted. {status, message, data}\n*/\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteMany = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let { query,isWarning } = params;\n    if(isWarning){\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    }else {\n        const deleteWithDependency = makeDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n        return await deleteWithDependency(query)\n    }\n}\n<%_ } else { _%>\nconst deleteMany = ({ <%-MODEL_NAME%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME%>Db.deleteMany(params.query);\n    return response.success({data:result});\n};\n<%_ } _%>\nmodule.exports = deleteMany;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/fileUpload.js.ejs",
    "content": "const formidable = require('formidable');\n<%_if(S3_UPLOAD){_%>\n  \n<%_} else {_%>\n  const validUrl = require('valid-url');\n<%_}_%>\n\nconst response = require('../../utils/response');\nconst makeDirectory = require('../../utils/makeDirectory');\n\n<%_if(LOCAL_UPLOAD){_%>\nconst {uploadFilesOnLocalServer} = require('../../services/fileUpload');\n<%_}_%> \n<%_if(S3_UPLOAD){_%>\n  const {uploadFilesOnS3} = require('../../services/fileUpload');\n<%_ }else if(S3_UPLOAD && S3_UPLOAD_PRIVATE){_%>\n  const {uploadFilesOnS3,generatePreSignedURL} = require('../../services/fileUpload');\n<%_}_%>\n\nconst upload =async(req,res) =>{\n          <%_if(S3_UPLOAD){_%>\n          let combinedOutput = {};\n          let allowedFileTypes = <%=ALLOWED_TYPE%>;\n          <%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\n          let maxFileSize = <%=max_size%>; //In Megabyte\n\n          // Setting up formidable options.\n          const form = new formidable.IncomingForm();\n          form.multiples = true;\n          form.maxFileSize = 300 * 1024 * 1024; //300 MB\n          form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n          //Parse Form data\n          const {\n            fields, files\n          } = await new Promise(async (resolve, reject) => {\n            form.parse(req, function (error, fields, files) {\n              if (error) reject(error);\n              resolve({\n                fields,\n                files\n              });\n            });\n          });\n\n          let uploadSuccess = [];\n          let uploadFailed = [];\n          let fileCount = 1;\n\n          let fileArr = [];\n          if (!files['file[]'] || files['file[]'].size == 0) {\n            return response.badRequest({message : 'Select at least one file to upload.'});\n          }\n          if (!Array.isArray(files['file[]'])) {\n            fileArr.push(files['file[]']);\n            files['file[]'] = fileArr;\n          }\n\n          for (let file of files['file[]']) {\n            let response = await uploadFilesOnS3(file, fields, fileCount++, allowedFileTypes, maxFileSize);\n            if (response.status == false) {\n              uploadFailed.push({\n                'name': file.name,\n                'error': response.message,\n                'status': false\n              });\n            } else {\n              let url = response.data;\n              if (!validUrl.isUri(response.data)) {\n                response.data = response.data.replace('/public', '');\n                url = `${response.data}`;\n              }\n              uploadSuccess.push({\n                'name': file.name,\n                'path': url,\n                'status': true\n              });\n            }\n          }\n\n          let uploadFileRes = {\n            uploadSuccess,\n            uploadFailed\n          };\n\n          <%_if(S3_UPLOAD_PRIVATE){_%>\n            let finalResponse = [];\n            if (Array.isArray(uploadFileRes.uploadSuccess) && uploadFileRes.uploadSuccess.length) {\n              uploadFileRes.uploadSuccess = await new Promise(async (resolve, reject) => {\n                for (let u of uploadFileRes.uploadSuccess) {\n                  if (u.status && u.path) {\n                    let presignedUrl = await generatePreSignedURL(u.path);\n                    if (presignedUrl && presignedUrl.status) {\n                      u.path = presignedUrl.path;\n                    }\n                    finalResponse.push(u);\n                  }\n                }\n                resolve(finalResponse);\n              });\n            }\n          <%_}_%>\n          let fileUploadResponseObj = {};\n          if (uploadFileRes.uploadSuccess.length > 0) {\n            let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          } else {\n            let message = 'Failed to upload files.';\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          }\n\n          combinedOutput.uploadFileRes = fileUploadResponseObj;\n          return response.success({ data: combinedOutput });\n        <%_} else {_%>\n          let combinedOutput = {};\n          let defaultDirectory = 'public/assets';\n          let allowedFileTypes = <%=ALLOWED_TYPE%>;\n          <%_ let max_size = MAX_SIZE ? MAX_SIZE : 5 _%>\n          let maxFileSize = <%=max_size%>; //In Megabyte\n\n          // Create Directory if not exist.\n          await makeDirectory(defaultDirectory);\n          \n          // Setting up formidable options.\n          const form = new formidable.IncomingForm();\n          form.multiples = true;\n          form.maxFileSize = 300 * 1024 * 1024; //300 MB\n          form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n          //Parse Form data\n          const {\n            fields, files\n          } = await new Promise(async (resolve, reject) => {\n            form.parse(req, function (error, fields, files) {\n              if (error) reject(error);\n              resolve({\n                fields,\n                files\n              });\n            });\n          });\n          \n          let uploadSuccess = [];\n          let uploadFailed = [];\n          let fileCount = 1;\n\n          let fileArr = [];\n          if (!files['file[]'] || files['file[]'].size == 0) {\n            return response.badRequest({message : 'Select at least one file to upload.'});\n          }\n          if (!Array.isArray(files['file[]'])) {\n            fileArr.push(files['file[]']);\n            files['file[]'] = fileArr;\n          }\n\n          for (let file of files['file[]']) {\n            let response = await uploadFilesOnLocalServer(file, fields, fileCount++, allowedFileTypes, maxFileSize, defaultDirectory);\n            if (response.status == false) {\n              uploadFailed.push({\n                'name': file.name,\n                'error': response.message,\n                'status': false\n              });\n            } else {\n              let url = response.data;\n              if (!validUrl.isUri(response.data)) {\n                response.data = response.data.replace('/public', '');\n                url = `${response.data}`;\n              }\n              uploadSuccess.push({\n                'name': file.name,\n                'path': url,\n                'status': true\n              });\n            }\n          }\n\n          let uploadFileRes = {\n            uploadSuccess,\n            uploadFailed\n          };\n\n          let fileUploadResponseObj = {};\n          if (uploadFileRes.uploadSuccess.length > 0) {\n            let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          } else {\n            let message = 'Failed to upload files.';\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          }\n\n          combinedOutput.uploadFileRes = fileUploadResponseObj;\n          return response.success({ data: combinedOutput });\n        <%_ } _%>\n}\n\nmodule.exports = upload;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/findAll.js.ejs",
    "content": "const response = require('../../utils/response');\n\n/**\n* @description : find all records of <%-MODEL_NAME_FC%> from database based on query and options.\n* @param {Object} params : request body including option and query.\n* @return {Object} : found <%-MODEL_NAME_FC%>(s). {status, message, data}\n*/\nconst findAll = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query, options,isCountOnly } = params;\n    if(isCountOnly){\n        result = await <%-MODEL_NAME-%>Db.count(query);\n        let result = { totalRecords: result };\n        return response.success({ data:result });  \n    } else {\n        let result = await <%-MODEL_NAME-%>Db.paginate(query,options);\n        if(!result){\n            return response.recordNotFound();\n        }\n        return response.success({ data:result });\n    }\n}\nmodule.exports = findAll;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/findById.js.ejs",
    "content": "const response = require('../../utils/response');\n\n/**\n* @description : find record of <%-MODEL_NAME_FC%> from database by id;\n* @param {Object} params : request body including option and query.\n* @return {Object} : found <%-MODEL_NAME_FC%>. {status, message, data}\n*/\nconst findById = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME-%>Db.findOne(params.query, params.options);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\nmodule.exports = findById;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/partialUpdate.js.ejs",
    "content": "const <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\n/**\n* @description : partially update record of <%-MODEL_NAME_FC%> with data by id;\n* @param {Object} params : request body.\n* @return {obj} : updated <%-MODEL_NAME_FC%>. {status, message, data}\n*/\nconst partialUpdate = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    const <%-MODEL_NAME.toLowerCase()-%> = await <%-MODEL_NAME-%>Db.updateOne(params.query,params.partialUpdate);\n    if(!<%-MODEL_NAME.toLowerCase()-%>){\n        return response.recordNotFound();\n    }\n    return response.success({data:<%-MODEL_NAME.toLowerCase()-%>});\n}\nmodule.exports = partialUpdate;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/softDelete.js.ejs",
    "content": "/**\n softDelete.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeSoftDeleteWithDependency = require('./deleteDependent').softDeleteWithDependency;\n<%_ } _%>\n\n\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n/**\n* @description : soft delete record of <%-MODEL_NAME_FC%> from database by id;\n* @param {Object} params : request body.\n* @return {Object} : deactivated <%-MODEL_NAME_FC%>. {status, message, data}\n*/\nconst softDelete = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let {query,dataToUpdate,isWarning } = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const softDeleteWithDependency = makeSoftDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        return await softDeleteWithDependency(query, dataToUpdate);\n    }\n    \n}\n<%_ } else { _%>\n/**\n* @description : soft delete record of <%-MODEL_NAME_FC%> from database by id;\n* @param {Object} params : request body.\n* @return {Object} : deactivated <%-MODEL_NAME_FC%>. {status, message, data}\n*/\nconst softDelete = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query,dataToUpdate } = params;\n    let result = await <%-MODEL_NAME-%>Db.softDelete(query, dataToUpdate);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\n<%_ } _%>\nmodule.exports = softDelete;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/softDeleteMany.js.ejs",
    "content": "/**\n softDeleteMany.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeSoftDeleteWithDependency = require('./deleteDependent').softDeleteWithDependency;\n<%_ } _%>\n\n/**\n* @description : soft delete multiple records of <%-MODEL_NAME_FC%> from database by ids;\n* @param {Object} params : request body.\n* @return {Object} : number of deactivated documents of <%-MODEL_NAME_FC%>. {status, message, data}\n*/\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst softDeleteMany = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let { query, dataToUpdate,isWarning} = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const softDeleteWithDependency = makeSoftDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n        return await softDeleteWithDependency(query, dataToUpdate);\n    }\n    \n}\n<%_ } else { _%>\nconst softDeleteMany = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query,dataToUpdate } = params;\n    let result = await <%-MODEL_NAME-%>Db.softDeleteMany(query, dataToUpdate);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\n<%_ } _%>\nmodule.exports = softDeleteMany;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/update.js.ejs",
    "content": "const <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\n/**\n* @description : update record of <%-MODEL_NAME_FC%> with data by id.\n* @param {Object} params : request body including query and data.\n* @return {Object} : updated <%-MODEL_NAME_FC%>. {status, message, data}\n*/\nconst update = ({ <%-MODEL_NAME-%>Db, updateValidation}) => async (params) => {\n    let { dataToUpdate, query } = params;\n    const validateRequest = await updateValidation(dataToUpdate);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let <%-MODEL_NAME.toLowerCase()-%> = <%-MODEL_NAME-%>Entity(dataToUpdate);\n    <%-MODEL_NAME.toLowerCase()-%> = await <%-MODEL_NAME-%>Db.updateOne(query,<%-MODEL_NAME.toLowerCase()-%>);\n    if(!<%-MODEL_NAME.toLowerCase()-%>){\n        return response.recordNotFound();\n    }\n    return response.success({data:<%-MODEL_NAME.toLowerCase()-%>});\n}\nmodule.exports = update;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/use-case/updateProfile.js.ejs",
    "content": "/**\n updateProfile.js\n */\n\n\nconst <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\nconst updateProfile = ({<%-MODEL_NAME-%>Db,updateValidation}) => async (params,id) => {\n    delete params.createdAt;\n    delete params.updatedAt;\n    delete params.id;\n    const validateRequest = await updateValidation(params);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let <%-MODEL_NAME.toLowerCase()-%> = <%-MODEL_NAME-%>Entity(params);\n    let updated<%-MODEL_NAME_FC%> = await <%-MODEL_NAME-%>Db.updateOne({_id:id}, <%-MODEL_NAME.toLowerCase()-%>);\n    return response.success({data:updated<%-MODEL_NAME_FC%>});\n}\nmodule.exports = updateProfile;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/common.js.ejs",
    "content": "const mongoose = require('mongoose');\nfunction convertObjectToEnum (obj) {\n  const enumArr = [];\n  Object.values(obj).map((val) => enumArr.push(val));\n  return enumArr;\n};\n\nfunction randomNumber (length = 4) {\n  const numbers = '12345678901234567890';\n  let result = '';\n  for (let i = length; i > 0; i -= 1) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\nfunction replaceAll (string, search, replace) { return string.split(search).join(replace); };\n\n<%_if(IS_AUTH){ _%>\nfunction makeUniqueValidation (<%-MODEL%>Service) {\nconst uniqueValidation = async (data) =>{\n    <%_if (LOGIN_WITH.length > 1) {_%>\n    let filter = {$or:[]};\n    <%_for(let i in LOGIN_WITH){_%>\n    if(data && data[\"<%-LOGIN_WITH[i]%>\"]){\n        filter['$or'].push(\n        <%_for(let j in LOGIN_WITH){_%>\n        {\"<%-LOGIN_WITH[j]%>\":data[\"<%-LOGIN_WITH[i]%>\"]},\n        <%_}_%>\n        )\n    }\n    <%_}_%>\n    <%_} else {_%>\n    let filter = {};\n    if(data && data[\"<%-LOGIN_WITH[0]%>\"]){\n        filter = { \"<%-LOGIN_WITH[0]%>\": data[\"<%-LOGIN_WITH[0]%>\"] }\n    }\n    <%_}_%>\n    filter.isActive = true;\n    filter.isDeleted = false;\n    let found = await <%-MODEL%>Service.getSingleDocumentByQuery(filter);\n    if(found){\n        return false;\n    }\n    return true;\n}\nreturn Object.freeze({ uniqueValidation });\n}\n<%_}_%>\n\n<%_if(IS_AUTH){_%>\n  const getDifferenceOfTwoDatesInTime = (currentDate,toDate) =>{\n    let hours = toDate.diff(currentDate,'hour');\n    currentDate =  currentDate.add(hours, 'hour');\n    let minutes = toDate.diff(currentDate,'minute');\n    currentDate =  currentDate.add(minutes, 'minute');\n    let seconds = toDate.diff(currentDate,'second');\n    currentDate =  currentDate.add(seconds, 'second');\n    if (hours){\n      return `${hours} hour, ${minutes} minute and ${seconds} second`; \n    }\n    return `${minutes} minute and ${seconds} second`; \n  };\n<%_}_%>\n<%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n/*\n * getRoleAccessData: return roleAccess of User\n * @param userRoleService : user role db service\n * @param routeRoleService : route role db service\n * @param userId : id of user to find role data\n */\nconst getRoleAccessData = async (userRoleService,routeRoleService,userId) =>{\n  let userRole = await userRoleService.getAllDocuments({ userId: userId },{pagination:false});\n  let routeRole = await routeRoleService.getAllDocuments({ roleId: { $in: userRole.data ? userRole.data.map(u=>u.roleId) : [] } },{ populate:['roleId','routeId'],pagination:false });\n  let models = mongoose.modelNames();\n  let Roles = routeRole.data ? routeRole.data.map(rr => rr.roleId && rr.roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (Roles.length){\n    Roles.map(role => {\n      roleAccess[role] = {};\n      models.forEach(model => {\n        if (routeRole.data && routeRole.data.length) {\n          routeRole.data.map(rr => {\n            if (rr.routeId && rr.routeId.uri.includes(model.toLowerCase()) && rr.roleId && rr.roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr.routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr.routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr.routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr.routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return roleAccess;\n};\n<%_}_%>\n\nmodule.exports = {\n  convertObjectToEnum,\n  randomNumber,\n  replaceAll,\n  <%_if(IS_AUTH){ _%>\n  makeUniqueValidation,\n  getDifferenceOfTwoDatesInTime,\n  <%_}_%>\n  <%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n  getRoleAccessData,\n  <%_}_%>\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/convertObjectToEnum.js",
    "content": "const convertObjectToEnum = (obj) => {\n  const enumArr = [];\n  Object.values(obj).map((val) => enumArr.push(val));\n  return enumArr;\n};\n\nmodule.exports = convertObjectToEnum;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/deleteDependentService1.js.ejs",
    "content": "<%_ \n    const groupBy = function (xs, key) {\n    return xs.reduce(function (rv, x) {\n        (rv[x[key]] = rv[x[key]] || []).push(x);\n        return rv;\n    }, {});\n    };\n\n    let modelDependency = groupBy(DELETE_DEPENDENCY, 'model');\n_%>\nconst response = require('../../utils/response');\n\nconst getDependencyCount =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})=> async (filter) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {_id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj._id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    const <%-modelName%>Cnt =  await <%-modelDbName%>.count(<%-modelFilterName%>);\n                <%_  }\n            _%>\n                let response = { <%_  for (modelName in modelDependency) {  _%> <%-modelName%> : <%-modelName%>Cnt,  <%_  }  _%>}\n                return response;\n        }else{\n            return {  <%-MODEL_NAME%> : 0};\n        }\n    <%_}else{_%>\n    const <%-MODEL_NAME%>Cnt =  await <%-MODEL_NAME%>Db.count(filter);\n    return {<%-MODEL_NAME%> : <%-MODEL_NAME%>Cnt}\n    <%_}_%>\n}\n\nconst deleteWithDependency =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})=> async (filter) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {_id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj._id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    await <%-modelDbName%>.deleteMany(<%-modelFilterName%>);\n                <%_  }\n            _%>\n\n                let result = await <%-MODEL_NAME%>Db.deleteMany(filter);\n                return response.success({data :result });\n        }else{\n            return response.badRequest({message :\"No <%-MODEL_NAME%> found.\" });\n        }\n    <%_}else{_%>\n    let result =  await <%-MODEL_NAME%>Db.deleteMany(filter);\n    return response.success({data :result });\n    <%_}_%>\n}\n\nconst softDeleteWithDependency =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (filter,updateBody) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {_id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj._id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    await <%-modelDbName%>.updateMany(<%-modelFilterName%>,updateBody);\n                <%_  }\n            _%>\n\n                let result = await <%-MODEL_NAME%>Db.updateMany(filter,updateBody);\n                return response.success({data : result});\n        }else{\n            return response.badRequest({message : \"No <%-MODEL_NAME%> found.\"});\n        }\n    <%_}else{_%>\n    let result = await <%-MODEL_NAME%>.updateMany(filter,updateBody);\n    return response.success({data : result});\n    <%_}_%>\n}\nmodule.exports = {getDependencyCount, deleteWithDependency,softDeleteWithDependency}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/generateRandomNumber.js",
    "content": "const generateRandomNumber = (length = 4) => {\n  const numbers = '12345678901234567890';\n  let result = '';\n  for (let i = length; i > 0; i -= 1) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\nmodule.exports = generateRandomNumber;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/generateToken.js",
    "content": "/* eslint-disable */\nconst jwt = require('jsonwebtoken');\nconst { JWT } = require('../constants/authConstant');\n\nasync function generateToken (user, secret) {\n  return jwt.sign({\n    id: user.id,\n    username: user.username,\n  }, secret, { expiresIn: JWT.EXPIRES_IN });\n}\n\nmodule.exports = generateToken;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/getSelectObject.js",
    "content": "/**\n * getSelectObject : to return a object of select from string, array\n * @param {string/array/obj} select : selection attributes\n * @returns {object} : object of select to be passed with filter\n */\nconst getSelectObject = (select) => {\n  let selectArray = [];\n  if (typeof select === 'string') {\n    selectArray = select.split(' ');\n  } else if (Array.isArray(select)) {\n    selectArray = select;\n  } else if (typeof select === 'object') {\n    return select;\n  }\n  const selectObject = {};\n  if (selectArray.length) {\n    for (let index = 0; index < selectArray.length; index += 1) {\n      const element = selectArray[index];\n      if (element.startsWith('-')) {\n        Object.assign(selectObject, { [element.substring(1)]: -1 });\n      } else {\n        Object.assign(selectObject, { [element]: 1 });\n      }\n    }\n  }\n  return selectObject;\n};\n\nmodule.exports = getSelectObject;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/makeDirectory.js",
    "content": "const fs = require('fs');\n/**\n *\n * Function used to create directory.\n *\n * @param  {string} dirPath\n * @returns  {boolean}\n */\nconst makeDirectory = async (directoryPath) => {\n  if (!fs.existsSync(directoryPath)) {\n    fs.mkdirSync(directoryPath, { recursive: true });\n    return true;\n  }\n  return true;\n};\n\nmodule.exports = makeDirectory;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/response/index.js",
    "content": "const responseStatus = require('./responseStatus');\n\nmodule.exports = {\n  success: (data = {}) => ({\n    status: responseStatus.success,\n    message: data.message || 'Your request is successfully executed',\n    data: data.data || {},\n  }),\n\n  failure: (data = {}) => ({\n    status: responseStatus.failure,\n    message: data.message || 'Some error occurred while performing action.',\n    data: data.data || {},\n  }),\n\n  internalServerError: (data = {}) => ({\n    status: responseStatus.serverError,\n    message: data.message || 'Internal server error.',\n    data: data.data || {},\n  }),\n\n  badRequest: (data = {}) => ({\n    status: responseStatus.badRequest,\n    message: data.message || 'The request cannot be fulfilled due to bad syntax.',\n    data: data.data || {},\n  }),\n\n  recordNotFound: (data = {}) => ({\n    status: responseStatus.recordNotFound,\n    message: data.message || 'Record(s) not found with specified criteria.',\n    data: data.data || {},\n  }),\n\n  validationError: (data = {}) => ({\n    status: responseStatus.validationError,\n    message: data.message || `Invalid Data, Validation Failed.`,\n    data: data.data || {},\n  }),\n\n  unAuthorized: (data = {}) => ({\n    status: responseStatus.unauthorized,\n    message: data.message || 'You are not authorized to access the request',\n    data: data.data || {},\n  }),\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/response/responseCode.js",
    "content": "module.exports = {\n  success: 200,\n  badRequest: 400,\n  internalServerError: 500,\n  unAuthorized: 401,\n  notFound: 404,\n  validationError: 422,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/response/responseHandler.js",
    "content": "const responseCode = require('./responseCode');\n\nmodule.exports = (res, body = {}) => {\n  const headers = body.headers || { 'Content-Type': 'application/json' };\n  let statusCode;\n\n  switch (body.status) {\n  case 'SUCCESS':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'FAILURE':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'SERVER_ERROR':\n    statusCode = body.statusCode || responseCode.internalServerError;\n    break;\n  case 'BAD_REQUEST':\n    statusCode = body.statusCode || responseCode.badRequest;\n    break;\n  case 'RECORD_NOT_FOUND':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'VALIDATION_ERROR':\n    statusCode = body.statusCode || responseCode.validationError;\n    break;\n  case 'UNAUTHORIZED':\n    statusCode = body.statusCode || responseCode.unAuthorized;\n    break;\n  default:\n    statusCode = responseCode.internalServerError;\n  }\n  return res.set(headers).status(statusCode).send(body);\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/utils/response/responseStatus.js",
    "content": "module.exports = {\n  success: 'SUCCESS',\n  failure: 'FAILURE',\n  serverError: 'SERVER_ERROR',\n  badRequest: 'BAD_REQUEST',\n  recordNotFound: 'RECORD_NOT_FOUND',\n  validationError: 'VALIDATION_ERROR',\n  unauthorized: 'UNAUTHORIZED',\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/validation/index.js",
    "content": "const schemaValidation = (schema) => (data) => {\n  const { error } = schema.validate(data);\n  if (error) {\n    const message = error.details.map((el) => el.message).join('\\n');\n    return {\n      isValid: false,\n      message,\n    };\n  }\n  return { isValid: true };\n};\n\nmodule.exports = schemaValidation;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/validation/validateSchema.js.ejs",
    "content": "const joi = require(\"joi\")\n<%_if(ENUM_VALIDATION){_%>        \n<%_for(let enumIndex of ENUM_VALIDATION){_%>\nconst <%-enumIndex%>Default=require('../constants/<%-enumIndex%>');    \n<%_}_%>       \n<%_}_%>    \n\n<%_ if(typeof VARIABLES !== \"undefined\") {\nfor(let i=0;i< VARIABLES.length; i++) {_%>\n<%-VARIABLES[i]%>\n<%_ } } _%>\n<%_if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){_%>\nconst {USER_ROLE} = require(\"../../constants/authConstant\");\nconst {convertObjectToEnum} = require(\"../../utils/common\")   \n<%_}_%>\nconst createSchema = joi.object(<%-VALIDATION_KEY%>).unknown(true);\n\nconst updateSchema = joi.object(<%-UPDATE_VALIDATION_KEY%>).unknown(true);\n\nmodule.exports = {createSchema, updateSchema};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/views/emailTemplate.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <!-- message -->\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear ,</b>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/views/index.ejs",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n  <link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\" rel=\"stylesheet\">\n  <link rel=\"icon\" type=\"image/png\" href=\"https://dxuoui1db8w1y.cloudfront.net/index.png?o=g\">\n  <title>welcome to node.js</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n\n    body {\n      font-family: 'Courier Prime', monospace;\n      height: 100vh;\n      background-color: #181818;\n      display: flex;\n    }\n    .sidebar{\n      height: 100vh;\n    }\n    .main-section{\n      padding: 100px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    h1{\n      color: #ffffff;\n      font-weight: 100;\n      font-size: 4vw;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <img class=\"sidebar\" src=\"https://dxuoui1db8w1y.cloudfront.net/sidebar.jpg?o=g\" alt=\"sidebar\">\n  </div>\n  <div class=\"main-section\">\n    <div>\n      <div style=\"display: flex; justify-content: space-between; margin-bottom: 50px;\">\n        <img src=\"https://dxuoui1db8w1y.cloudfront.net/dhiwise.png?o=g\" alt=\"dhiwise\" style=\"width: 130px;\">\n      </div>\n    <h1><br>Welcome to <span style=\"color: #3E863D;\">Node.Js</span><br>application </h1>\n  </div>\n  </div>\n</body>\n\n</html>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/views/resetPassword.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <%-message%>\n                    </div>\n                </div>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/views/resetPasswordLink.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        Reset Password Link\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,<%-message%></b>\n                </p>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    <a href=\"<%-link%>\"><%-linkText%></a>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCode/views/sendOTP.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        OTP\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,</b>\n                </p>\n            </td>\n        </tr>\n        <% if(otp) { %>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    Your OTP code is <strong> <%- otp %></strong>\n                </p>\n            </td>\n        </tr>\n        <% } %>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  parserOptions: {\n    ecmaVersion: 12,\n    sourceType: 'module',\n  },\n  rules: {\n    semi: ['error', 'always'],\n    indent: ['error', 2],\n    'no-irregular-whitespace': ['error', {\n      skipStrings: true,\n      skipComments: true,\n      skipRegExps: true,\n      skipTemplates: true,\n    }],\n    'multiline-comment-style': ['error', 'starred-block'],\n    'object-property-newline': ['error', {\n      allowAllPropertiesOnSameLine: false,\n      allowMultiplePropertiesPerLine: false,\n    }],\n    'object-curly-newline': ['error', {\n      minProperties: 2,\n      multiline: true,\n    }],\n    'no-multiple-empty-lines': ['error', {\n      max: 1,\n      maxEOF: 0,\n    }],\n    'no-param-reassign': 'off',\n    'no-underscore-dangle': 'off',\n    'class-methods-use-this': 'off',\n    'max-len': [2, {\n      code: 1000,\n      ignorePattern: '^import .*',\n    }],\n    'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],\n    'space-infix-ops': ['error', { int32Hint: false }],\n    'space-before-function-paren': ['error', {\n      anonymous: 'always',\n      named: 'always',\n      asyncArrow: 'always',\n    }],\n    'keyword-spacing': ['error', {\n      before: true,\n      after: true,\n    }],\n    'object-curly-spacing': ['error', 'always'],\n    quotes: ['error', 'single', { allowTemplateLiterals: true }],\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/.gitignore",
    "content": "node_modules\n.dhiwise"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/README.ejs",
    "content": "# NodeJS, Sequelize, Express Project in Clean-Code Architecture\n\n**supported version of nodejs > 12**,\n**supported version of sequelize-6.6.5**\n\n- This is a Web application, developed using MVC pattern with Node.js, ExpressJS, and Sequelize ORM. \n- Basic boilerplate for web applications, built on Express.js using the clean-code architecture\n- A Sql database is used for data storage, with object modeling provided by Sequelize.\n- Supported SQL Databases are - MSSQL, MySql, PostgreSQL \n\n## Initial\n- Configure a basic server in app.js.\n- Organize the routes with Express Router.\n- Use the mainRoutes in app as middleware.\n- Set a final use after the routes, to display a 404 message for the unhandled requests.\n1. Install needed Node.js modules:\n     ```$ npm install```\n2. execute server:\n     ```$ npm start```\n\t<%_if(IS_AUTH){_%>\n3. When the app will run successfully,\n<%_if(ROLE_WISE_CREDENTIALS){_%>\n<%_for (let i in ROLE_WISE_CREDENTIALS){_%>\n\n\t\t- One user with <%-i%> role,\n\t    # Default <%-i%> credentials\n\t\t**username** : <%-ROLE_WISE_CREDENTIALS[i][USER_FIELD]%>\n\t\t**password** : <%-ROLE_WISE_CREDENTIALS[i][PASSWORD_FIELD]%>\n\t\t\n<%_}_%> \n<%_}_%>\t \n\t\t<%_}_%>\n\n## Default Folder structure:\n\n\t--project_folder\n\t\t--config\n\t\t--constants\n\t\t--controller\n\t\t--entity\n\t\t--helpers\n\t\t--logs\n\t\t--middleware\n\t\t--model\n\t\t--postman\n\t\t--public\n\t\t--routes\n\t\t--services\n\t\t--utils\n\t\t--validation\n\t\t--views\n\t\t--app.js\n\t\t--.env\n\t\t--.gitignore\n\t\t--.eslintrc.js\n## app.js\n- Entry point of application.\n\n## config\n- Passport strategy for all platforms.\n- Based on Auth Model - authentication files has been generated.\n- Used .env file and configure the db connection string and port to use in the project.\n\n## constants\n- Contains files of constants\n\n## controller\n- Includes controller files per model\n- Controllers are separated per Platform\n\n     \t  -controller\n     \t        -admin\n     \t            -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -device\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -desktop\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n     \t        -client\n     \t          -model\n     \t                -index.js\n     \t                -controller.js\n\n## entity\n- These are the business objects of your application. These should not be affected by any change external to them, and these should be the most stable code within your application. These can be POJOs, objects with methods, or even data structures.\n\n## helper\n- a helper function is used to assist in providing some functionality, which isn't the main goal of the application or class in which it is used.\n\n## logs\n- Log file\n\n## middleware\n- User authentication Middleware based on Roles and permission for Routes' access\n- Custom Policy files\n\n## model\n- Sequelize Models, as per user defined schema \n\n## postman\n- Postman collection File for Platform based APIs that are generated.\n- Import this JSON in Postman to test the APIs.\n\n## public \n- You can add static files like like images, pdf etc.\n\n## routes\n- Based on platform,separate folder is generated,within those folders model wise route files are that has model crud APIs' routes.\n- index.js file, main file which includes all platform routes.\n- Added index files in app.js to access the routes of the application.\n\n## services\n     \t-auth.js\n       \t\t-Logic for JWT Tokenization for user to login into Application using username and password along with otp if required.\n       \t-dbService.js\n       \t    - Database related operations\n       \t     -common Database functionalities\n     \t  \t -findAll(find all records)\n     \t  \t -updateByPk(update single record in db by primary key)\n     \t  \t -deleteByPk(delete single record in db)\n     \t  \t -createOne(Insert single record in db)\n     \t  \t -findOne(find single record by query)\n     \t  \t -softDeleteByPk\n     \t  \t -updateMany(update records that matches query)\n             -deleteMany(delete record that matches query)\n     \t  \t -createMany(insert multiple records in db)\n     \t  \t -count (count records that matches query)\n       \t    \n## utils\n     \t-common.js\n       \t\t-converted object to enum function.\n     \t-messages.js\n  \t\t    -static messages that are sent with response - contains status and Data\n\t    -responseCode.js\n  \t\t    -codes for responses\n\t    -validateRequest.js\n  \t\t    -validate schema based on joi validation\n\n## validation\n- Joi validations files.\n- Files are separated by models.\n\n## views\n- Add ejs files"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/__test__/auth.test.js.ejs",
    "content": "const dotenv = require('dotenv');\ndotenv.config();\nprocess.env.NODE_ENV = 'test';\nconst request = require('supertest');\nconst db = require('../../config/dbConnection')\nconst app = require('../../app.js');\nconst authConstant=require('../../constants/authConstant');\nconst routes = require('../../routes.js');\napp.use(routes);\n\nbeforeAll(async function () {\n  await db.sync({})\n})\n\nafterAll(async function(){\n  await db.dropAllSchemas()\n  await db.drop()\n  await db.close()\n})\n\ndescribe('POST /register -> if email and username is given', () => {\n  test('should register a <%-AUTH_MODEL%>', async () => {\n    let registeredUser = await request(app)\n      .post('/<%-PLATFORM%>/auth/register')\n      <%_var finalStr=new String(); \n      FAKE_DATA_OF_AUTH.role=`@@authConstant.USER_ROLE.${ROLE}@@`;\n        finalStr=JSON.stringify(FAKE_DATA_OF_AUTH); \n        finalStr=finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\" ); \n      _%>\n      .send(<%-finalStr%>);\n    expect(registeredUser.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(registeredUser.body.status).toBe('SUCCESS');\n    expect(registeredUser.body.data).toMatchObject({\n      id: expect.any(Number)\n    });\n    expect(registeredUser.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username and password is correct', () => {\n  test('should return <%-AUTH_MODEL%> with authentication token', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n      expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n      expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n      expect(<%-AUTH_MODEL%>.body.data).toMatchObject({\n          id: expect.any(Number),\n          token: expect.any(String)\n      }); \n      expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username is incorrect', () => {\n  test('should return unauthorized status and <%-AUTH_MODEL%> not exists', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: 'wrong.username',\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.statusCode).toBe(401);\n  });\n});\n\ndescribe('POST /login -> if password is incorrect', () => {\n  test('should return unauthorized status and incorrect password', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: 'wrong@password'\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.statusCode).toBe(401);\n  });\n});\n\ndescribe('POST /login -> if username or password is empty string or has not passed in body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send({});\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.body.message).toBe('Insufficient parameters');\n    expect(user.statusCode).toBe(422);\n  });\n});\n\ndescribe('POST /forgot-password -> if email has not passed from request body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ email: '' });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.body.message).toBe('Insufficient parameters');\n    expect(user.statusCode).toBe(422);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is not available in database', () => {\n  test('should return record not found status', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': 'unavailable.email@hotmail.com', });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('RECORD_NOT_FOUND');\n    expect(user.body.message).toBe('Record not found with specified criteria.');\n    expect(user.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is valid and OTP sent successfully', () => {\n  test('should return success message', async () => {\n    const expectedOutputMessages = [\n      'otp successfully send.',\n      'otp successfully send to your email.',\n      'otp successfully send to your mobile number.'\n    ];\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': <%_if(FAKE_DATA_OF_AUTH['email'] !== undefined) {_%><%=FAKE_DATA_OF_AUTH['email']%><%_}else{_%>'valid.mail@hotmail.com'<%_}_%>_%>, });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('SUCCESS');\n    expect(expectedOutputMessages).toContain(user.body.message);\n    expect(user.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /validate-otp -> otp is sent in request body and OTP is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .post('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'otp': foundUser.body.data.resetPasswordLink.code, }).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('POST /validate-otp -> if OTP is incorrect or OTP has expired', () => {\n  test('should return invalid OTP', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({ 'otp': '12334' });\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid OTP');\n  });\n});\n\ndescribe('POST /validate-otp -> if request body is empty or otp has not been sent in body', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('PUT /reset-password -> code is sent in request body and code is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .put('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'code': foundUser.body.data.resetPasswordLink.code, 'newPassword':'newPassword'}).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('PUT /reset-password -> if request body is empty or code/newPassword is not given', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM%>/auth/reset-password')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(422);\n  });\n});\n\ndescribe('PUT /reset-password -> if code is invalid', () => {\n  test('should return invalid code', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM%>/auth/reset-password')\n      .send({\n        'code': '123',\n        'newPassword': 'testPassword'\n      });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid Code');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/app.js.ejs",
    "content": "const express = require('express');\nconst cors = require('cors');\nconst path = require('path');\nconst dotenv = require('dotenv');\ndotenv.config();\nglobal.__basedir = __dirname;\n<%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\nconst listEndpoints = require('express-list-endpoints')\n<%_}_%>\n<%_ if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){ _%>\nconst passport = require(\"passport\")\nconst seeder = require('./seeders');\n<%_ } _%>\n\n<% Object.keys(modules).sort().forEach(function (variable) { -%>\nlet <%- variable %> = require('<%- modules[variable] %>');\n<% }); -%>\n<% Object.keys(localModules).sort().forEach(function (variable) { -%>\nconst <%- variable %> = require('<%- localModules[variable] %>');\n<% }); -%>\nconst models = require('./db/sequelize/models');\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\nconst {<%-platform.toLowerCase()%>PassportStrategy} = require('./middleware');\n<%_ } _%>\n<%_ } _%>\n\nconst app = express();\nconst corsOptions = {\n    origin: process.env.ALLOW_ORIGIN,\n}\napp.use(cors(corsOptions));\n\n//template engine\napp.set('view engine', 'ejs'); \napp.set('views', path.join(__dirname, 'views'));\n\n<% uses.forEach(function (use) { -%>\napp.use(<%- use %>);\n<% }); -%>\n\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\n<%-platform.toLowerCase()%>PassportStrategy(passport);\n<%_ } _%>\n<%_ } _%>\n\n<% mounts.forEach(function (mount) { -%>\napp.use(<%= mount.path %>, <%- mount.code %>);\n<% }); -%>\n\napp.get('/', (req, res) => {\n  res.render('index');\n})\n\nlet currentFile = __filename\nif (process.env.NODE_ENV !== 'test' ) {\n    <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    models.sequelize.sync({alter:true}).then(()=>{\n        <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes\n        const routes =  require(\"./routes/index\")\n        app.use(routes);\n        <%_ } _%>\n        const allRegisterRoutes = listEndpoints(app);\n        seeder(allRegisterRoutes).then(()=>{console.log(\"Seeding done.\")});\n    })\n    <%_}else if(typeof SEEDER !== \"undefined\" && SEEDER){_%>\n    models.sequelize.sync({}).then(()=>{\n        <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes\n        const routes =  require(\"./routes/index\")\n        app.use(routes);\n        <%_ } _%>\n        seeder().then(()=>{console.log(\"Seeding done.\")});\n    });\n    <%_} else {_%>\n     <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes\n        const routes =  require(\"./routes/index\")\n        models.sequelize.sync({}).then(()=>{\n            app.use(routes)\n        });\n    <%_ } _%>\n    <%_ } _%>\n    app.listen(process.env.PORT,()=>{\n        console.log(`your application is running on ${process.env.PORT}`)\n    });\n}else{\n    module.exports = app\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/config/constant.js.ejs",
    "content": "const JWT={\n    <%_ PLATFORM.forEach(function (plt,index) { _%>\n        <%- plt.toUpperCase() %>_SECRET:\"myjwt<%- plt.toLowerCase() %>secret\",\n    <%_ }); _%>    \n    EXPIRES_IN: <%-TOKEN_EXPIRE_TIME%>\n}\n\nconst USER_ROLE ={\n    <%_ USER_ROLE.forEach(function (role,index) { _%>\n        <%- role %>:<%- index+=1 %>,\n    <%_ }); _%>\n}\n\nconst PLATFORM = {\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>:<%- index+1 %>,\n<%_ }); _%>\n    \n}\n\nlet LOGIN_ACCESS ={\n<% Object.keys(LOGIN_ACCESS).map(function (key,index) { -%>\n    [USER_ROLE.<%- key %>]:<%_ let Arr=[]; LOGIN_ACCESS[key].forEach(function(plt,index){ _%>\n    <%_Arr.push(`PLATFORM.${plt.toUpperCase()}`);_%>\n<%_ }) _%><%-JSON.stringify(Arr).toString().replace(/\"/g, \"\");%>,           \n<% }); -%>\n}\n\nconst DEFAULT_ROLE= 1\n\n<%_if(LOGIN_RETRY_LIMIT){_%>\nconst MAX_LOGIN_RETRY_LIMIT = <%=LOGIN_RETRY_LIMIT.max%>;   \nconst LOGIN_REACTIVE_TIME = <%=LOGIN_RETRY_LIMIT.reActiveTime%>;\n<%_}_%>    \n\n<%_if(RESET_PASSWORD){_%>\nconst FORGOT_PASSWORD_WITH = <%-RESET_PASSWORD%>\n<%_}_%>\n\n<%_if(DEVICE_ALLOWED_REQUIRED){_%>\nconst NO_OF_DEVICE_ALLOWED = <%-NO_OF_DEVICE%>\n<%_}_%>\n    \n<%_ let customRoutes=[]_%>\n<%_if(CUSTOM_ROUTES){_%>\n<%_ for(let platform in CUSTOM_ROUTES){ \n    customRoutes.push(`${platform.toUpperCase()}_CUSTOM_ROUTES`)\n_%>\nconst <%-platform.toUpperCase()%>_CUSTOM_ROUTES = <%=CUSTOM_ROUTES[platform]%>   \n<%_ } _%>\n<%_}_%>\n\nmodule.exports = {\n    JWT,\n    USER_ROLE,\n    DEFAULT_ROLE,\n    PLATFORM,\n    <%_if(LOGIN_RETRY_LIMIT){_%>\n    MAX_LOGIN_RETRY_LIMIT,\n    LOGIN_REACTIVE_TIME,\n    <%_}_%>\n    <%_if(RESET_PASSWORD){_%>\n    FORGOT_PASSWORD_WITH,\n    <%_}_%>\n    LOGIN_ACCESS,\n    <%_if(DEVICE_ALLOWED_REQUIRED){_%>\n    NO_OF_DEVICE_ALLOWED,\n    <%_}_%>\n    <%_ if(CUSTOM_ROUTES){ _%>\n    <%-customRoutes.join()%>\n    <%_ } _%>\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/config/db.js.ejs",
    "content": "if(process.env.NODE_ENV !== 'test'){\n    module.exports = {\n        HOST: process.env.HOST,\n        USER: process.env.DATABASE_USERNAME,\n        PASSWORD: process.env.DATABASE_PASSWORD,\n        DB: process.env.DATABASE_NAME,\n        dialect: <%=ADAPTER%>,\n        port: process.env.DB_PORT,\n    }\n}else{\n    module.exports = {\n        HOST: process.env.TEST_HOST,\n        USER: process.env.TEST_DATABASE_USERNAME,\n        PASSWORD: process.env.TEST_DATABASE_PASSWORD,\n        DB: process.env.TEST_DATABASE_NAME,\n        dialect: <%=ADAPTER%>,\n        port: process.env.TEST_DB_PORT,\n    }\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/config/dbConnection.js.ejs",
    "content": "const { Sequelize, DataTypes } = require('sequelize');\nconst dbConfig = require('../../config/db');\nconst sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {\n  host: dbConfig.HOST,\n  dialect: dbConfig.dialect,\n  port: dbConfig.port,\n});\nmodule.exports = sequelize;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/config/passport.js.ejs",
    "content": "\n/*\n* <%- STRATEGY %> authentication - with passport\n*/\n\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\nconst userModel  = require(\"../model\").<%-MODEL%>\nconst <%-MODEL%>Service = require(\"../services/dbService\")({model:userModel});\nmodule.exports = {\n   <%- STRATEGY.toLowerCase() %>PassportStrategy: passport => {\n       const options = {};\n       options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();\n       options.secretOrKey = JWT.<%- STRATEGY.toUpperCase() %>_SECRET;\n       passport.use('<%- STRATEGY.toLowerCase() %>-rule',\n           new Strategy(options, (payload, done) => {\n            <%-MODEL%>Service.findOne({id: payload.id}).then((user)=>{\n                   if (user) {\n                     return done(null, { ...user.toJSON() });\n                   }\n                   return done('No User Found', {});\n                 }).catch(err => done(err, false))\n           })\n       );\n   }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/config/requestConstant.js.ejs",
    "content": "module.exports=<%=JSON.parse(CONSTANTS)%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/authController.js.ejs",
    "content": "const authConstant = require(\"../../../constants/authConstant\");\nconst response = require('../../../utils/response'); \nconst responseHandler = require('../../../utils/response/responseHandler');  \n\nconst register = (registerUsecase) => async (req,res) => {\n    try{\n        let result = await registerUsecase(req.body);\n        return responseHandler(res,result);\n    }catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nconst forgotPassword = (forgotPasswordUsecase) => async (req,res) => {\n    try{\n        let result = await forgotPasswordUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n    \nconst validateResetPasswordOtp = (validateResetPasswordOtpUsecase) => async (req,res) => {\n    try{\n        let result = await validateResetPasswordOtpUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n    \nconst resetPassword = (resetPasswordUsecase) => async (req,res) => {\n    try {\n        let result = await resetPasswordUsecase(req.body);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\nconst authentication = (authenticationUsecase) => async (req,res)=>{\n    try {\n        let result = await authenticationUsecase(req.body, authConstant.PLATFORM.<%-PLATFORM_NAME.toUpperCase()%>);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nconst logout = (logoutUsecase) => async (req,res) => {\n    try {\n        let user = req.user;\n        let token = req.headers.authorization.token.replace('Bearer ', '');\n        let result = await logoutUsecase(user, token);\n        return responseHandler(res,result);\n    } catch (error) {\n        return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n}\n\nmodule.exports={\n    register,\n    authentication,\n    forgotPassword,\n    resetPassword,\n    validateResetPasswordOtp,\n    logout\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/authControllerIndex.js.ejs",
    "content": "let  <%-MODEL %>Db = require('../../../data-access/<%-MODEL %>Db');\nconst userTokensDb = require(\"../../../data-access/userTokensDb\");\nconst userAuthSettingsDb = require(\"../../../data-access/userAuthSettingsDb\");\n<%_if(ROLE_PERMISSION){_%>\nconst userRoleDb  = require('../../../data-access/userRoleDb');\nconst routeRoleDb  =require('../../../data-access/routeRoleDb');\n<%_}_%>\n\nconst <%-MODEL %>Schema = require('../../../validation/schema/<%-MODEL %>');\nconst createValidation = require('../../../validation')(<%-MODEL %>Schema.createSchema);\n\n\nconst authController = require('./authController');\n\nconst registerUsecase = require('../../../use-case/authentication/register')({ \n        <%-MODEL %>Db, \n        createValidation, \n});\nconst authenticationUsecase = require('../../../use-case/authentication/authentication')({ <%-MODEL %>Db, userTokensDb<%_if(ROLE_PERMISSION){_%>,userRoleDb,routeRoleDb<%_ } _%>});\nconst forgotPasswordUsecase = require('../../../use-case/authentication/forgotPassword')({ <%-MODEL %>Db,userAuthSettingsDb});\nconst resetPasswordUsecase = require('../../../use-case/authentication/resetPassword')({ <%-MODEL %>Db,userAuthSettingsDb});\nconst validateResetPasswordOtpUsecase = require('../../../use-case/authentication/validateResetPasswordOtp')({ <%-MODEL %>Db,userAuthSettingsDb});\nconst logoutUsecase = require('../../../use-case/authentication/logout')({userTokensDb});\n\nconst register = authController.register(registerUsecase);\nconst authentication = authController.authentication(authenticationUsecase);\n\nconst forgotPassword = authController.forgotPassword(forgotPasswordUsecase);\nconst resetPassword = authController.resetPassword(resetPasswordUsecase);\nconst validateResetPasswordOtp = authController.validateResetPasswordOtp(validateResetPasswordOtpUsecase);\nconst logout = authController.logout(logoutUsecase);\n\nmodule.exports={\n    register,\n    authentication,\n    forgotPassword,\n    resetPassword,\n    validateResetPasswordOtp,\n    logout\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/controller.js.ejs",
    "content": "const response = require('../../../utils/response');\nconst responseHandler = require('../../../utils/response/responseHandler'); \nconst {Op} = require(\"sequelize\");\n<%_ var methods = [] _%>\n\n<%_for(let i=0;i< SUPPORT_API.length;i++){ _%>\n  <%_ if(SUPPORT_API[i].method==\"create\") {_%>\n      <%_methods.push('add'+DB_MODEL_FC) _%> \n      const add<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n          try {\n            let dataToCreate = { ...req.body || {} };\n            delete dataToCreate.updatedBy\n            <%_ if(SUPPORT_API[i].isLogin){ _%>\n            dataToCreate.<%-SUPPORT_API[i].addedBy%> = req.user.id.toString();\n            <%_ } _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(dataToCreate);\n              <%_if(SUPPORT_API[i].fieldSelection){_%>\n              result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n              <%_}_%>\n              return responseHandler(res,result);\n            } catch (error) {\n               return responseHandler(res,response.internalServerError({message:error.message}));\n            }\n          };\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n    <%_methods.push('bulkInsert'+DB_MODEL_FC) _%>\n    const bulkInsert<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res)=>{\n      try{\n        let dataToCreate = req.body && req.body.data ? [...req.body.data] : [];\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        dataToCreate.map((item) => { item.<%-SUPPORT_API[i].addedBy%> = req.user.id; return item });\n        <%_ } _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(dataToCreate);\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n          if(result.data.length){\n            for(let i=0;i< result.data.length; i++){\n              result.data[i] = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data[i]);\n            }\n          }\n        <%_}_%>\n        return responseHandler(res,result);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n    }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"partialUpdate\") {_%>\n    <%_methods.push('partialUpdate'+DB_MODEL_FC) _%>\n    const partialUpdate<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) =>  async (req,res) =>{\n        try {\n          if(!req.params.id){\n            return responseHandler(res,response.badRequest());\n          }\n          let query = { id: req.params.id};\n          let dataToUpdate = {...req.body || {}};\n          <%_ if(SUPPORT_API[i].isLogin){ _%>\n          delete dataToUpdate[\"addedBy\"]\n          dataToUpdate.updatedBy=req.user.id\n          <%_ } _%> \n          let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n          <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(Object.keys(result.data).length){\n              result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n            }\n          <%_}_%>\n          return responseHandler(res,result);\n        } catch (error){\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n      }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"update\") {_%>\n    <%_methods.push('update'+DB_MODEL_FC) _%>\n    const update<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) =>{\n      try {\n        if(!req.params.id){\n          return responseHandler(res,response.badRequest());\n        }\n        let dataToUpdate = { ...req.body || {} };\n        let query = { id: req.params.id};\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n          delete dataToUpdate.addedBy;\n          dataToUpdate.updatedBy = req.user.id;\n          <%_ } _%>\n          \n          let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n          <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(Object.keys(result.data).length){\n              result.data = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result.data);\n            }\n          <%_}_%>\n          return responseHandler(res,result);\n        }\n        catch (error){\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n      }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"bulkUpdate\") {_%>\n    <%_methods.push('bulkUpdate'+DB_MODEL_FC) _%>\n    const bulkUpdate<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) =>  async(req,res) =>{\n      try{\n        let dataToUpdate = { ...req.body.data || {} };\n        let query = { ...req.body.filter || {} };\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n          delete dataToUpdate.addedBy;\n          dataToUpdate.updatedBy=req.user.id\n        <%_ } _%>\n        <%_         \n          nestedCalls={}\n          if(SUPPORT_API[i].IS_NESTED_CALL){\n              nestedCalls = SUPPORT_API[i].NESTED_CALLS\n              if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                  for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                  data.filter = <%=JSON.parse(element.filter)%>                                            \n                  <%_}}\n              }                \n          }\n          _%>\n          let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({dataToUpdate,query});\n          return responseHandler(res,result);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n    }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"delete\") {_%>\n    <%_methods.push('delete'+DB_MODEL_FC) _%>\n      const delete<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res)=>{\n        try {\n          if(!req.params.id){\n            return responseHandler(res,response.badRequest());\n          }\n          let query = {id:req.params.id};\n          <%_         \n          nestedCalls={}\n          if(SUPPORT_API[i].IS_NESTED_CALL){\n              nestedCalls = SUPPORT_API[i].NESTED_CALLS\n              if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                  for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                      <%-element.existingVariable%> = <%=JSON.parse(element.filter)%>    \n                  <%_}}\n              }                \n          }\n          _%>\n          return await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,isWarning:req.body.isWarning || false});\n        } catch (error) {\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n      }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"deleteMany\") {_%>\n      <%_methods.push('deleteMany'+DB_MODEL_FC) _%>\n      <%_ if(DELETE_DEPENDENT_MODEL){ _%>\n  const deleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n      try{\n        if(!req.body || !req.body.ids){\n          return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = {id:{[Op.in]: ids}}\n\n        return await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,isWarning:req.body.isWarning || false,req,res});\n        return responseHandler(res,result);\n      }\n      catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n    }\n  <%_ } else { _%>\n  const deleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req, res) => {\n      try{\n        if(!req.body || !req.body.ids){\n          return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = {id:{[Op.in]: ids}};\n\n        let result =  await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query},req,res);\n        return responseHandler(res,result);\n      }\n      catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n  }\n  <%_ } _%>\n  <%_ } _%>\n\n  <%_ if(SUPPORT_API[i].method==\"softDelete\") {_%>\n    <%_methods.push('softDelete'+DB_MODEL_FC) _%>\n    const softDelete<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) =>  async(req,res)=>{\n      try{\n        if(!req.params.id){\n            return responseHandler(res,response.badRequest());\n        }\n        let query = { id: req.params.id};\n        <%_         \n            nestedCalls={}          \n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        <%-element.existingVariable%> = <%=JSON.parse(element.filter)%> \n                    <%_}}\n                }                \n            }\n        _%>\n        let dataToUpdate = {\n            isDeleted: true,\n            <%_if(SUPPORT_API[i].isAuth){ _%>\n            updatedBy: req.user.id,\n            <%_}_%>\n        }\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate,isWarning:req.body.isWarning || false});\n        return responseHandler(res,result);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n    }\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"softDeleteMany\") {_%>\n    <%_methods.push('softDeleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){ _%>\n        const softDeleteMany<%-DB_MODEL_FC%> =  (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n            try{\n                if(!req.body || !req.body.ids){\n                    return responseHandler(res,response.badRequest());\n                }\n                let ids = req.body.ids;\n                let query = {id:{[Op.in]: ids}}\n                let dataToUpdate = {\n                    isDeleted: true,\n                    <%_if(SUPPORT_API[i].isLogin){ _%>\n                    updatedBy: req.user.id,\n                    <%_}_%>\n                }\n\n                if (ids && (Array.isArray(ids) && ids.length > 0)) {\n                    <%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL && SUPPORT_API[i].isAuth){ _%>\n                    let query = {}\n                    if (loggedInUser){\n                        query = {\n                            id: {\n                                [Op.in]: ids,\n                                [Op.ne]: loggedInUser.id\n                            }\n                        }\n                    } else{\n                        return response.badRequest();\n                    }\n                    <%_}else{_%>\n                        let query = {id:{[Op.in]: ids,}}\n                    <%_}_%>\n                    let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate,isWarning:req.body.isWarning || false},req,res);\n                    return responseHandler(res,result);\n                }\n                return response.badRequest();\n            }catch(error){\n                return responseHandler(res,response.internalServerError({message:error.message}));\n            }\n        }\n  <%_ } else { _%>\n  const softDeleteMany<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return responseHandler(res,response.badRequest());\n        }\n        let ids = req.body.ids;\n        let query = {id:{[Op.in]: ids}}\n        let dataToUpdate = {\n            isDeleted: true,\n            <%_if(SUPPORT_API[i].isLogin){ _%>\n            updatedBy: req.user.id,\n            <%_}_%>\n        }\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query= {...query,...<%=JSON.parse(element.filter)%>}\n                    <%_}}\n                }                \n            }\n        _%>\n        let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,dataToUpdate},req,res);\n        return responseHandler(res,result);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n  }\n  <%_ } _%>\n  <%_ } _%>\n\n  <%_ if(SUPPORT_API[i].method==\"findAll\") {_%>\n    <%_methods.push('findAll'+DB_MODEL_FC) _%>\n      const findAll<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async (req,res) => {\n        try {\n            let query= req.body && req.body.query ? {...req.body.query} : {};\n            let options= req.body && req.body.options ? {...req.body.options} : {};\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n            if(options && options.select && options.select.length){\n                options.attributes = <%=SUPPORT_API[i].fields%>.filter(Set.prototype.has, new Set(options.select));\n            }else{\n                options.attributes=<%=SUPPORT_API[i].fields%>\n            }\n            <%_} else {_%>\n            if(options && options.select && options.select.length){\n            options.attributes = options.select;\n            }\n            <%_}_%>\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        <%-element.existingVariable%> = <%=JSON.parse(element.filter)%> \n                    <%_}}\n                }                \n            }\n            _%> \n          let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query,options,isCountOnly:req.body.isCountOnly || false});\n          return responseHandler(res,result); \n        }\n        catch (error){\n          return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n      };\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"findById\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC) _%>\n   const get<%-DB_MODEL_FC%> = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) =>{\n      try {\n        if(!req.params.id){\n            return responseHandler(res,response.badRequest());\n        }\n        let query = { id: req.params.id};\n        let options = {};\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n            let fieldSelect = <%=SUPPORT_API[i].fields%>\n            options.select = {\n                ...options.select,\n                ...fieldSelect\n            }\n        <%_}_%>\n        let result =  await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase({query, options}); \n        return responseHandler(res,result); \n      }\n      catch (error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n    };\n  <%_}_%>\n  <%_ if(SUPPORT_API[i].method==\"count\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC+'Count') _%>\n    const get<%-DB_MODEL_FC%>Count = (<%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase) => async(req,res) => {\n        try {\n          let where = {...req.body.where || {} };\n          <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        where=...<%=JSON.parse(element.filter)%>                      \n                    <%_}}\n                }                \n            }\n          _%>\n            let result = await <%-SUPPORT_API[i].method + DB_MODEL_FC %>Usecase(where); \n            return responseHandler(res,result);  \n        } catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }\n<%_ } _%>\n<%_}_%>\n\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\n  <%_\n  methods.push('changePassword'); \n  methods.push('updateProfile'); \n  methods.push('getLoggedInUserInfo');  _%>\n   \n   const changePassword = (changePasswordUsecase) => async (req,res) => {\n        try{\n            let result = await changePasswordUsecase(req.body);\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    }   \n    const updateProfile = (updateProfileUsecase) => async (req,res) => {\n        try{\n            let result = await updateProfileUsecase(req.body,req.user.id);\n            return responseHandler(res,result);\n        }catch(error){\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }   \n    }\n\n    const getLoggedInUserInfo = (get<%-DB_MODEL_FC%>Usecase) => async (req,res) =>{\n        try {\n            if(!req.user){\n                return responseHandler(res,response.badRequest());\n            }\n            const query = {\n                id : req.user.id,\n                isDeleted: false,\n                isActive:true\n            };\n            let result = await get<%-DB_MODEL_FC%>Usecase({query,options:{}});\n            return responseHandler(res,result);\n        } catch (error) {\n            return responseHandler(res,response.internalServerError({message:error.message}));\n        }\n    };\n  \n<%_}_%>\n\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{ methods.push(v.functionName)_%>\n\n  <%_if(typeof(v.descriptions)!=='undefined'){_%>\n    /* \n    * <%-v.descriptions%>\n    */\n  <%_}_%>\n  const <%-v.functionName%> = (<%-v.functionName%>Usecase) => async(req,res) =>{\n    try{\n      return await <%-v.functionName%>Usecase(req,res);\n    }catch(error){\n      return responseHandler(res,response.internalServerError({message:error.message}));\n    }\n  }\n  <%_});_%>\n<%_}_%>\n\nmodule.exports = {\n    <%-methods.join()%>\n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/controllerIndex.js.ejs",
    "content": "<%_ let usedDb = []; _%>\n<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%> \n    const <%-model%>Db = require('../../../data-access/<%-model %>Db');\n<%_ usedDb.push(model);  }); _%>\n\n<%_ if(!usedDb.includes(DB_MODEL)){_%>\nconst <%-DB_MODEL %>Db = require('../../../data-access/<%-DB_MODEL %>Db');\n<%_ } _%>\n\nconst <%-DB_MODEL %>Schema = require('../../../validation/schema/<%-DB_MODEL %>');\n\nconst createValidation = require('../../../validation')(<%-DB_MODEL %>Schema.createSchema);\nconst updateValidation = require('../../../validation')(<%-DB_MODEL %>Schema.updateSchema);\n\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/create')({ <%-DB_MODEL %>Db,createValidation });\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/update')({ <%-DB_MODEL %>Db, updateValidation });\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/deleteOne')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/findById')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/findAll')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/count')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n        <%_ if(controllerMethod === 'createBulk'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/createBulk')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/updateBulk')({ <%-DB_MODEL %>Db});\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        const <%-controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/deleteMany')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/softDelete')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/softDeleteMany')({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>});\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        const <%- controllerMethod + DB_MODEL_FC %>Usecase = require('../../../use-case/<%-DB_MODEL %>/partialUpdate')({ <%-DB_MODEL %>Db,updateValidation});\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\nconst changePasswordUsecase = require('../../../use-case/<%-DB_MODEL %>/changePassword')({ <%-DB_MODEL %>Db});\nconst updateProfileUsecase = require('../../../use-case/<%-DB_MODEL %>/updateProfile')({ <%-DB_MODEL %>Db,updateValidation});\nconst get<%-DB_MODEL_FC%>Usecase = require('../../../use-case/<%-DB_MODEL %>/findById')({ <%-DB_MODEL %>Db})\n<%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    const <%-v.functionName%>Usecase = require('../../../use-case/<%-DB_MODEL %>/<%-v.functionName%>')({ <%-v.model%>Db});\n  <%_});_%>\n<%_}_%>\n\nconst <%-DB_MODEL %>Controller = require('./<%-DB_MODEL %>');\n\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        const add<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.add<%-DB_MODEL_FC %>(<%-controllerMethod +DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        const update<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.update<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        const delete<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.delete<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        const get<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.get<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        const findAll<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.findAll<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        const get<%-DB_MODEL_FC %>Count = <%-DB_MODEL %>Controller.get<%-DB_MODEL_FC %>Count(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n        <%_ if(controllerMethod === 'createBulk'){ _%>\n        const bulkInsert<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.bulkInsert<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        const bulkUpdate<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.bulkUpdate<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        const deleteMany<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.deleteMany<%-DB_MODEL_FC %>(<%-controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        const softDelete<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.softDelete<%-DB_MODEL_FC %>(<%-controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        const softDeleteMany<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.softDeleteMany<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        const partialUpdate<%-DB_MODEL_FC %> = <%-DB_MODEL %>Controller.partialUpdate<%-DB_MODEL_FC %>(<%- controllerMethod + DB_MODEL_FC %>Usecase);\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\nconst changePassword = <%-DB_MODEL %>Controller.changePassword(changePasswordUsecase);\nconst updateProfile = <%-DB_MODEL %>Controller.updateProfile(updateProfileUsecase);\nconst getLoggedInUserInfo = <%-DB_MODEL %>Controller.getLoggedInUserInfo(get<%-DB_MODEL_FC%>Usecase);\n<%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    const <%-v.functionName%> = <%-DB_MODEL %>Controller.<%-v.functionName%>(<%-v.functionName%>Usecase);\n  <%_});_%>\n<%_}_%>\n\n\n<%_\n// Code For custom route\nlet shouldPassCQ_Imports = false\n_%>\n\nmodule.exports = {\n<%_for(const controllerMethod in CONTROLLER_METHODS){_%>\n    <%_ if(controllerMethod === 'create'){ _%>\n        add<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'update'){ _%>\n        update<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'delete'){ _%>\n        delete<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'findById'){ _%>\n        get<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'findAll'){ _%>\n        findAll<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'count'){ _%>\n        get<%-DB_MODEL_FC %>Count,\n    <%_}_%>\n    <%_ if(controllerMethod === 'createBulk'){ _%>\n        bulkInsert<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'bulkUpdate'){ _%>\n        bulkUpdate<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'deleteMany'){ _%>\n        deleteMany<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDelete'){ _%>\n        softDelete<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'softDeleteMany'){ _%>\n        softDeleteMany<%-DB_MODEL_FC %>,\n    <%_}_%>\n    <%_ if(controllerMethod === 'partialUpdate'){ _%>\n        partialUpdate<%-DB_MODEL_FC %>,\n    <%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){_%>\n    changePassword,\n    updateProfile,\n    getLoggedInUserInfo,\n    <%_}_%>\n<%_if(CUSTOM_ROUTES){_%>\n  <%_CUSTOM_ROUTES.forEach((v,i)=>{_%>\n    <%-v.functionName%>,\n  <%_});_%>\n<%_}_%>\n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/fileUploadController.js.ejs",
    "content": "const response = require('../../../utils/response');\nconst responseHandler = require('../../../utils/response/responseHandler'); \n\nconst upload = (fileUploadUsecase) => async (req,res) => {\n  try {\n    let result = await fileUploadUsecase(req,res);\n    return responseHandler(res,result);\n  } catch (error) {\n    return responseHandler(res,response.internalServerError({message:error.message}));\n  }\n};\n\nmodule.exports = {upload}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/controllers/fileUploadControllerIndex.js.ejs",
    "content": "const fileUploadUsecase = require('<%-USECASE_PATH%>/fileUpload/upload');\nconst fileUploadController = require('./fileUploadController');\n\nconst upload = fileUploadController.upload(fileUploadUsecase);\n\nmodule.exports = { upload };"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/customEnv.ejs",
    "content": "<%_for(const [key,value] of Object.entries(CUSTOM_ENV)) {_%>\n<%-key%>=<%-value%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/data-access/dbFile.js.ejs",
    "content": "let <%-MODEL_NAME_FC-%> = require('../db/sequelize/models').<%-MODEL_NAME-%>;\nlet { create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,\n} = require('../db/sequelize/dbService')(<%-MODEL_NAME_FC-%>);\n\nmodule.exports = {\n    create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,   \n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/data-access/dbService.js",
    "content": "/* eslint-disable */\nconst { Op } = require('sequelize');\nconst models = require('./models');\n\nconst OPERATORS = ['$and', '$or', '$like', '$in', '$eq', '$gt', '$lt', '$gte', '$lte', '$any', '$between'];\n\nmodule.exports = function sequelizeDbService (Model) {\n  function queryBuilderParser (data) {\n    if (data) {\n      Object.entries(data).forEach(([key]) => {\n        if (typeof data[key] === 'object') {\n          queryBuilderParser(data[key]);\n        }\n        if (OPERATORS.includes(key)) {\n          const opKey = key.replace('$', '');\n          data[Op[opKey]] = data[key];\n          delete data[key];\n        } else if (key === '$ne') {\n          data[Op.not] = data[key];\n          delete data[key];\n        } else if (key === '$nin') {\n          data[Op.notIn] = data[key];\n          delete data[key];\n        }\n      });\n    }\n    return data;\n  }\n\n  function sortParser (input) {\n    const newSortedObject = [];\n    if (input) {\n      Object.entries(input).forEach(([key, value]) => {\n        if (value === 1) {\n          newSortedObject.push([key, 'ASC']);\n        } else if (value === -1) {\n          newSortedObject.push([key, 'DESC']);\n        }\n      });\n    }\n    return newSortedObject;\n  }\n\n  const create = async (data) => Model.create(data);\n\n  const createMany = async (data) => Model.bulkCreate(data);\n\n  const updateOne = async (filter, data) => {\n    filter = queryBuilderParser(filter);\n    const recordToUpdate = await Model.findOne({ where: filter });\n    const query = { [Model.primaryKeyField]: recordToUpdate[Model.primaryKeyField] };\n    await Model.update(data, { where: query });\n    return Model.findOne({ where: filter });\n  };\n\n  const updateMany = async (filter, data) => {\n    filter = queryBuilderParser(filter);\n    const [noOfUpdatedRecords] = await Model.update(data, { where: filter });\n    if (noOfUpdatedRecords > 0) {\n      return Model.findAll({ where: filter });\n    }\n    return null;\n  };\n\n  const deleteOne = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    const recordToDelete = await Model.findOne({ where: filter });\n    const query = { [Model.primaryKeyField]: recordToDelete[Model.primaryKeyField] };\n    return Model.destroy({\n      where: query,\n      ...options,\n    });\n  };\n\n  const deleteMany = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    const noOfDeletedRecords = await Model.destroy(filter, options);\n    return noOfDeletedRecords;\n  };\n\n  const softDelete = async (filter, data = { isDeleted: true }) => {\n    filter = queryBuilderParser(filter);\n    const recordToUpdate = await Model.findOne({ where: filter });\n\n    const query = { [Model.primaryKeyField]: recordToUpdate[Model.primaryKeyField] };\n    await Model.update(data, { where: query });\n    return Model.findOne({ where: query });\n  };\n\n  const softDeleteMany = async (filter) => {\n    filter = queryBuilderParser(filter);\n    return Model.update({ isDeleted: true }, {\n      where: filter,\n      returning: true,\n    });\n  };\n\n  const findOne = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    if (options && options.select && options.select.length) {\n      options.attributes = options.select;\n      delete options.select;\n    }\n    if (options && options.include && options.include.length) {\n      const include = [];\n      options.include.forEach((i) => {\n        i.model = models[i.model];\n        if (i.query) {\n          i.where = queryBuilderParser(i.query);\n        }\n        include.push(i);\n      });\n      options.include = include;\n    }\n    options = {\n      where: filter,\n      ...options,\n    };\n    return Model.findOne(options);\n  };\n\n  const findMany = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    if (options && options.select && options.select.length) {\n      options.attributes = options.select;\n    }\n    if (options && options.sort) {\n      options.order = sortParser(options.sort);\n      delete options.sort;\n    }\n    if (options && options.include && options.include.length) {\n      const include = [];\n      options.include.forEach((i) => {\n        i.model = models[i.model];\n        if (i.query) {\n          i.where = queryBuilderParser(i.query);\n        }\n        include.push(i);\n      });\n      options.include = include;\n    }\n    options = {\n      where: filter,\n      ...options,\n    };\n    return Model.findAll(options);\n  };\n\n  const paginate = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    if (options && options.sort) {\n      options.order = sortParser(options.sort);\n      delete options.sort;\n    }\n    if (options && options.include && options.include.length) {\n      const include = [];\n      options.include.forEach((i) => {\n        i.model = models[i.model];\n        if (i.query) {\n          i.where = queryBuilderParser(i.query);\n        }\n        include.push(i);\n      });\n      options.include = include;\n    }\n    options = {\n      where: filter,\n      ...options,\n    };\n    return Model.paginate(options);\n  };\n\n  const count = async (filter, options = {}) => {\n    filter = queryBuilderParser(filter);\n    options = {\n      where: filter,\n      ...options,\n    };\n    return Model.count(options);\n  };\n\n  const upsert = async (data, options = {}) => Model.upsert(data, options);\n\n  return Object.freeze({\n    create,\n    createMany,\n    updateOne,\n    updateMany,\n    deleteOne,\n    deleteMany,\n    softDelete,\n    softDeleteMany,\n    findOne,\n    findMany,\n    paginate,\n    count,\n    upsert,\n\n  });\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/entity/entity.js.ejs",
    "content": "module.exports = (<%-ENTITY_NAME-%>) => {\n\n    let new<%-ENTITY_NAME_FC-%> = { \n        <%_ for(const key of ENTITY_KEYS){ _%>\n                <%-key%>: <%-ENTITY_NAME-%>.<%-key%>,\n        <%_} _%>  \n    };\n\n    // remove undefined values\n    if(new<%-ENTITY_NAME_FC-%>.id){\n        Object.keys(new<%-ENTITY_NAME_FC-%>).forEach(key =>{\n            if(new<%-ENTITY_NAME_FC-%>[key] === undefined) return new<%-ENTITY_NAME_FC-%>[key]=null\n        });\n    }else{\n        Object.keys(new<%-ENTITY_NAME_FC-%>).forEach(key => new<%-ENTITY_NAME_FC-%>[key] === undefined && delete new<%-ENTITY_NAME_FC-%>[key]);\n    }\n\n    // To validate Entity uncomment this block\n\n    /* const validate = (new<%-ENTITY_NAME_FC-%>) => {\n         if (!new<%-ENTITY_NAME_FC-%>.field) {\n             throw new Error(\"this field is required\");\n         }\n    }\n    \n    validate(new<%-ENTITY_NAME_FC-%>) */\n    return Object.freeze(new<%-ENTITY_NAME_FC-%>);\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/helpers/date.js",
    "content": "const getDifferenceOfTwoDatesInTime = (currentDate, toDate) => {\n  const hours = toDate.diff(currentDate, 'hour');\n  currentDate = currentDate.add(hours, 'hour');\n  const minutes = toDate.diff(currentDate, 'minute');\n  currentDate = currentDate.add(minutes, 'minute');\n  const seconds = toDate.diff(currentDate, 'second');\n  currentDate = currentDate.add(seconds, 'second');\n  if (hours) {\n    return `${hours} hour, ${minutes} minute and ${seconds} second`;\n  }\n  return `${minutes} minute and ${seconds} second`;\n};\n\nmodule.exports = { getDifferenceOfTwoDatesInTime };\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/controller.js.ejs",
    "content": "const response = require('../../../utils/response');\nconst responseHandler = require('../../../response/responseHandler'); \n\n<%_ROUTES.forEach((v,i)=>{_%>\n  const <%-v.functionName%> = (<%-v.functionName%>Usecase) => async(req,res) =>{\n      try{\n        return await <%-v.functionName%>Usecase(req,res);\n      }catch(error){\n        return responseHandler(res,response.internalServerError({message:error.message}));\n      }\n  }\n<%_})_%>\n\nmodule.exports = {\n  <%_ROUTES.forEach((v,i)=>{_%>\n  <%-v.functionName%>,\n  <%_})_%>\n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/controllerIndex.js.ejs",
    "content": "<%_\nlet models = UNIQ_TASK_MODELS\nlet modelFC=\"\"\nif(models){ _%>\n  <%_ for(const model of models){ _%>\n    const <%-model%>Db = require(\"<%-DATA_ACCESS_PATH%>/<%-model%>Db\")\n  <%_ } _%> \n<%_ }_%> \n\n\n<%_ ROUTES.forEach((v,i)=>{ _%>\n  <%_if(typeof(v.model) !== 'undefined' && v.model !== null){_%>\n  const <%-v.functionName%>Usecase = require('<%-USECASE_PATH%>/<%-v.model%>/<%-v.functionName%>')({<%_ if(v.cq_model && v.cq_model.length) { for( let i=0;i< v.cq_model.length;i++) { _%> <%- v.cq_model[i] %>Db, <%_ } }_%>});\n  <%_}else{_%>\n  const <%-v.functionName%>Usecase = require('<%-USECASE_PATH%>/customRoutes/<%-v.functionName%>')({<%_ if(v.cq_model && v.cq_model.length) { for( let i=0;i< v.cq_model.length;i++) { _%> <%- v.cq_model[i] %>Db, <%_ } }_%>});\n  <%_}_%>\n<%_})_%>\n\nconst <%-SERVICE_NAME %>Controller = require('./<%-SERVICE_NAME %>');\n\n<%_ ROUTES.forEach((v,i)=>{_%>\n  const <%-v.functionName%> = <%-SERVICE_NAME %>Controller.<%-v.functionName%>(<%-v.functionName%>Usecase);\n<%_})_%>\n\nmodule.exports = {<%_ROUTES.forEach((v,i)=>{_%>\n  <%-v.functionName%>,\n<%_})_%>}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/existIndexRoute.js.ejs",
    "content": "<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/<%-v%>\",require(\"./<%-v%>/index\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/indexRoutes.js.ejs",
    "content": "\n<%_ ROUTES.forEach(function(route){ _%>\n    router.use(\"/<%-route%>\",require(\"./<%-route%>Routes\"))\n<%_ })_%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/platformIndexRoutes.js.ejs",
    "content": "const express = require(\"express\")\nconst router =  express.Router()\n\n<%_ CONTROLLERS.forEach(function(controller){ _%>\nrouter.use(\"/\",require(\"./<%-controller%>Routes\"))\n<%_ })_%>\n\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/route.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\nconst <%- SERVICE_NAME%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-SERVICE_NAME%>\");\nconst responseHandler = require(\"../../utils/response/responseHandler\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_\nif(POLICIES && POLICIES.length){\n POLICIES.forEach((policy)=>{_%>\nconst <%-policy%> = require(\"../../middleware/<%-policy%>\")\n<%_}) }_%>\n<%_\nif(typeof(CONTROLLER_IMPORTS) !== 'undefined' ){\nObject.keys(CONTROLLER_IMPORTS).forEach(function(key) { _%>\nconst <%-key%> = require(\"<%-CONTROLLER_IMPORTS[key]%>\")\n<%_ }); } _%> \n\n<%_ ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>( <%_if(v.policies && v.policies.length){_%>\n  <%_v.policies.forEach((policy)=>{_%>\n  <%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n  <%_}else{_%>\n  <%-policy%>,<%_}_%>\n  <%_})_%>\n  <%_}_%><%-v.controller%>Controller.<%- v.functionName %>);\n<%_})_%>\n    \nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/individualRoutes/service.js.ejs",
    "content": "<%_ROUTES.forEach((v,i)=>{_%>\n/* \n* <%-v.descriptions%>\n*/\nconst <%-v.functionName%>=()=>{\n    try {\n        console.log(\"<%-v.functionName%> service called\")\n        return true;\n    } catch (error) {\n        throw error;\n    }\n}    \n<%_ })_%>\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: middleware that checks authentication and authorization of user\n */\n\nconst { LOGIN_ACCESS,PLATFORM\n<%_if(CUSTOM_ROUTES){_%><%_ for(let platform in CUSTOM_ROUTES){ _%>\n,<%-platform.toUpperCase()%>_CUSTOM_ROUTES  \n<%_ } _%>\n<%_}_%>\n} = require('../constants/authConstant');\nconst responseHandler = require('../utils/response/responseHandler');\nconst { unAuthorized } = require('../utils/response');\n\n\nconst verifyCallback = (userTokensDb, req, resolve, reject, platform) => async (error, user, info) => {\n    if (error || info || !user) {\n        return reject(\"Unauthorized User\");\n    }\n    req.user = user;\n    if (!user.isActive) {\n        return reject(\"User is deactivated\");\n    }\n    let userToken = await userTokensDb.findOne({token:(req.headers.authorization).replace('Bearer ',''),userId:user.id});\n    if (!userToken){\n        return reject('Token not found');\n    }\n    if (userToken.isTokenExpired){\n        return reject('Token is Expired');\n    }\n    if (user.role) {\n        let allowedPlatforms = LOGIN_ACCESS[user.role] ? LOGIN_ACCESS[user.role] : [];\n        if (!allowedPlatforms.includes(platform)) {\n            return reject('Unauthorized user');\n        }\n    }\n    resolve();\n};\n\nconst auth = ({passport, userTokensDb}) => (platform) => async (req, res, next) => {\n<% var c = 0; %>\n    <% PLATFORM.forEach((v)=>{ c++;  %>\n        <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                return new Promise((resolve, reject) => {\n                    passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(userTokensDb,req, resolve, reject, platform))(\n                        req,\n                        res,\n                        next\n                    );\n                })\n                .then(() => next())\n                .catch((err) => {\n                    responseHandler(res,unAuthorized());\n                 });\n            }\n        <%_ }else{ _%>\n            else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                return new Promise((resolve, reject) => {\n                    passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(userTokensDb,req, resolve, reject, platform))(\n                        req,\n                        res,\n                        next\n                    );\n                })\n                .then(() => next())\n                .catch((error) => {\n                    responseHandler(res,unAuthorized())\n                 });\n            }\n        <%_ } _%> \n    <%  }) %>\n   \n};\n\nmodule.exports = auth;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/checkRolePermission.js.ejs",
    "content": "/**\n * checkRolePermission.js\n * @description :: middleware that checks access of APIs of logged-in user\n */\nconst response = require('../utils/response');\nconst responseHandler = require('../utils/response/responseHandler');\n\nconst checkRolePermission = ({userRoleDb, routeRoleDb,projectRouteDb}) =>async (req, res, next) => {\n  if (!req.user) { \n    return responseHandler(res, response.unAuthorized());\n  }\n    const loggedInUserId = req.user.id;\n    let rolesOfUser = await userRoleDb.findMany({ userId: loggedInUserId, isActive: true, isDeleted: false }, {\n      roleId: 1,\n      id: 0,\n    });\n\n    if (rolesOfUser && rolesOfUser.data && rolesOfUser.data.length) {\n      rolesOfUser = [...new Set((rolesOfUser.data).map((item) => item.roleId))];\n      const route = await projectRouteDb.findOne({\n        route_name: replaceAll((req.route.path.toLowerCase()).substring(1), '/', '_'),\n        uri: req.route.path.toLowerCase(),\n      });\n\n      if (route) { \n        const allowedRoute = await routeRoleDb.findOne({\n          routeId: route.id,\n          roleId: { $in: rolesOfUser },\n          isActive: true,\n          isDeleted: false,\n        });\n        if (allowedRoute && allowedRoute.data && allowedRoute.data.length) {\n          next();\n        } else {\n          return responseHandler(res, response.unAuthorized());\n        }\n      }else{\n        next();\n      }\n    }else{\n      next();\n    } \n}\n\n\nfunction replaceAll(string, search, replace) {\n  return string.split(search).join(replace);\n};\n\nmodule.exports = checkRolePermission;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/index.js.ejs",
    "content": "let <%-USER_MODEL%>Db = require('../data-access/<%-USER_MODEL%>Db');\nlet userTokensDb = require('../data-access/userTokensDb');\nlet userRoleDb = require('../data-access/userRoleDb');\nlet routeRoleDb = require('../data-access/routeRoleDb');\nlet projectRouteDb = require('../data-access/projectRouteDb');\nconst passport = require('passport');\n\nconst auth = require('./auth')({ passport, userTokensDb });\nconst checkRolePermission = require('./checkRolePermission')({ userRoleDb, routeRoleDb,projectRouteDb});\n\n<%_for(let platform of PLATFORMS){_%>  \nconst <%-platform%>PassportStrategy = require('./<%-platform%>PassportStrategy')({ <%-USER_MODEL%>Db });\n<%_}_%>   \n\n\nmodule.exports = {\n  auth,\n  checkRolePermission,\n  <%_for(let platform of PLATFORMS){_%>  \n  <%-platform%>PassportStrategy,\n<%_}_%> \n};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/loginUser.js.ejs",
    "content": "const jwt = require(\"jsonwebtoken\");\nconst message = require(\"../utils/messages\");\nconst responseCode = require(\"../utils/responseCode\")\nconst responseHandler = require(\"../utils/response/responseHandler\");\n<%_ PLATFORM.forEach((v)=>{ _%>\nconst <%-v%>Secret = require(\"../constants/authConstant\").JWT.<%-v.toUpperCase()%>_SECRET;\n<%_ }) _%>    \nconst authenticateJWT = (platform) => async (req, res, next) => {\n    const authHeader = req.headers.authorization;\n    if (authHeader) {\n        const token = authHeader.split(' ')[1];\n        let url = req.originalUrl;\n        let secret = '';\n        <%_ var c = 0; PLATFORM.forEach((v)=>{ c++;  _%>\n            <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                secret = <%-v%>Secret;\n            }\n            <%_ }else{ _%>\n            else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                secret = <%-v%>Secret;\n            }\n            <%_ } _%> \n        <%_  }) _%>\n        jwt.verify(token,secret, (err, user) => {\n            if (err) {\n                responseHandler(res,message.unAuthorized())\n            }\n            req.user = user;\n            next();\n        });\n    } else {\n        responseHandler(res,message.unAuthorized())\n    }\n};\nmodule.exports = authenticateJWT"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/passport.js.ejs",
    "content": "\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\n\nconst <%- STRATEGY.toLowerCase() %>PassportStrategy = ({ userDb }) => async (passport) => {\n     const options = {};\n     options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); \n     options.secretOrKey = JWT.<%- STRATEGY.toUpperCase() %>_SECRET;\n\n\n        \n    passport.use('<%- STRATEGY.toLowerCase() %>-rule',\n        new Strategy(options, async (payload, done) => {            \n            try {\n              const user = await userDb.findOne({ id: payload.id });\n              if (user) {\n                return done(null, { ...user.toJSON() });\n              }\n              return done('No User Found', {});\n            } catch (error) {\n              return done(err,{});\n            }\n        })\n    );\n}\nmodule.exports = <%- STRATEGY.toLowerCase() %>PassportStrategy;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/middleware/sampleMiddleware.js.ejs",
    "content": "<%_if(POLICY.code){_%>\n<%-POLICY.code%>\n<%_}else{_%>\nconst <%-POLICY.functionName%>=(req,res,next)=>{\n    try {\n        next();\n    } catch (error) {\n        throw error;\n    }\n}\n    \nmodule.exports=<%-POLICY.functionName%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/models/index.js.ejs",
    "content": "const dbConnection=require(\"../dbConnection\")\nconst db={}\ndb.sequelize = dbConnection\n\n<%\nObject.keys(RELATIONSHIPS).map(d => {\n    modelName = `db.${d} = require('./${d}')(dbConnection);`;\n    if(modelName){\n%>\n        <%- modelName%>\n<%\n    }\n});    \n%>\n<%_ Object.keys(RELATIONSHIPS).map(d => {\nif(Array.isArray(RELATIONSHIPS[d])){\n    RELATIONSHIPS[d].length ? RELATIONSHIPS[d].forEach(m => { \n_%>\n<%_if(m.relType === 'HAS_ONE') {_%>\n    db.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\n    db.<%- d %>.hasOne(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}else if(m.relType === 'HAS_MANY'){_%>\n    db.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\n    db.<%- d %>.hasMany(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}else{_%>\n    db.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\n    db.<%- d %>.hasMany(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}_%>\n<%_ \n    }) : [] \n}});\n_%>\n\n<%_\nif(VIRTUAL_RELATION!==undefined){\n(Object.keys(VIRTUAL_RELATION)).forEach(model => {\n    if(Array.isArray(VIRTUAL_RELATION[model])){\n        const vrs = VIRTUAL_RELATION[model];\n        vrs.forEach((vr) => {\n          const data = `db.${model}.hasMany(db.${vr.ref}, { foreignKey: \"${vr.foreignField}\" })`;\n          _%>\n          <%-data%>\n          <%_\n        });\n    }\n})\n}\n_%>\nmodule.exports = db;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/models/model.js.ejs",
    "content": "const { DataTypes } = require('sequelize');\n<%_if(USER){ _%> \nconst bcrypt = require('bcrypt');\n<%_}_%> \n<%_if(MODEL_ENUM){_%>\n<%_let a=[]_%>    \n<%_for(let i in MODEL_ENUM){_%>\n<%_if(MODEL_ENUM[i].enumFile){_%>\n<%_if(!a.includes(MODEL_ENUM[i].enumFile)){_%>\n<%_a.push(MODEL_ENUM[i].enumFile)_%>\nconst <%-MODEL_ENUM[i].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i].enumFile%>\")\n<%_}_%>        \n<%_}_%>\n<%_}_%>\n<%_}_%>\n<%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n<%_if(typeof FLAG !== \"undefined\"){_%>    \nconst dayjs = require('dayjs');\n<%_}_%>\n<%_}_%>        \nconst sequelizePaginate = require('sequelize-paginate');\nconst sequelizeTransforms = require('sequelize-transforms');\nconst { convertObjectToEnum } = require('../../../utils/common');\nfunction makeModel (sequelize){\n    <%_ var model = DB_SCHEMA _%>\n    <%_ var modelArr = Object.keys(model)_%>\n    const <%-DB_MODEL_FC%> = sequelize.define(\"<%-DB_MODEL%>\",{\n    <%_ for(let v in model){ _%>\n    <%_if(MODEL_ENUM && MODEL_ENUM[v]){_%>\n        <%model[v].values=`convertObjectToEnum(${MODEL_ENUM[v].enumFile}Enum`%>\n        <%model[v].values+=`.${MODEL_ENUM[v].values})`%>\n        <%_if(MODEL_ENUM[v].defaultValue){_%>\n        <%_ if( Array.isArray(MODEL_ENUM[v].defaultValue)){ _%>\n            <% model[v].defaultValue=`${MODEL_ENUM[v].enumFile}Enum` %>\n            <% model[v].defaultValue+=`.${MODEL_ENUM[v].values}` %>\n            <% model[v].defaultValue+=`[${MODEL_ENUM[v].defaultValue[0]}]` %>       \n        <% }else { %>\n                <% model[v].defaultValue=`${MODEL_ENUM[v].enumFile}Enum` %>\n                <% model[v].defaultValue+=`.${MODEL_ENUM[v].values}` %>\n                <% model[v].defaultValue+=`.${MODEL_ENUM[v].defaultValue}` %>\n        <% } %>\n     <%_}_%>\n    <%_}_%>  \n    <%_ let jsonStr = JSON.stringify(model[v]);\n            var finalStr = new String();\n            finalStr = jsonStr.toString().replace(/\"/g, \"\");\n            finalStr = finalStr.replace(/@@/g, '\"').replace('`${',\"\").replace('}`',\"\");\n        _%>\n    <%_ if(modelArr[modelArr.length-1]!==v){ _%>\n        <%-v%>:<%-finalStr%>,\n    <%_}else{_%>\n        <%-v%>:<%-finalStr%>\n    <%_ } _%><%_ } _%>}\n    <%_ if(typeof HOOKS !== \"undefined\") { _%>\n    ,{hooks:{\n    <%_ for(let [key,value] of Object.entries(HOOKS)){_%>\n        <%-key%>: [\n        <%_for(let i=0;i<value.length;i++){_%>\n        async function(<%-DB_MODEL%>,options){\n            <%-value[i].code%>\n        },\n        <%_}_%> \n        ],\n    <%_}_%> \n    } \n    <%_ } _%>\n<%_ if(typeof INDEX !== \"undefined\" && INDEX.length !== 0) { _%>\n    ,indexes:  <%- JSON.stringify(INDEX) %>\n<%_ } _%>\n    }\n    );\n    <%_if(typeof USER!== undefined && USER){ _%>\n    <%-DB_MODEL_FC%>.prototype.isPasswordMatch = async function (password) {\n            const user = this;\n            return bcrypt.compare(password, user.<%-PASSWORD%>);\n        }\n     <%_ } _%>\n    <%-DB_MODEL_FC%>.prototype.toJSON = function () {\n        var values = Object.assign({}, this.get());\n        <%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n        <%_for(index of CONCAT_HOOK){_%>\n        <%_for(formateIndex in index){_%>\n        <%_if(typeof (index[formateIndex])==='object'){_%>\n        if(values.<%-formateIndex%>){\n            values.<%-formateIndex%>=<%=index[formateIndex].true%>;\n        }else{\n            values.<%-formateIndex%>=<%=index[formateIndex].false%>;\n        }\n        <%_}else{_%>    \n        <%_if(index[formateIndex].includes('concat')){_%>\n        if(values.<%-STRING_ATT[0]%> && values.<%-STRING_ATT[1]%>){\n            values.<%-formateIndex%>=<%-index[formateIndex]%>;\n        }  \n        <%STRING_ATT.shift()%>\n        <%STRING_ATT.shift()%>        \n        <%_}else{_%>\n        values.<%-formateIndex%>=<%-index[formateIndex]%>;\n        <%_}_%>        \n        <%_}_%>\n        <%_}_%>   \n        <%_}_%>   \n        <%_}_%>            \n        <%_if(IS_PRIVATE_ATTR !== null && IS_PRIVATE_ATTR === true) {_%>\n            <%_if(PRIVATE_ATTRS !== null && PRIVATE_ATTRS) {_%>\n                <%_Object.keys(PRIVATE_ATTRS).map((t) => {_%>            \n                    <%_if(PRIVATE_ATTRS[t]) {_%>            \n                        delete values.<%-t%>\n                    <%_}_%>        \n                <%_});_%>        \n            <%_}_%>    \n        <%_}_%>\n    \n        return values;\n    }\n    sequelizeTransforms(<%-DB_MODEL_FC%>);\n    sequelizePaginate.paginate(<%-DB_MODEL_FC%>);\n    return <%-DB_MODEL_FC%>;\n}\nmodule.exports = makeModel;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/auth.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\n<%_if(SOCIAL_PLATFORMS.length){ _%>\nconst session = require('express-session');\n<%_}_%>\nconst responseHandler = require('../../utils/response/responseHandler');\nconst {auth} = require('../../middleware');\nconst authController = require(\"../../controller/<%-PLATFORM%>/authentication\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\nrouter.post(\"/register\",authController.register);\nrouter.post('/login',authController.authentication);\nrouter.post(\"/forgot-password\",authController.forgotPassword);\nrouter.post(\"/validate-otp\",authController.validateResetPasswordOtp);\nrouter.put(\"/reset-password\",authController.resetPassword);\n<%_if(SOCIAL_PLATFORMS.length) { \n  SOCIAL_PLATFORMS.forEach(s=>{ _%>\nrouter.get(\"/<%-s.toLowerCase()%>\",(req,res)=>{\nreq.session.platform = <%=PLATFORM%>\nres.redirect(`http://localhost:${process.env.PORT}/auth/<%-s.toLowerCase()%>`);\n})\n<%_})_%>\n<%_}_%>\nrouter.post('/logout',auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),authController.logout);\n  \nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/commonIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n\n<%_PLATFORM.forEach((p) =>{ _%>\nrouter.use(require(\"./<%-p%>Routes\"));\n<%_ }) _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/index.js.ejs",
    "content": "const express = require(\"express\")\nconst router =  express.Router()\n<%_ if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimit=require('express-rate-limit');\n<%_ } _%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimiter=rateLimit({\n    windowMs:<%-REACTIVE_TIME%>*60*1000,\n    max:<%-LOGIN_RATE%>,\n    message: \"Too many API calls from this IP, please try again after a <%-REACTIVE_TIME%> minutes\"\n});\n<%_}_%>\n\n<%_for(let module in PLATFORM){_%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nrouter.use(rateLimiter,require(\"./<%-module%>/index\"));  \n<%_} else {_%> \nrouter.use(require(\"./<%-module%>/index\"));\n<%_}_%>\n<%_}_%>\n\n\nmodule.exports =router\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/modelRoutes.js.ejs",
    "content": "const express = require('express');\nconst router = express.Router();\nconst <%-DB_MODEL%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-DB_MODEL%>\");\n<%_ if(CONTROLLERS_TO_IMPORT && CONTROLLERS_TO_IMPORT.length){ _%>\n<%_ for(let i=0;i < CONTROLLERS_TO_IMPORT.length;i++){ \n    if(CONTROLLERS_TO_IMPORT[i] != DB_MODEL){ _%>\nconst <%-CONTROLLERS_TO_IMPORT[i]-%>Controller = require('../../controller/<%-CONTROLLERS_TO_IMPORT[i]-%>');\n<%_ } }_%>  \n<%_ } _%> \n<%_ if(CUSTOM_POLICY.length){ \n    if(CUSTOM_POLICY.includes('auth')){ let arrayIndex = CUSTOM_POLICY.indexOf('auth'); delete CUSTOM_POLICY[arrayIndex]; CUSTOM_POLICY =  CUSTOM_POLICY.filter(Boolean);}\n_%><%_ } _%>\n<%_ if(IS_AUTH){ _%>\nconst { auth, <%_for(let i=0;i < CUSTOM_POLICY.length;i++){_%><%-CUSTOM_POLICY[i]-%>,<%_}_%> } = require(\"../../middleware\");\n<%_ }else{ _%>\n<%_ for(let i=0;i < CUSTOM_POLICY.length;i++){ _%>\nconst <%-CUSTOM_POLICY[i]-%> = require('../../middleware/<%-CUSTOM_POLICY[i]-%>');\n<%_ } _%> <%_ } _%> \nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/me').get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.getLoggedInUserInfo);\n<%_ } _%>\n<%_ } _%>\n<%_ for(let i=0; i < SUPPORT_API.length; i++){ _%>\n<%_ if(SUPPORT_API[i].method==\"create\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/create').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/create').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/addBulk').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/addBulk').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/list').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/list').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/:id').get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/:id').get(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"count\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/count').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/count').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ } _%><%_ } _%>\n<%_if(SUPPORT_API[i].method==\"update\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/update/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)   \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/update/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)  \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"partialUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/partial-update/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)   \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/partial-update/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)  \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"bulkUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/updateBulk').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>) \n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/updateBulk').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"delete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/delete/:id').delete(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/delete/:id').delete(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"deleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/deleteMany').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/deleteMany').post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDelete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDelete/:id').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDelete/:id').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDeleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDeleteMany').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_ }else{ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/softDeleteMany').put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>)\n<%_}_%><%_}_%>\n<%_}_%>\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){ _%>\nrouter.route('/<%-ROUTE_PREFIX%>/change-password').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.changePassword);\nrouter.route('/<%-ROUTE_PREFIX%>/update-profile').put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.updateProfile);\n<%_ } _%>\n<%_ } _%>\n<%_if(CUSTOM_ROUTES && CUSTOM_ROUTES.length){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n<%_}else{_%>\n<%-policy%>,<%_}_%>\n<%_})_%>\n<%_}_%><%-v.controller%>Controller.<%-v.functionName%>)\n<%_})_%> \n<%_}%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/platformIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n<%_ if(IS_AUTH){ _%>\nrouter.use(\"/<%-PLATFORM_NAME.toLowerCase()%>/auth\",require(\"./auth\"));\n<%_ } _%>\n<%_ for(let i in PLATFORM){ _%>\nrouter.use(require(\"./<%-i%>Routes\"));\n<%_}_%>  \n<%_if(typeof ROUTES!==\"undefined\"){_%>\n<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.controller%>Routes\"));\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/routes/uploadRoutes.js.ejs",
    "content": "let express = require('express');\nlet router = express.Router();\nconst fileUploadController = require(\"../../controller/<%-PLATFORM%>/fileUpload/fileUploadController\");\n<%_ if(IS_AUTH){ _%>\nconst { auth } = require('../../middleware');\n<%_ } _%>\nconst { PLATFORM }=require('../../constants/authConstant')\n\n<%_ if(IS_AUTH){ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/upload\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.upload);\n<%_ }else{ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/upload\").post(fileUploadController.upload);\n<%_ } _%>\n<%_ if(S3_UPLOAD_PRIVATE){_%>\n<%_ if(IS_AUTH){ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.generatePreSignedURL);\n<%_ }else{ _%>\nrouter.route(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\").post(fileUploadController.generatePreSignedURL);\n<%_ } _%>\n<%_ } _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/seeders/index.js.ejs",
    "content": "<%_if(IS_AUTH){_%>\n  const bcrypt = require('bcrypt') \n  const <%-AUTH_MODEL%>DbService = require('../data-access/<%-AUTH_MODEL%>Db');\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    const authConstant=require('../constants/authConstant');\n    const userRoleDbService = require('../data-access/userRoleDb');\n    const routeRoleDbService = require('../data-access/routeRoleDb');\n    const projectRouteDbService = require('../data-access/projectRouteDb');\n    const roleDbService = require('../data-access/roleDb');\n    const replaceAll = require('../utils/replaceAll')\n  <%_}_%>\n<%_}_%>\n<%_if(IS_AUTH){_%>\n    async function seedUser() {\n      try{\n        let userToBeInserted = {}\n        <%_for(let i in USER_EXIST_CONDITION){_%>\n          userToBeInserted = await <%-AUTH_MODEL%>DbService.findOne(<%-JSON.stringify(USER_EXIST_CONDITION[i])%>);\n          <%_var finalStr = new String();\n            USER[i].role=`@@authConstant.USER_ROLE.${ROLE_NAME[i]}@@`;\n            finalStr = JSON.stringify(USER[i]);\n            finalStr = finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\");\n          _%>\n          if (!userToBeInserted) {  \n            userToBeInserted = <%-finalStr%>\n            await <%-AUTH_MODEL%>DbService.create(userToBeInserted);\n          }else{\n            userToBeInserted = <%-finalStr%>\n            userToBeInserted.password = await bcrypt.hash(userToBeInserted.password, 8)\n            await <%-AUTH_MODEL%>DbService.updateByQuery(<%-JSON.stringify(USER_EXIST_CONDITION[i])%>, userToBeInserted);\n          }\n        <%_}_%>\n        console.info('User model seeded 🍺');\n      }catch(error){\n        console.log('User seeder failed due to ', error.message)\n      }   \n    }\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    async function seedRole() {\n      try {\n        const roles = <%=ROLES%>;\n        const insertedRoles = await roleDbService.findMany({ code: { '$in': roles.map(role => role.toUpperCase()) } });\n        const rolesToInsert = [];\n        roles.forEach(role => {\n          if (!insertedRoles.find(insertedRole => insertedRole.code === role.toUpperCase())) {\n            rolesToInsert.push({\n              name: role,\n              code: role.toUpperCase(),\n              weight: 1\n            });\n          }\n        });\n        if (rolesToInsert.length) {\n          const result = await roleDbService.createMany(rolesToInsert);\n          if (result) console.log('Role seeded 🍺');\n          else console.log('Role seeder failed!');\n        } else {\n          console.log('Role is up to date 🍺');\n        }\n      } catch (error) {\n        console.log('Role seeder failed due to ', error.message);\n      }\n    }\n  \n    async function seedProjectRoutes (routes) {\n      try {\n        if (routes) {\n          let routeName = '';\n          const dbRoutes = await projectRouteDbService.findMany({});\n          let routeArr = [];\n          let routeObj = {};\n          routes.forEach(route => {\n            routeName = `${replaceAll((route.path).toLowerCase(), '/', '_')}`;\n            route.methods.forEach(method => {\n              routeObj = dbRoutes.find(dbRoute => dbRoute.route_name === routeName && dbRoute.method === method);\n              if (!routeObj) {\n                routeArr.push({\n                  'uri': route.path.toLowerCase(),\n                  'method': method,\n                  'route_name': routeName,\n                });\n              }\n            });\n          });\n          if (routeArr.length) {\n            const result = await projectRouteDbService.createMany(routeArr);\n            if (result) console.info('ProjectRoute model seeded 🍺');\n            else console.info('ProjectRoute seeder failed.');\n          } else {\n            console.info('ProjectRoute is up to date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('ProjectRoute seeder failed due to ', error.message);\n      }\n    }\n  \n    async function seedRouteRole() {\n      try{\n        const routeRoles =[ \n          <%_for(let i=0;i < ROUTE_ROLE_ARRAY.length;i++){_%>\n          <%=ROUTE_ROLE_ARRAY[i]%>,\n          <%_}_%>\n        ];\n        if (routeRoles && routeRoles.length) {\n          const routes = [...new Set(routeRoles.map(routeRole => routeRole.route.toLowerCase()))];\n          const routeMethods = [...new Set(routeRoles.map(routeRole => routeRole.method))];\n          const roles = <%=ROLES%>;\n          const insertedProjectRoute = await projectRouteDbService.findMany({\n            uri: { '$in': routes },\n            method: { '$in': routeMethods },\n            'isActive': true,\n            'isDeleted': false\n          });\n          const insertedRoles = await roleDbService.findMany({\n            code: { '$in': roles.map(role => role.toUpperCase()) },\n            'isActive': true,\n            'isDeleted': false\n          });\n          let projectRouteId = '';\n          let roleId = '';\n          let createRouteRoles = routeRoles.map(routeRole => {\n            projectRouteId = insertedProjectRoute.find(pr => pr.uri === routeRole.route.toLowerCase() && pr.method === routeRole.method);\n            roleId = insertedRoles.find(r => r.code === routeRole.role.toUpperCase());\n            if (projectRouteId && roleId) {\n              return {\n                roleId: roleId.id,\n                routeId: projectRouteId.id\n              };\n            }\n          });\n          createRouteRoles = createRouteRoles.filter(Boolean);\n          const routeRolesToBeInserted = [];\n          let routeRoleObj = {};\n    \n          await Promise.all(\n            createRouteRoles.map(async routeRole => {\n              routeRoleObj = await routeRoleDbService.findOne({\n                routeId: routeRole.routeId,\n                roleId: routeRole.roleId,\n              });\n              if (!routeRoleObj) {\n                routeRolesToBeInserted.push({\n                  routeId: routeRole.routeId,\n                  roleId: routeRole.roleId,\n                });\n              }\n            })\n          );\n          if (routeRolesToBeInserted.length) {\n            const result = await routeRoleDbService.createMany(routeRolesToBeInserted);\n            if (result) console.log('RouteRole seeded 🍺');\n            else console.log('RouteRole seeder failed!');\n          } else {\n            console.log('RouteRole is up to date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('RouteRole seeder failed due to ', error.message)\n      }\n    }\n  \n    async function seedUserRole (){\n      try{\n        const userRoles = <%-JSON.stringify(USER_ROLE_ARRAY)%>;\n        const defaultRole = await roleDbService.findOne({ code: <%=DEFAULT_ROLE%> });\n        const insertedUsers = await <%-AUTH_MODEL%>DbService.findMany({ username: { '$in': userRoles.map(userRole => userRole.username) } });\n        let user = {};\n        const userRolesArr = [];\n        userRoles.map(userRole => {\n          user = insertedUsers.find(user => user.username === userRole.username && user.isPasswordMatch(userRole.password) && user.isActive && !user.isDeleted);\n          if (user) {\n            userRolesArr.push({\n              userId: user.id,\n              roleId: defaultRole.id\n            });\n          }\n        });\n        let userRoleObj = {};\n        const userRolesToBeInserted = [];\n        if (userRolesArr.length) {\n          await Promise.all(\n            userRolesArr.map(async userRole => {\n              userRoleObj = await userRoleDbService.findOne({\n                userId: userRole.userId,\n                roleId: userRole.roleId\n              });\n              if (!userRoleObj) {\n                userRolesToBeInserted.push({\n                  userId: userRole.userId,\n                  roleId: userRole.roleId\n                });\n              }\n            })\n          );\n          if (userRolesToBeInserted.length) {\n            const result = await userRoleDbService.createMany(userRolesToBeInserted);\n            if (result) console.log('UserRole seeded 🍺');\n            else console.log('UserRole seeder failed');\n          } else {\n            console.log('UserRole is up to date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('UserRole seeder failed due to ', error.message)\n      }\n    }\n  <%_}_%>\n<%_}_%>\n\nasync function seedData(<%_if(IS_AUTH && SHOULD_ADD_ROLE_PERMISSION){_%>allRegisterRoutes<%_}_%>){\n<%_if(IS_AUTH){_%>\n  await seedUser();\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    await seedRole();\n    await seedProjectRoutes(allRegisterRoutes);\n    await seedRouteRole();\n    await seedUserRole();\n  <%_}_%>\n<%_}_%>\n};\nmodule.exports = seedData;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/auth.js.ejs",
    "content": "const { JWT,LOGIN_ACCESS,\n    PLATFORM<%_if(LOGIN_RETRY_LIMIT){_%>,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME<%_}_%>\n    <%_if(RESET_PASSWORD){_%>,FORGOT_PASSWORD_WITH<%_}_%>\n    <%_if(MAX_DEVICE_ALLOWED){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\");\nconst jwt = require(\"jsonwebtoken\");\nconst common = require(\"../utils/common\");\nconst dayjs = require(\"dayjs\");\nconst emailService = require(\"./email/emailService\");\nconst smsService = require(\"./sms/smsService\");\n<%_if(FORGOT_WITH_LINK){_%>\nconst uuid = require(\"uuid\").v4;\n<%_}_%>\nconst bcrypt = require(\"bcrypt\");\n<%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS'){_%>\nconst ejs = require(\"ejs\");\n<%_}_%>\nconst {Op} = require('sequelize');\nconst model = require('../model');\n\nasync function generateToken(user,secret){\n    return jwt.sign( {id:user.id,'<%-LOGIN_WITH[0]%>':user.<%-LOGIN_WITH[0]%>}, secret, {\n        expiresIn: JWT.EXPIRES_IN\n    });\n}\n\nfunction makeAuthService({<%-MODEL%>Service,userAuthSettingService,userTokenService<%_if(ROLE_PERMISSION){_%>,userRoleService,routeRoleService<%_}_%>}) {\n    const loginUser = async(username,password,url<%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n            try {\n                <%_ if(LOGIN_WITH.length>1){ _%>\n                let where = <%-MULTIPLE_LOGIN%>\n                <%_ }else{_%>\n                let where ={'<%-LOGIN_WITH[0]%>':username}\n                <%_}_%>                  \n                const user = await <%-MODEL%>Service.findOne(where);\n                if (user) {\n                    let userAuth = await userAuthSettingService.findOne({ userId: user.id });\n                    <%_if(MAX_DEVICE_ALLOWED){_%>\n                        const userToken = await userTokenService.count({ [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0, userId:user.id } } );\n                        if(userToken >= NO_OF_DEVICE_ALLOWED){\n                            return {\n                                flag: true,\n                                data: \"You have reached your device limit\"\n                            }\n                        }\n                    <%_}_%>\n                    <%_if(LOGIN_RETRY_LIMIT){_%>\n                    if (userAuth && userAuth.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT) {\n                        let now = dayjs();\n                        if (userAuth.loginReactiveTime) {\n                            let limitTime = dayjs(userAuth.loginReactiveTime);\n                            if (limitTime > now) {\n                            let expireTime = dayjs().add(LOGIN_REACTIVE_TIME, 'minute');\n                            if (!(limitTime > expireTime)){\n                                return {\n                                    flag:true,\n                                    data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,limitTime)}.`\n                                }; \n                            }  \n                            await userAuthSettingService.updateMany({userId:user.id}, {\n                                loginReactiveTime: expireTime.toISOString(),\n                                <%-LOGIN_RETRY_LIMIT.key%>: userAuth.<%-LOGIN_RETRY_LIMIT.key%> + 1\n                            });\n                            return {\n                                flag: true,\n                                data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                            };\n                            }else{\n                                await userAuthSettingService.updateMany({userId:user.id}, {\n                                    loginReactiveTime: null,\n                                    <%-LOGIN_RETRY_LIMIT.key%>: 0\n                                });\n                                userAuth = await userAuthSettingService.findOne({ userId: user.id });\n                            }\n                        } else {\n                            // send error\n                            let expireTime = dayjs().add(LOGIN_REACTIVE_TIME, 'minute');\n                            await userAuthSettingService.updateMany({userId:user.id}, {\n                            loginReactiveTime: expireTime.toISOString(),\n                            <%-LOGIN_RETRY_LIMIT.key%>: userAuth.<%-LOGIN_RETRY_LIMIT.key%> + 1\n                            });\n                            return {\n                            flag: true,\n                            data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                            };\n                        }\n                        }\n                    <%_}_%>\n                    const isPasswordMatched = await user.isPasswordMatch(password);\n                    if (isPasswordMatched) {\n                        const {password,...userData}=user.toJSON()\n                        let token;\n                        if(!user.role){\n                            return {flag:true, data:'You have not assigned any role'}\n                        }\n                        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n                            <%_if(i===0){_%>\n                            if(url.includes('<%-PLATFORMS[i]%>')){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}else{_%>\n                            else if(url.includes('<%-PLATFORMS[i]%>')){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}_%>\n                        <%_}_%>                        \n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        if(userAuth && userAuth.<%-LOGIN_RETRY_LIMIT.key%>){\n                            await userAuthSettingService.updateMany({userId:user.id}, {\n                                <%-LOGIN_RETRY_LIMIT.key%>: 0,\n                                loginReactiveTime: null\n                            });\n                        }\n                        <%_}_%>\n                        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n                        await userTokenService.createOne({\n                            userId: user.id,\n                            token: token,\n                            tokenExpiredTime: expire \n                        });\n                        let userToReturn = { ...userData, token };\n                        <%_if(ROLE_PERMISSION){_%>\n                        let roleAccessData = {};\n                        if (roleAccess){\n                            roleAccessData = await common.getRoleAccessData(model,userRoleService,routeRoleService,user.id);\n                            userToReturn = {\n                                ...userToReturn,\n                                roleAccess: roleAccessData\n                            };\n                        }\n                        <%_}_%>\n                        return {flag:false,data:userToReturn}\n                    } else {\n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        await userAuthSettingService.updateMany({userId:user.id},{<%-LOGIN_RETRY_LIMIT.key%>:userAuth.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                        <%_}_%>\n                        return {flag:true,data:'Incorrect Password'}\n                    }\n                } else {\n                    return {flag:true,data:'User not exists'}\n                }\n            } catch (error) {\n                throw new Error(error.message)\n            }\n    }\n    const changePassword = async(params)=>{\n        try {\n            let password = params.newPassword;\n            let oldPassword = params.oldPassword;\n            let where = {id:params.userId};\n            let user = await <%-MODEL%>Service.findOne(where);\n            if (user && user.id) {\n                const isPasswordMatched = await user.isPasswordMatch(oldPassword);\n                if(!isPasswordMatched){\n                    return {flag:true,data:'Incorrect Old Password'};\n                }\n                password = await bcrypt.hash(password, 8);\n                let updatedUser = <%-MODEL%>Service.updateByPk(user.id,{<%-PASSWORD%>:password});\n                if (updatedUser) {\n                    return {flag:false,data:'Password changed successfully'};                \n                }\n                return {flag:true,data:'password can not changed due to some error.please try again'}\n            }\n            return {flag:true,data:'User not found'}\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n\n    const sendResetPasswordNotification = async (user) => {\n        let resultOfEmail=false;\n        let resultOfSMS=false;\n        try {\n            <%_if(FORGOT_WITH_LINK){_%>\n            let token = uuid();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await userAuthSettingService.updateMany({userId:user.id},\n            {\n                resetPasswordCode: token, expiredTimeOfResetPasswordCode: expires\n            });\n            if(FORGOT_PASSWORD_WITH.LINK.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await <%-MODEL%>Service.findOne({id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                };\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = { \n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:updatedUser\n                };\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = \"Click on the link below to reset your password.\";\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/resetPassword\",\n                    data: {\n                        link: `http://localhost:${process.env.PORT}` + viewType + token,\n                        linkText: \"Reset Password\",\n                        message:msg\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;\n                }catch(error){\n                    console.log(error)\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.LINK.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE ==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await <%-MODEL%>Service.findOne({id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = `Click on the link to reset your password.\n                http://localhost:${process.env.PORT}${viewType + token}`;\n                let smsObj = {\n                    to:user.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            <%_if(FORGOT_WITH_OTP){_%>\n            let otp = common.randomNumber();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await userAuthSettingService.updateMany({userId:user.id},\n            {\n                resetPasswordCode: token, expiredTimeOfResetPasswordCode: expires\n            });\n            if(FORGOT_PASSWORD_WITH.OTP.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await <%-MODEL%>Service.findOne({id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>',    \n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                }\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>',\n                    data:updatedUser\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/resetPassword',\n                    data: {\n                        isWidth: true,\n                        name: \"username\",\n                        email: user.<%-EMAIL_FIELD%> || '-',\n                        message: otpMsg,\n                        otp: otp\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;  \n                }catch(error){\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.OTP.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await <%-MODEL%>Service.findOne({id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let smsObj = {\n                    message: otpMsg,\n                    to: user.<%-MOBILE_FIELD%>,\n                };\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}_%>\n                resultOfSMS = await sendSMSForResetPasswordOtp(user);\n            }\n            <%_}_%>\n            return {resultOfEmail,resultOfSMS};\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n    \n    const resetPassword = async (userId, newPassword) => {\n        try {\n            let where = { id: userId };    \n            const dbUser = await <%-MODEL%>Service.findOne(where);\n            if (!dbUser) {\n                return {\n                    flag: false,\n                    data: \"User not found\",\n                };\n            }\n            newPassword = await bcrypt.hash(newPassword, 8);\n            let updatedUser = await <%-MODEL%>Service.updateByPk(userId, {\n                <%-PASSWORD%>: newPassword\n            });\n            if (!updatedUser) {\n                return {\n                  flag: true,\n                  data: 'Password is not reset successfully',\n                };\n              }\n            await userAuthSettingService.updateMany({userId:userId}, { resetPasswordCode: '', expiredTimeOfResetPasswordCode: null, <%-LOGIN_RETRY_LIMIT.key%>: 0 })\n            let mailObj = {\n                subject: 'Reset Password',\n                to: dbUser.<%-EMAIL_FIELD%>,\n                template: '/views/successfullyResetPassword',\n                data: {\n                    isWidth: true,\n                    email: dbUser.<%-EMAIL_FIELD%> || '-',\n                    message: \"Password Successfully Reset\"\n                }\n            };\n            await emailService.sendMail(mailObj);\n            return {\n                flag: false,\n                data: \"Password reset successfully\",\n            };\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n    return Object.freeze({\n        loginUser,\n        changePassword,\n        resetPassword,\n        sendResetPasswordNotification,\n    })\n}\n\nmodule.exports = makeAuthService;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/customQueryService.js.ejs",
    "content": "function makeMongoCustomQueryService(model){\n  const find = async ({\n    filter = {}, attributes=[], order=[] \n  }) => {\n    const result = await model.findAll({\n      where: filter\n    },\n    {attributes: attributes},\n    {order: order})\n    return result;\n  };\n  return Object.freeze({\n    find,\n  })\n}\n\nmodule.exports = makeMongoCustomQueryService\n\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/dbService.js",
    "content": "// eslint-disable-next-line import/no-unresolved\nconst { Op } = require('sequelize');\n\nconst OPERATORS = ['and', 'or', 'like', 'in', 'eq', 'gt', 'lt', 'gte', 'lte', 'any', 'between'];\n\nfunction makeSequelizeDbService ({ model }) {\n  const createOne = async (data) => {\n    const result = await model.create(data);\n    return result;\n  };\n  const createMany = async (data) => {\n    if (data && data.length > 0) {\n      const result = await model.bulkCreate(data);\n      return result;\n    }\n    throw new Error('send array as input in create many method');\n  };\n\n  const updateByPk = async (pk, data) => {\n    let result = await model.update(data, {\n      returning: true,\n      where: { [model.primaryKeyField]: pk },\n    });\n    if (result) {\n      result = await model.findOne({ where: { [model.primaryKeyField]: pk } });\n    }\n    return result;\n  };\n  const updateMany = async (query, data) => {\n    const result = await model.update(data, {\n      returning: true,\n      where: query,\n    });\n    return result;\n  };\n  const deleteByPk = async (pk) => {\n    const result = await model.destroy({ where: { [model.primaryKeyField]: pk } });\n    return result;\n  };\n\n  const deleteMany = async (query) => {\n    const result = await model.destroy({ where: query });\n    return result;\n  };\n\n  const findOne = async (query, options = {}) => {\n    const result = await model.findOne({\n      where: query,\n      ...options,\n    });\n    return result;\n  };\n\n  const findMany = async (query, options = {}) => {\n    options = {\n      where: { ...query },\n      ...options,\n    };\n    const result = await model.paginate(options);\n    const data = {\n      data: result.docs,\n      paginator: {\n        itemCount: result.total,\n        perPage: options.paginate || 25,\n        pageCount: result.pages,\n        currentPage: options.page || 1,\n      },\n    };\n    return data;\n  };\n\n  const findAllRecords = async (query, options = {}) => {\n    options = {\n      where: { ...query },\n      ...options,\n    };\n    const result = await model.findAll(options);\n    return result;\n  };\n\n  const softDeleteByPk = async (pk, options = {}) => {\n    const result = await model.update(\n      { isDeleted: true },\n      {\n        fields: ['isDeleted'],\n        where: { [model.primaryKeyField]: pk },\n        ...options,\n      },\n    );\n    return result;\n  };\n  const softDeleteMany = async (query, options = {}, loggedInUserId) => {\n    let result;\n    if (loggedInUserId !== undefined) {\n      result = await model.update(\n        {\n          isDeleted: true,\n          updatedBy: loggedInUserId,\n        },\n        {\n          fields: ['isDeleted'],\n          where: query,\n          ...options,\n        },\n      );\n    } else {\n      result = await model.update(\n        { isDeleted: true },\n        {\n          fields: ['isDeleted'],\n          where: query,\n          ...options,\n        },\n      );\n    }\n    return result;\n  };\n\n  const count = async (query, options = {}) => {\n    const result = await model.count({\n      where: query,\n      ...options,\n    });\n    return result;\n  };\n\n  const findByPk = async (param, options = {}) => {\n    const result = await model.findByPk(param, options);\n    return result;\n  };\n\n  const upsert = async (params, options = {}) => {\n    const result = await model.upsert(params, options);\n    return result;\n  };\n\n  const queryBuilderParser = (data) => {\n    if (data) {\n      Object.entries(data).forEach(([key]) => {\n        if (typeof data[key] === 'object') {\n          queryBuilderParser(data[key]);\n        }\n        if (OPERATORS.includes(key)) {\n          data[Op[key]] = data[key];\n          delete data[key];\n        } else if (key === 'neq') {\n          data[Op.not] = data[key];\n          delete data[key];\n        } else if (key === 'nin') {\n          data[Op.notIn] = data[key];\n          delete data[key];\n        }\n      });\n    }\n    return data;\n  };\n\n  const sortParser = (input) => {\n    const newSortedObject = [];\n    if (input) {\n      Object.entries(input).forEach(([key, value]) => {\n        if (value === 1) {\n          newSortedObject.push([key, 'ASC']);\n        } else if (value === -1) {\n          newSortedObject.push([key, 'DESC']);\n        }\n      });\n    }\n    return newSortedObject;\n  };\n\n  return Object.freeze({\n    createOne,\n    createMany,\n    updateByPk,\n    updateMany,\n    findOne,\n    findMany,\n    findByPk,\n    deleteByPk,\n    deleteMany,\n    softDeleteByPk,\n    count,\n    softDeleteMany,\n    upsert,\n    queryBuilderParser,\n    sortParser,\n    findAllRecords,\n  });\n}\nmodule.exports = makeSequelizeDbService;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/emailService.js.ejs",
    "content": "const nodemailer = require('nodemailer');\nconst ejs = require(\"ejs\")\nmodule.exports = {\n    sendMail: async (obj) => {\n        let transporter = nodemailer.createTransport({\n            service: 'Mailgun',\n            auth: {\n                user: '',\n                pass: ''\n            }\n        });\n        if (!Array.isArray(obj.to)) {\n            obj.to = [obj.to];\n        }\n        const htmlText = await ejs.renderFile(`${__basedir}${obj.template}/html.ejs`, obj.data);\n\n        return await Promise.all(obj.to.map((emailId) => {\n            var mailOpts = {\n                from: obj.from || \"noreply@yoyo.co\",\n                to: emailId,\n                subject: obj.subject,\n                html: htmlText\n            };\n            transporter.sendMail(mailOpts, function (err, response) {\n                if (err) {\n                    //ret.message = \"Mail error.\";\n                } else {\n                    //ret.message = \"Mail send.\";\n                }\n            });\n        }));\n    }\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/fileUpload.js.ejs",
    "content": "const fs = require('fs');\nconst path = require('path');\n<%_if(S3_UPLOAD){_%>\n  const AWS = require('aws-sdk');\n  <%_if(S3_UPLOAD_PRIVATE){_%>\n    const AmazonS3URI = require('amazon-s3-uri');\n  <%_}_%> \n<%_}_%>\nconst makeDirectory = require('../../utils/makeDirectory');\n\n<%_if(S3_UPLOAD){_%>\n  let S3Config = {\n    AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n    AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n    AWS_S3_REGION: process.env.AWS_S3_REGION,\n    AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n  };\n<%_}_%>\n<%_if(LOCAL_UPLOAD){_%>\n  /**\n  * \n  * Function used to upload file in local storage.\n  * \n  * @param   {object}    file\n  * @param   {object}    fields\n  * @param   {integer}   fileCount\n  * @param   {array}     allowedFileTypes\n  * @param   {integer}   maxFileSize\n  * @param   {string}    defaultDirectory\n  * @returns {object}    { status, message, data}\n  * \n  */\n  async function uploadFilesOnLocalServer(file, fields, fileCount, allowedFileTypes, maxFileSize, defaultDirectory) {\n\n    let tempPath = file.path;\n\n    let extension = path.extname(file.name);\n    extension = extension.split('.').pop();\n\n    fileType = file.type; uploadFilesOnLocalServer;\n\n    //Check allowed extension;\n    if (allowedFileTypes.length) {\n      if (!allowedFileTypes.includes(extension)) {\n        return {\n          status: false,\n          message: 'Filetype not allowed.'\n        };\n      }\n    }\n\n    //Check File Size\n    const fileSize = ((file.size / 1024) / 1024);\n    if (maxFileSize < fileSize) {\n      return {\n        status: false,\n        message: `Allow file size upto ${maxFileSize} MB.`\n      };\n    }\n\n    //Create Directory if not exist.\n    await makeDirectory(defaultDirectory);\n\n    //Create New path\n    let newPath = defaultDirectory + '/' + new Date().getTime() + path.extname(file.name);\n\n    //Create requested directory,if given in request parameter.\n    if (fields && fields.folderName) {\n      let newDir = defaultDirectory + '/' + fields.folderName;\n\n      await makeDirectory(newDir);\n\n      if (fields.fileName) {\n        newPath = newDir + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n        fileName = fields.fileName;\n      }\n    } else if (fields && fields.fileName) {\n      newPath = defaultDirectory + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n      fileName = fields.fileName;\n    }\n\n    let data = fs.readFileSync(tempPath);\n    fs.writeFileSync(newPath, data);\n    fs.unlinkSync(tempPath);\n\n    return {\n      status: true,\n      message: 'File upload successfully.',\n      data: '/' + newPath\n    };\n  }\n<%_}_%>\n<%_if(S3_UPLOAD){_%>\n  async function uploadFilesOnS3(file, fields, fileCount, allowedFileTypes, maxFileSize) {\n    let extension = path.extname(file.name);\n    extension = extension.split('.').pop();\n\n    fileType = file.type;\n\n    if (allowedFileTypes.length) {\n      //Check allowed extension;\n      if (!allowedFileTypes.includes(extension)) {\n        return {\n          status: false,\n          message: 'Filetype not allowed.'\n        };\n      }\n    }\n\n    // Check File Size\n    const fileSize = ((file.size / 1024) / 1024);\n    if (maxFileSize < fileSize) {\n      return {\n        status: false,\n        message: `Allow file size upto ${maxFileSize} MB.`\n      };\n    }\n\n    let fileName = file.name;\n    //Create Requested Directory,if given in request parameter.\n    if (fields && fields.folderName) {\n      fileName = fields.folderName + '/' + fileName;\n    }\n    else if (fields && fields.fileName) {\n      fileName = fields.fileName + '-' + fileCount + path.extname(file.name);\n    }\n\n    const s3 = new AWS.S3({\n      region: S3Config.AWS_S3_REGION,\n      accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n      secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n    });\n\n    let params = {\n      Bucket: S3Config.AWS_S3_BUCKET_NAME,\n      Body: fs.createReadStream(file.path),\n      Key: fileName,\n    };\n\n    const response = await new Promise(async (resolve, reject) => {\n      s3.putObject(params, function (err, data) {\n        if (err) {\n          resolve({\n            status: false,\n            message: err.message\n          });\n        } else {\n          resolve({\n            status: true,\n            data: 'https://' + process.env.AWS_S3_BUCKET_NAME + '.s3.' + S3Config.AWS_S3_REGION + '.amazonaws.com/' + fileName\n          });\n        }\n      });\n    });\n\n    return response;\n  }\n<%_}_%>\n\n<%_if(S3_UPLOAD && S3_UPLOAD_PRIVATE){_%>\n  async function generatePreSignedURL (uri){\n    if (uri){\n      const s3 = new AWS.S3({\n        region: S3Config.AWS_S3_REGION,\n        accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n        secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n      });\n\n      const {\n        region, bucket, key \n      } = AmazonS3URI(uri);\n\n      let options = {\n        Bucket: bucket,\n        Key: key,\n        Expires: 1 * 60 * 60, // 1 hour\n      };\n\n      let response = await new Promise(async (resolve,reject)=>{\n        await s3.getSignedUrl('getObject', options, (err, url) => {\n          if (err) {\n            resolve({\n              status: false,\n              err: err,\n            });\n          } else {\n            resolve({\n              status: true,\n              path: url,\n            });\n          }\n        });\n      });\n      return response;\n    }\n    else {\n      return {\n        status:false,\n        err:'Please send Url'\n      };\n    }\n  }\n<%_}_%>  \n\nmodule.exports = {\n  <%_if(LOCAL_UPLOAD){_%>\n    uploadFilesOnLocalServer,\n  <%_}_%> \n  <%_if(S3_UPLOAD){_%>\n    uploadFilesOnS3,\n    <%_if(S3_UPLOAD_PRIVATE){_%>\n      generatePreSignedURL\n    <%_}_%>\n  <%_}_%> \n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/services/smsService.js.ejs",
    "content": "const axios = require('axios')\nconst sendSMS = async (obj) => {\n    console.log('SMS---', obj);\n    if (obj.to) {\n        obj.mobiles = obj.to;\n    }\n    let mobiles;\n    if (Array.isArray(obj.mobiles)) {\n        obj.mobiles = obj.mobiles.map((m) => {\n            let tmpNo = m.split('+');\n            return tmpNo[1] ? tmpNo[1] : tmpNo[0];\n        });\n        mobiles = obj.mobiles.join(',');\n    }\n    else {\n        let tmpNo = obj.mobiles.split('+');\n        mobiles = tmpNo[1] ? tmpNo[1] : tmpNo[0];\n    }\n    const message = obj.message\n    const userid = \"\"\n    const password = escape(\"yourPassword\")\n    const v = 1.1\n    const method = \"sendMessage\"\n    const msg_type = \"text\"\n    const send_to = mobiles\n    return await new Promise((resolve, reject) => {\n        axios(\n            {\n                url: `http://enterprise.smsgupshup.com/GatewayAPI/rest?msg=${message}&v=${v}&userid=${userid}&password=${password}&method=${method}&send_to=${send_to}&msg_type=${msg_type}`,\n                method: 'GET',\n            })\n            .then(function (response) {\n                let response1 = response.data.split('|');\n                console.log(response.data)\n                if (response1.length) {\n                    if (response1[0].trim() === 'error') {\n                        reject(response)\n                    } else {\n                        resolve(response)\n                    }\n                }\n            })\n            .catch(function (error) {\n                reject(error)\n            });\n    });\n}\nmodule.exports = {sendSMS}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/authentication.js.ejs",
    "content": "\nconst response = require('../../utils/response');\nconst makeLoginUser = require('../common/loginUser'); \n\nconst authentication = ({ <%-USER_MODEL-%>Db,userTokensDb<%_if(ROLE_PERMISSION){_%>,userRoleDb,routeRoleDb<%_}_%> }) => async (params, platform) => {\n    let username = params.username;\n    let password = params.password;\n\n    if(!username || !password){\n        return response.badRequest()\n    }\n\n    const loginUser = makeLoginUser({<%-USER_MODEL-%>Db,userTokensDb<%_if(ROLE_PERMISSION){_%>,userRoleDb,routeRoleDb<%_}_%>});\n    return await loginUser(username, platform, password);\n}\nmodule.exports = authentication;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/forgotPassword.js.ejs",
    "content": "\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\nconst MakeSendResetPasswordNotification = require('../common/sendResetPasswordNotification');\n\nconst forgotPassword = ({ <%-USER_MODEL-%>Db,userAuthSettingsDb  }) => async (params) => {\n    if (!params.email) {\n        return response.validationError()\n    }\n    let where = { <%-EMAIL_FIELD%>: params.email };\n    params.email = params.email.toString().toLowerCase();\n    let <%-USER_MODEL-%> = await <%-USER_MODEL%>Db.findOne(where);\n    if (user) {\n        let sendResetPasswordNotification = MakeSendResetPasswordNotification({<%-USER_MODEL-%>Db,userAuthSettingsDb});\n        let notificationResponse = await sendResetPasswordNotification(user);\n        if (notificationResponse.status == responseStatus.success) {\n            let {resultOfEmail, resultOfSMS} = notificationResponse.data;\n            if (resultOfEmail && resultOfSMS) {\n                return response.success({message :\"otp successfully send.\"});\n            } else if (resultOfEmail && !resultOfSMS) {\n                return response.success({message : \"otp successfully send to your email.\"});\n            } else if (!resultOfEmail && resultOfSMS) {\n                return response.success({message : \"otp successfully send to your mobile number.\"});\n            } else {\n                return response.failure({message :\"otp can not be sent due to some issue try again later\"});\n            }\n        } else {\n            return response.failure();\n        }\n    } else {\n        return response.recordNotFound()\n    }\n    \n}\nmodule.exports = forgotPassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/logout.js.ejs",
    "content": "const response = require('../../utils/response');\n\nconst logout = ({userTokensDb}) => async (user, token) => {\n     let userToken = await userTokensDb.findOne({ token:token ,userId:user.id });\n    let updatedDocument = {\n        isTokenExpired : true\n    }\n    await userTokensDb.updateOne( {id:userToken.id},updatedDocument);\n    return response.success({message:\"Logged out Successfully\"});\n}\nmodule.exports = logout;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/register.js.ejs",
    "content": "const  <%-USER_MODEL-%>Entity = require('../../entities/<%-USER_MODEL-%>');\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\n<%_ if(NOTIFICATION_TYPE===\"SMS\"){ _%>\n    const sendPasswordBySMS = require('../common/sendPasswordBySMS'); \n<%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\n    const sendPasswordByEmail = require('../common/sendPasswordByEmail');\n<%_}_%>\n\nconst register = ({ <%-USER_MODEL-%>Db, createValidation }) => async (params) => {\n    let validateSchema = await createValidation(params);\n    if (!validateSchema.isValid) {\n        return response.validationError({ message: validateSchema.message });\n    }\n    let newUser = <%-USER_MODEL-%>Entity(params);\n    let checkUniqueValidation = checkUnique({<%-USER_MODEL-%>Db}); //dependance injection\n    let unique = await checkUniqueValidation(params);    \n    if (unique.status != responseStatus.success ){\n        return response.badRequest({message : 'User Registration Failed, Duplicate data found'});\n    }\n    const result = await <%-USER_MODEL-%>Db.create(newUser);\n        <%_ if(NOTIFICATION_TYPE===\"SMS\"){ _%>\n        // send sms to user for successfully registered.\n        let renderData = {\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n            <%_}else{_%>\n            ...result\n            <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-REGISTER_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n            to:result.<%-MOBILE_FIELD%>,\n            message:msg\n        }\n        await sendSMS(smsObj);\n    <%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\n        // send email to user for successfully registered.\n        let mailObj = {\n            subject: \"Register User\",\n            to: result.<%-EMAIL_FIELD%>,\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:{\n                <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n                <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n            }\n            <%_}else if(!REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:result\n            <%_}_%>\n        };\n        await sendEmail(mailObj);\n    <%_}_%>\n    return response.success({data :result});\n}\n\n\nconst checkUnique =({ <%-USER_MODEL-%>Db,userTokensDb }) => async (data) =>{\n    let filter = { $or:[] };\n    if (data && data['username']){\n      filter['$or'].push(\n        { 'username':data['username'] },\n        { 'email':data['username'] },\n      );\n    }\n    if (data && data['email']){\n      filter['$or'].push(\n        { 'username':data['email'] },\n        { 'email':data['email'] },\n      );\n    }\n    let found = await <%-USER_MODEL-%>Db.findOne(filter);\n    if (found){\n      return response.failure();\n    }\n    return response.success();\n  };\n\n\n\nmodule.exports = register;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/resetPassword.js.ejs",
    "content": "const dayjs = require(\"dayjs\");\nconst bcrypt = require('bcrypt');\nconst response = require('../../utils/response');\nconst emailService = require('../../services/email/emailService');\n\nconst resetPassword = ({ <%-USER_MODEL-%>Db,userAuthSettingsDb }) => async (params) => {\n    if (!params.code || !params.newPassword) {\n        return response.badRequest()\n    }\n    let user = await userAuthSettingsDb.findOne({ resetPasswordCode: params.code });\n\n    if (!user || !user.expiredTimeOfResetPasswordCode) {\n        return response.badRequest({ message: 'Invalid Code' });\n    }\n    if (dayjs(new Date()).isAfter(dayjs(user.expiredTimeOfResetPasswordCode))) { \n        return response.badRequest({ message: 'Your reset password link is expired.' });\n    }\n\n    let where = { id: user.userId };    \n    const dbUser = await <%-USER_MODEL%>Db.findOne(where);\n\n    if (!dbUser) {\n        return response.badRequest({message :  \"User not found\"});\n    }\n    let newPassword = await bcrypt.hash(params.newPassword, 8);\n\n    let updatedUser = await <%-USER_MODEL%>Db.updateOne({id :user.userId}, {\n        <%-PASSWORD_FIELD%>: newPassword\n    });\n\n    await userAuthSettingsDb.updateMany({userId:user.userId}, { resetPasswordCode: '', expiredTimeOfResetPasswordCode: null, <%-LOGIN_RETRY_LIMIT.key%>: 0 })\n\n    let mailObj = {\n        subject: 'Reset Password',\n        to: user.<%-EMAIL_FIELD%>,\n        template: '/views/successfullyResetPassword',\n        data: {\n            isWidth: true,\n            email: user.<%-EMAIL_FIELD%> || '-',\n            message: \"Password Successfully Reset\"\n        }\n    };\n    await emailService.sendMail(mailObj);\n    return response.success({message :\"Password reset successfully\"});\n}\nmodule.exports = resetPassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/authentication/validateResetPasswordOtp.js.ejs",
    "content": "const dayjs = require(\"dayjs\");\nconst response = require('../../utils/response');\n\nconst validateResetPasswordOtp = ({ <%-USER_MODEL-%>Db,userAuthSettingsDb }) => async (params) => {\n    if (!params || !params.otp) {\n        return response.badRequest()\n    }\n    let user = await userAuthSettingsDb.findOne({ resetPasswordCode: params.otp });\n    if (!user || !user.resetPasswordLink.expireTime) {\n        return response.badRequest({message : \"Invalid OTP\"});\n    }\n    if (dayjs(new Date()).isAfter(dayjs(user.resetPasswordLink.expireTime))) {\n        return response.badRequest({message:\"Your reset password link is expired.\"});\n    }\n    return response.success({message :'OTP Validated'});\n}\nmodule.exports = validateResetPasswordOtp;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/bulkUpdate.js.ejs",
    "content": "/**\n updateBulk.js\n */\n\nconst response = require('../../utils/response');\n\n/**\n * @description : update multiple records of <%-MODEL_NAME%> with data by filter.\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} params : {query: query to find data, data: data to update }\n * @return {object} : response of bulkUpdate. {status, message, data}\n */\nconst bulkUpdate = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    const results = await <%-MODEL_NAME-%>Db.updateMany(params.query,params.dataToUpdate);\n    return response.success({ data:results });\n}\nmodule.exports = bulkUpdate;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/changePassword.js.ejs",
    "content": "/**\n changePassword.js\n */\nconst bcrypt = require(\"bcrypt\");\n\nconst response = require('../../utils/response');\n\nconst changePassword = ({<%-MODEL_NAME-%>Db}) => async (params) => {\n\n  if (!params.newPassword || !params.userId || !params.oldPassword) {\n    return response.validationError({message:'Please Provide userId and new Password and Old password'});\n  }\n  let password = params.newPassword;\n  let oldPassword = params.oldPassword;\n  let user = await <%-MODEL_NAME%>Db.findOne({id :params.userId });\n  if(!user){\n    return response.badRequest({message:'User not found.'});\n  }\n  let isPasswordMatch = await user.isPasswordMatch(oldPassword);\n  if(!isPasswordMatch){\n    return response.badRequest({message:'Incorrect old password.'});\n  }\n  password = await bcrypt.hash(password, 8);\n  let updatedUser = <%-MODEL_NAME%>Db.updateOne({id : user.id}, { <%-PASSWORD_FIELD%>:password });\n  if (updatedUser) {\n    return response.success({message : 'Password changed successfully.'});\n  }\n  return response.badRequest({message : 'Password not updated.'});\n}\n\nmodule.exports = changePassword;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/common/getRoleAccess.js.ejs",
    "content": "const response = require('../../utils/response');\nconst modelNames = Object.keys(require('../../db/sequelize/models').sequelize.models);\nconst models = require(\"../../db/sequelize/models\")\nconst getRoleAccess = ({userRoleDb,routeRoleDb })=> async(userId) => {\n  let userRole = await userRoleDb.findMany({ userId: userId },{pagination:false});\n  let routeRole = await routeRoleDb.findMany({ roleId: { $in: userRole ? userRole.map(u=>u.roleId) : [] } },{include: [{ model: models.routeRole, as: 'routeId' },{model:models.role,as:'roleId'} ]});\n// { populate:['roleId','routeId'],pagination:false }\n\n  let roles = routeRole ? routeRole.map(rr => rr.roleId && rr.roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (roles.length){\n    roles.map(role => {\n      roleAccess[role] = {};\n      modelNames.forEach(model => {\n        if (routeRole && routeRole.length) {\n          routeRole.map(rr => {\n            if (rr.routeId && rr.routeId.uri.includes(`/${model.toLowerCase()}/`) && rr.roleId && rr.roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr.routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr.routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr.routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr.routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return response.success({ data: roleAccess });\n}\nmodule.exports = getRoleAccess;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/common/loginUser.js.ejs",
    "content": "const {\n  JWT,LOGIN_ACCESS,\n  PLATFORM,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME,FORGOT_PASSWORD_WITH\n} = require('../../constants/authConstant');\nconst dayjs = require('dayjs');\nconst generateToken = require('../../utils/generateToken');\nconst {getDifferenceOfTwoDatesInTime} = require('../../helpers/date');\nconst response = require('../../utils/response');\nconst responseStatus = require('../../utils/response/responseStatus');\n\n<%_if(ROLE_PERMISSION){_%>\n    const makeGetRoleAccess = require('../common/getRoleAccess');\n<%_}_%>\n\n\nconst loginUser = ({ <%-USER_MODEL-%>Db,userTokensDb<%_if(ROLE_PERMISSION){_%>,userRoleDb,routeRoleDb<%_}_%> })=> async(username,platform,url,password = null <%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n\n    <%_ if(LOGIN_WITH.length>1){ _%>\n        let where = <%-MULTIPLE_LOGIN%>\n    <%_ }else{_%>\n        let where ={'<%-LOGIN_WITH[0]%>':username}\n    <%_}_%>\n    let user = await <%-USER_MODEL-%>Db.findOne(where);\n    if (user) {\n        <%_if(MAX_DEVICE_ALLOWED){_%>\n            const userToken = await userTokensDb.count({ $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n            if(userToken >= NO_OF_DEVICE_ALLOWED){\n                response.badRequest({message : \"You have reached your device limit\"});\n            }\n        <%_}_%>\n        <%_if(LOGIN_RETRY_LIMIT){_%>\n            if(user.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT){\n                let now = dayjs();\n                if (user.loginReactiveTime){\n                    let limitTime = dayjs(user.loginReactiveTime);\n                    if (limitTime > now){\n                        let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                        if (!(limitTime > expireTime)){\n                        return response.badRequest({message :`you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,limitTime)}.`});\n                        }   \n                        await <%-USER_MODEL-%>Db.updateOne({_id :user.id},{\n                        loginReactiveTime:expireTime.toISOString(),\n                        <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1  \n                        });\n                        return response.badRequest({message : `you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,expireTime)}.`});\n                    }else {\n                        user = await <%-USER_MODEL-%>Db.updateOne({ _id:user.id },{\n                            loginReactiveTime:'',\n                            <%-LOGIN_RETRY_LIMIT.key%>:0\n                        },{ new:true });\n                    }\n                } else {\n                    // send error\n                    let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                    await <%-USER_MODEL-%>Db.updateOne(user.id,{\n                        loginReactiveTime:expireTime.toISOString(),\n                        <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1 \n                    });\n                    return response.badRequest({message :`you have exceed the number of limit.you can login after ${getDifferenceOfTwoDatesInTime(now,expireTime)}.`}); \n                } \n            }\n        <%_}_%>\n        if(password){\n            const isPasswordMatched = await <%-USER_MODEL-%>.isPasswordMatch(password);\n            if (!isPasswordMatched) {\n                <%_if(LOGIN_RETRY_LIMIT){_%>\n                    await <%-USER_MODEL-%>Db.updateOne({_id : user.id},{<%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                <%_}_%>\n                return response.badRequest({message : \"incorrect password\"});\n            }\n        }\n        \n        const userData=user.toJSON()\n        let token;\n        if (!user.role) {\n            return response.badRequest({message : \"You have not been assigned role.\" });\n        }\n        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n            <%_if(i===0){_%>\n            if( platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                    return response.badRequest({message : 'you are unable to access this platform'});\n                }\n                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n            }\n            <%_}else{_%>\n            else if( platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                    return response.badRequest({ message : 'you are unable to access this platform'});\n                }\n                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n            }\n            <%_}_%>\n        <%_}_%> \n        <%_if(LOGIN_RETRY_LIMIT){_%>\n            if(user.<%-LOGIN_RETRY_LIMIT.key%>){\n                await <%-USER_MODEL-%>Db.updateOne({_id :user.id},{<%-LOGIN_RETRY_LIMIT.key%>:0,loginReactiveTime:''});\n            }\n        <%_}_%>\n        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n        await userTokensDb.create({ userId: user.id, token: token,tokenExpiredTime: expire });                  \n        let userToReturn = { ...userData, token };\n        <%_if(ROLE_PERMISSION){_%>\n            let roleAccessData = {};\n            if (roleAccess){\n                const getRoleAccessData = makeGetRoleAccess({userRoleDb,routeRoleDb}); //Dependency Injection\n                roleAccessData = await getRoleAccessData(user.id);\n\n                if(roleAccessData.status == responseStatus.success){\n                    userToReturn.roleAccess = roleAccessData.data\n                }\n                \n            }\n        <%_}_%>\n        return response.success({data:userToReturn, message : 'Login Successful'});\n    } else {\n        return response.badRequest({message :\"User not exists\"});\n    }\n}\n\nmodule.exports = loginUser;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/common/sendResetPasswordNotification.js.ejs",
    "content": "const dayjs = require('dayjs');\nconst uuid = require(\"uuid\").v4;\nconst {\nFORGOT_PASSWORD_WITH\n} = require('../../constants/authConstant');\nconst response = require('../../utils/response');\n\nconst {sendMail} = require('../../services/email/emailService');\nconst {sendSMS} = require('../../services/sms/smsService');\nconst generateRandomNumber = require('../../utils/generateRandomNumber');\n\nconst sendResetPasswordNotification = ({<%-USER_MODEL%>Db,userAuthSettingsDb}) => async (user) => {\n  let resultOfEmail = false;\n  let resultOfSMS = false;\n  <%_if(FORGOT_WITH_LINK){_%>\n    let token = uuid();\n    let expires = dayjs();\n    expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n    await userAuthSettingsDb.updateOne({userId:user.id},\n    {\n        resetPasswordCode: token, expiredTimeOfResetPasswordCode: expires\n    });\n    if(FORGOT_PASSWORD_WITH.LINK.email){\n        <%_if(RESET_PASSWORD_TEMPLATE_NAME &&  RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n          let updatedUser= await <%-USER_MODEL%>Db.findOne({id:user.id});\n        <%_}_%>\n\n        let mailObj = {\n          subject: \"Reset Password\",\n          to: user.<%-EMAIL_FIELD%>,\n        };\n        <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n          mailObj.template = \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\";\n          mailObj.data = {\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n          }\n        <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template =  \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\";\n        mailObj.data = updatedUser;\n        <%_}else{_%>\n          let viewType = \"/reset-password/\";\n          let msg = \"Click on the link below to reset your password.\";\n          mailObj.template = \"/views/resetPassword\";\n          mailObj.data = {\n              link: `http://localhost:${process.env.PORT}` + viewType + token,\n              linkText: \"Reset Password\",\n              message:msg\n          }\n        <%_}_%>\n        try {\n            await sendMail(mailObj);\n            resultOfEmail = true;\n        } catch (error) {\n            console.log(error);\n        }\n    }\n    if(FORGOT_PASSWORD_WITH.LINK.sms){\n      <%_if(RESET_PASSWORD_NOTIFICATION_TYPE ==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%>\n          let updatedUser= await <%-USER_MODEL%>Db.findOne({id:user.id});\n          let renderData = {\n              <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                  <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n              <%_}else{_%>\n                ...updatedUser\n              <%_}_%>\n          }\n          const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n          let smsObj = {\n            to:updatedUser.<%-MOBILE_FIELD%>,\n            message:msg\n          }\n          try{\n            await sendSMS(smsObj);\n            resultOfSMS = true;\n          }catch(error){\n            console.log(error)\n          }\n\n      <%_}else{_%>\n        let viewType = \"/reset-password/\";\n        let msg = `Click on the link to reset your password. http://localhost:${process.env.PORT}${viewType + token}`;\n        let smsObj = {\n          to:user.<%-MOBILE_FIELD%>,\n          message:msg\n        }\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n      <%_}_%>\n    }\n  <%_}_%>\n  <%_if(FORGOT_WITH_OTP){_%>\n    let otp = generateRandomNumber();\n    let expires = dayjs();\n    expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n    await <%-USER_MODEL%>Db.updateOne({id :user.id}, { resetPasswordLink: { code: otp, expireTime: expires } });\n    if(FORGOT_PASSWORD_WITH.OTP.email){\n      <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n        let updatedUser= await <%-MODEL%>Service.getSingleDocumentByQuery({id:user.id});\n      <%_}_%>\n        let mailObj = {\n          subject: 'OTP to reset your password',\n          to: user.<%-EMAIL_FIELD%>\n        }\n      <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template =  '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>';    \n        mailObj.data = {\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n              <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n        }\n      <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n        mailObj.template = '/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>';\n        mailObj.data = updatedUser;\n      <%_}else{_%>\n        mailObj.template = '/views/resetPassword';\n        mailObj.data: {\n          isWidth: true,\n          name: \"username\",\n          email: user.<%-EMAIL_FIELD%> || '-',\n          message: otpMsg,\n          otp: otp\n        }\n      <%_}_%>\n      try {\n          await sendMail(mailObj);\n          resultOfEmail = true;\n      } catch (error) {\n          console.log(error);\n      }\n    }\n    if(FORGOT_PASSWORD_WITH.OTP.sms){\n      <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%>\n        let updatedUser= await <%-USER_MODEL%>Db.findOne({id:user.id});\n        let renderData = {\n          <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n            <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n              <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n          <%_}else{_%>\n          ...updatedUser\n          <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n          to:updatedUser.<%-MOBILE_FIELD%>,\n          message:msg\n        }\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n\n      <%_}else{_%>\n        let message = `OTP code for Reset password`;\n        let otpMsg = `${message}: ${otp}`;\n        let smsObj = {\n          message: otpMsg,\n          to: user.<%-MOBILE_FIELD%>,\n        };\n        try{\n          await sendSMS(smsObj);\n          resultOfSMS = true;\n        }catch(error){\n          console.log(error)\n        }\n      <%_}_%> \n    }\n  <%_}_%> \n  return response.success({ data :{ resultOfEmail, resultOfSMS } });\n};\nmodule.exports = sendResetPasswordNotification;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/count.js.ejs",
    "content": "/**\n count.js\n */\n\nconst response = require('../../utils/response');\n\n/**\n * @description : returns total number of documents of <%-MODEL_NAME%>\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} params : {where: query to find data}\n * @return {object} : response of count. {status, message, data}\n */\nconst count = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME-%>Db.count(params);\n    result = {totalRecords:result}\n    return response.success({data:result});\n}\nmodule.exports = count;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/create.js.ejs",
    "content": "/**\n * create.js\n */\nconst  <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n<%_if(typeof DEFAULT_USER_ROLE !== \"undefined\" && DEFAULT_USER_ROLE){ _%>\nconst authConstant = require('../../constants/authConstant');\n<%_}_%>\n\n/**\n * @description : create documents of document of <%-MODEL_NAME-%> in mongodb collection\n * @param {object} <%-MODEL_NAME-%>Db : db service instance\n * @param {object} dataToCreate : data to create in database\n * @return {object} : response of create. {status, message, data}\n */\nconst create = ({ <%-MODEL_NAME-%>Db,createValidation }) => async (dataToCreate) => {\n    const validateRequest = await createValidation(dataToCreate);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let <%-MODEL_NAME-%> = <%-MODEL_NAME-%>Entity(dataToCreate);\n    <%-MODEL_NAME-%> = await <%-MODEL_NAME-%>Db.create(<%-MODEL_NAME-%>);\n    return response.success({data:<%-MODEL_NAME-%>});\n}\nmodule.exports = create;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/createBulk.js.ejs",
    "content": "\n/**\n *createBulk.js\n */\n\nconst  <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n<%_if(typeof DEFAULT_USER_ROLE !== \"undefined\" && DEFAULT_USER_ROLE){ _%>\nconst authConstant = require('../../constants/authConstant');\n<%_}_%>\n\nconst createBulk = ({ <%-MODEL_NAME-%>Db,createValidation }) => async (dataToCreate) => {\n    let <%-MODEL_NAME.toLowerCase()-%>Entities = dataToCreate.map(item => <%-MODEL_NAME-%>Entity(item))\n    let results = await <%-MODEL_NAME-%>Db.createMany(<%-MODEL_NAME.toLowerCase()-%>Entities);\n    return response.success({data:results});\n}\nmodule.exports = createBulk;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/customRouteOfModel.js.ejs",
    "content": "\n/**\n *<%-FUNCTION_NAME%>.js\n */\nconst response = require('../../utils/response');\n\nconst <%-FUNCTION_NAME%> = ({<%-MODELS.join()%>}) => async (req,res) => {\n  let combinedOutput = {};\n  <%_ for(let i=0;i< QUERY.length;i++){ _%>\n  combinedOutput.<%-QUERY[i].outputVariable%> = await <%-QUERY[i].model%>Db.findOne(<%-QUERY[i].filter%>); \n  <%_}_%>\n  return response.success({data:combinedOutput});\n}; \n\nmodule.exports = <%-FUNCTION_NAME %>;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/delete.js.ejs",
    "content": "\n/**\n deleteOne.js\n */\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeDeleteWithDependency = require('./deleteDependent').deleteWithDependency;\n<%_ } _%>\n\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteOne = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let { query,isWarning } = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const deleteWithDependency = makeDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        return await deleteWithDependency(query);\n    }\n}\n<%_ } else { _%>\nconst deleteOne = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME-%>Db.deleteOne(params.query);\n    return response.success({data: result});\n}\n<%_ } _%>\n\nmodule.exports = deleteOne;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/deleteMany.js.ejs",
    "content": "/**\n deleteMany.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeDeleteWithDependency = require('./deleteDependent').deleteWithDependency;\n<%_ } _%>\n\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteMany = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let { query,isWarning } = params;\n    if(isWarning){\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    }else {\n        const deleteWithDependency = makeDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        return  await deleteWithDependency(query);\n    }\n}\n<%_ } else { _%>\n    const deleteMany = ({ <%-MODEL_NAME%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME%>Db.deleteMany(params.query);\n    return response.success({data:result});\n};\n<%_ } _%>\nmodule.exports = deleteMany;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/fileUpload.js.ejs",
    "content": "const formidable = require('formidable');\n<%_if(S3_UPLOAD){_%>\n  \n<%_} else {_%>\n  const validUrl = require('valid-url');\n<%_}_%>\n\nconst response = require('../../utils/response');\nconst makeDirectory = require('../../utils/makeDirectory');\n\n<%_if(LOCAL_UPLOAD){_%>\nconst {uploadFilesOnLocalServer} = require('../../services/fileUpload');\n<%_}_%> \n<%_if(S3_UPLOAD){_%>\n  const {uploadFilesOnS3} = require('../../services/fileUpload');\n<%_ }else if(S3_UPLOAD && S3_UPLOAD_PRIVATE){_%>\n  const {uploadFilesOnS3,generatePreSignedURL} = require('../../services/fileUpload');\n<%_}_%>\n\nconst upload =async(req,res) =>{\n          <%_if(S3_UPLOAD){_%>\n          let combinedOutput = {};\n          let allowedFileTypes = <%=ALLOWED_TYPE%>;\n          <%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\n          let maxFileSize = <%=max_size%>; //In Megabyte\n\n          // Setting up formidable options.\n          const form = new formidable.IncomingForm();\n          form.multiples = true;\n          form.maxFileSize = 300 * 1024 * 1024; //300 MB\n          form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n          //Parse Form data\n          const {\n            fields, files\n          } = await new Promise(async (resolve, reject) => {\n            form.parse(req, function (err, fields, files) {\n              if (err) reject(err);\n              resolve({\n                fields,\n                files\n              });\n            });\n          });\n\n          let uploadSuccess = [];\n          let uploadFailed = [];\n          let fileCount = 1;\n\n          let fileArr = [];\n          if (!files['file[]'] || files['file[]'].size == 0) {\n            return response.badRequest({message : 'Select at least one file to upload.'});\n          }\n          if (!Array.isArray(files['file[]'])) {\n            fileArr.push(files['file[]']);\n            files['file[]'] = fileArr;\n          }\n\n          for (let file of files['file[]']) {\n            let response = await uploadFilesOnS3(file, fields, fileCount++, allowedFileTypes, maxFileSize);\n            if (response.status == false) {\n              uploadFailed.push({\n                'name': file.name,\n                'error': response.message,\n                'status': false\n              });\n            } else {\n              let url = response.data;\n              if (!validUrl.isUri(response.data)) {\n                response.data = response.data.replace('/public', '');\n                url = `${response.data}`;\n              }\n              uploadSuccess.push({\n                'name': file.name,\n                'path': url,\n                'status': true\n              });\n            }\n          }\n\n          let uploadFileRes = {\n            uploadSuccess,\n            uploadFailed\n          };\n\n          <%_if(S3_UPLOAD_PRIVATE){_%>\n            let finalResponse = [];\n            if (Array.isArray(uploadFileRes.uploadSuccess) && uploadFileRes.uploadSuccess.length) {\n              uploadFileRes.uploadSuccess = await new Promise(async (resolve, reject) => {\n                for (let u of uploadFileRes.uploadSuccess) {\n                  if (u.status && u.path) {\n                    let presignedUrl = await generatePreSignedURL(u.path);\n                    if (presignedUrl && presignedUrl.status) {\n                      u.path = presignedUrl.path;\n                    }\n                    finalResponse.push(u);\n                  }\n                }\n                resolve(finalResponse);\n              });\n            }\n          <%_}_%>\n          let fileUploadResponseObj = {};\n          if (uploadFileRes.uploadSuccess.length > 0) {\n            let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          } else {\n            let message = 'Failed to upload files.';\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          }\n\n          combinedOutput.uploadFileRes = fileUploadResponseObj;\n          return response.success({ data: combinedOutput });\n        <%_} else {_%>\n          let combinedOutput = {};\n          let defaultDirectory = 'public/assets';\n          let allowedFileTypes = <%=ALLOWED_TYPE%>;\n          <%_ let max_size = MAX_SIZE ? MAX_SIZE : 5 _%>\n          let maxFileSize = <%=max_size%>; //In Megabyte\n\n          // Create Directory if not exist.\n          await makeDirectory(defaultDirectory);\n          \n          // Setting up formidable options.\n          const form = new formidable.IncomingForm();\n          form.multiples = true;\n          form.maxFileSize = 300 * 1024 * 1024; //300 MB\n          form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n          //Parse Form data\n          const {\n            fields, files\n          } = await new Promise(async (resolve, reject) => {\n            form.parse(req, function (err, fields, files) {\n              if (err) reject(err);\n              resolve({\n                fields,\n                files\n              });\n            });\n          });\n          \n          let uploadSuccess = [];\n          let uploadFailed = [];\n          let fileCount = 1;\n\n          let fileArr = [];\n          if (!files['file[]'] || files['file[]'].size == 0) {\n            return response.badRequest({message : 'Select at least one file to upload.'});\n          }\n          if (!Array.isArray(files['file[]'])) {\n            fileArr.push(files['file[]']);\n            files['file[]'] = fileArr;\n          }\n\n          for (let file of files['file[]']) {\n            let response = await uploadFilesOnLocalServer(file, fields, fileCount++, allowedFileTypes, maxFileSize, defaultDirectory);\n            if (response.status == false) {\n              uploadFailed.push({\n                'name': file.name,\n                'error': response.message,\n                'status': false\n              });\n            } else {\n              let url = response.data;\n              if (!validUrl.isUri(response.data)) {\n                response.data = response.data.replace('/public', '');\n                url = `${response.data}`;\n              }\n              uploadSuccess.push({\n                'name': file.name,\n                'path': url,\n                'status': true\n              });\n            }\n          }\n\n          let uploadFileRes = {\n            uploadSuccess,\n            uploadFailed\n          };\n\n          let fileUploadResponseObj = {};\n          if (uploadFileRes.uploadSuccess.length > 0) {\n            let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          } else {\n            let message = 'Failed to upload files.';\n            fileUploadResponseObj = {\n              message: message,\n              data: uploadFileRes\n            };\n          }\n\n          combinedOutput.uploadFileRes = fileUploadResponseObj;\n          return response.success({ data: combinedOutput });\n          \n        <%_ } _%>\n}\n\nmodule.exports = upload;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/findAll.js.ejs",
    "content": "/**\n *findAll.js\n */\n\nconst response = require('../../utils/response');\n\nconst findAll = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query, options,isCountOnly } = params;\n    if(isCountOnly){\n        let count = await <%-MODEL_NAME-%>Db.count(query);\n        let result = { totalRecords: count };\n        return response.success({ data:result });  \n    } else {\n        let result = await <%-MODEL_NAME-%>Db.paginate(query,options);\n        if(result){\n            return response.success({ data:result });\n        }\n        return response.recordNotFound();\n    }\n}\nmodule.exports = findAll;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/findById.js.ejs",
    "content": "/**\n findById.js\n */\n\nconst response = require('../../utils/response');\n\nconst findById = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let result = await <%-MODEL_NAME-%>Db.findOne(params.query, params.options);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\nmodule.exports = findById;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/partialUpdate.js.ejs",
    "content": "/**\n partialUpdate.js\n */\n\nconst <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\nconst partialUpdate = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    const <%-MODEL_NAME.toLowerCase()-%> = await <%-MODEL_NAME-%>Db.updateOne(params.query,params.dataToUpdate);\n    if(!<%-MODEL_NAME.toLowerCase()-%>){\n        return response.recordNotFound();\n    }\n    return response.success({data:<%-MODEL_NAME.toLowerCase()-%>});\n}\nmodule.exports = partialUpdate;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/softDelete.js.ejs",
    "content": "/**\n softDelete.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeSoftDeleteWithDependency = require('./deleteDependent').softDeleteWithDependency;\n<%_ } _%>\n\n\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst softDelete = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n    let {query,dataToUpdate,isWarning } = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const softDeleteWithDependency = makeSoftDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        return await softDeleteWithDependency(query, dataToUpdate);\n    }\n    \n}\n<%_ } else { _%>\nconst softDelete = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query,dataToUpdate } = params;\n    let result = await <%-MODEL_NAME-%>Db.softDelete(query, dataToUpdate);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\n<%_ } _%>\nmodule.exports = softDelete;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/softDeleteMany.js.ejs",
    "content": "/**\n softDeleteMany.js\n */\n\nconst response = require('../../utils/response');\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\n    const makeGetDependencyCount = require('./deleteDependent').getDependencyCount;\n    const makeSoftDeleteWithDependency = require('./deleteDependent').softDeleteWithDependency;\n<%_ } _%>\n\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst softDeleteMany = ({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (params) => {\n   let { query, dataToUpdate,isWarning} = params;\n    if (isWarning) {\n        const getDependencyCount = makeGetDependencyCount({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        let result = await getDependencyCount(query);\n        return response.success({data:result});\n    } else {\n        const softDeleteWithDependency = makeSoftDeleteWithDependency({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) //dependency injection\n        return await softDeleteWithDependency(query, dataToUpdate);\n    }\n    \n}\n<%_ } else { _%>\nconst softDeleteMany = ({ <%-MODEL_NAME-%>Db }) => async (params) => {\n    let { query,dataToUpdate } = params;\n    let result = await <%-MODEL_NAME-%>Db.softDeleteMany(query, dataToUpdate);\n    if(!result){\n        return response.recordNotFound();\n    }\n    return response.success({data:result});\n}\n<%_ } _%>\nmodule.exports = softDeleteMany;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/update.js.ejs",
    "content": "/**\n *update.js\n */\n\nconst <%-MODEL_NAME.toLowerCase()-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\nconst update = ({ <%-MODEL_NAME-%>Db, updateValidation}) => async (params) => {\n    let { dataToUpdate, query } = params;\n    const validateRequest = await updateValidation(dataToUpdate);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let  <%-MODEL_NAME.toLowerCase()-%> =  <%-MODEL_NAME.toLowerCase()-%>Entity(dataToUpdate);\n\n    <%-MODEL_NAME.toLowerCase()-%> = await <%-MODEL_NAME-%>Db.updateOne(query,<%-MODEL_NAME.toLowerCase()-%>);\n    if(!<%-MODEL_NAME.toLowerCase()-%>){\n        return response.recordNotFound();\n    }\n    return response.success({data:<%-MODEL_NAME.toLowerCase()-%>});\n}\nmodule.exports = update;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/use-case/updateProfile.js.ejs",
    "content": "/**\n updateProfile.js\n */\n\n\nconst <%-MODEL_NAME-%>Entity = require('../../entities/<%-MODEL_NAME-%>');\nconst response = require('../../utils/response');\n\nconst updateProfile = ({<%-MODEL_NAME-%>Db,updateValidation}) => async (params,id) => {\n    delete params.createdAt;\n    delete params.updatedAt;\n    delete params.id;\n    const validateRequest = await updateValidation(params);\n    if (!validateRequest.isValid) {\n        return response.validationError({ message : `Invalid values in parameters, ${validateRequest.message}` });\n    }\n    let <%-MODEL_NAME.toLowerCase()-%> = <%-MODEL_NAME-%>Entity(params);\n    let updated<%-MODEL_NAME_FC%> = await <%-MODEL_NAME-%>Db.updateOne({id:id},<%-MODEL_NAME.toLowerCase()-%>);\n    return response.success({data:updated<%-MODEL_NAME_FC%>});\n}\nmodule.exports = updateProfile;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/common.js.ejs",
    "content": "const { Op } = require('sequelize');\n/*\n* convertObjectToEnum : convert object to enum\n* @param obj          : {}\n*/\nfunction convertObjectToEnum (obj) {\n  if (Array.isArray(obj)) {\n    return obj;\n  }\n  const enumArr = [];\n  Object.values(obj).map((val) => enumArr.push(String(val)));\n  return enumArr;\n};\n\n/*\n * randomNumber : generate random numbers.\n * @param length          : number *default 4\n */\nfunction randomNumber (length = 4) {\n  const numbers = '12345678901234567890';\n  let result = '';\n  for (let i = length; i > 0; i -= 1) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\n/*\n * replaceAll: find and replace al; occurrence of a string in a searched string\n * @param string : string to be replace\n * @param search : string which you want to replace\n * @param replace: string with which you want to replace a string\n */\nconst replaceAll = (string, search, replace) => string.split(search).join(replace);\n\n<%_if(IS_AUTH){ _%>\nfunction makeUniqueValidation (<%-MODEL%>Service) {\nconst uniqueValidation = async (data) =>{\n  const { Op } = require('sequelize');\n    <%_if (LOGIN_WITH.length > 1) {_%>\n      let filter = { [Op.or]:[]};\n      <%_for(let i in LOGIN_WITH){_%>\n      if(data && data[\"<%-LOGIN_WITH[i]%>\"]){\n          filter[Op.or].push(\n          <%_for(let j in LOGIN_WITH){_%>\n          {\"<%-LOGIN_WITH[j]%>\":data[\"<%-LOGIN_WITH[i]%>\"]},\n          <%_}_%>\n          )\n      }\n      <%_}_%>\n      <%_} else {_%>\n      let filter = {};\n      if(data && data[\"<%-LOGIN_WITH[0]%>\"]){\n          filter = { \"<%-LOGIN_WITH[0]%>\": data[\"<%-LOGIN_WITH[0]%>\"] }\n      }\n      <%_}_%>\n      let found = await <%-MODEL%>Service.findOne(filter);\n      if(found){\n          return false;\n      }\n      return true;\n  }\nreturn Object.freeze({ uniqueValidation });\n}\n<%_}_%>\n\n<%_if(IS_AUTH){_%>\nconst getDifferenceOfTwoDatesInTime = (currentDate,toDate) =>{\n  let hours = toDate.diff(currentDate,'hour');\n  currentDate =  currentDate.add(hours, 'hour');\n  let minutes = toDate.diff(currentDate,'minute');\n  currentDate =  currentDate.add(minutes, 'minute');\n  let seconds = toDate.diff(currentDate,'second');\n  currentDate =  currentDate.add(seconds, 'second');\n  if (hours){\n    return `${hours} hour, ${minutes} minute and ${seconds} second`; \n  }\n  return `${minutes} minute and ${seconds} second`; \n}\n<%_}_%>\n<%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n/*\n * getRoleAccessData: return roleAccess of User\n * @param model : sequelize models\n * @param userRoleService : user role db service\n * @param routeRoleService : route role db service\n * @param userId : Id of user to find role data\n */\nconst getRoleAccessData = async (model,userRoleService,routeRoleService,userId) =>{\n  let userRoles = await userRoleService.findAllRecords({ userId: userId });\n  let routeRoles = await routeRoleService.findAllRecords({ roleId: { [Op.in]: userRoles && userRoles.length ? userRoles.map(u=>u.roleId) : [] } },\n    {\n      include:[{\n        model: model.projectRoute,\n        as:'_routeId'\n      },{\n        model: model.role,\n        as: '_roleId'\n      }] \n    });\n  let models = Object.keys(model);\n  let Roles = routeRoles && routeRoles.length ? routeRoles.map(rr => rr._roleId && rr._roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (Roles.length){\n    Roles.map(role => {\n      roleAccess[role] = {};\n      models.forEach(model => {\n        if (routeRoles && routeRoles.length) {\n          routeRoles.map(rr => {\n            if (rr._routeId && rr._routeId.uri.includes(model.toLowerCase()) && rr._roleId && rr._roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr._routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr._routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr._routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr._routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return roleAccess;\n};\n<%_}_%>\n\nmodule.exports = {\n  convertObjectToEnum,\n  randomNumber,\n  replaceAll,\n  <%_if(IS_AUTH){ _%>\n  makeUniqueValidation,\n  getDifferenceOfTwoDatesInTime,\n  <%_}_%>\n  <%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n  getRoleAccessData,\n  <%_}_%>\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/convertObjectToEnum.js",
    "content": "const convertObjectToEnum = (obj) => {\n  const enumArr = [];\n  Object.values(obj).map((val) => enumArr.push(val));\n  return enumArr;\n};\n\nmodule.exports = convertObjectToEnum;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/deleteDependentService1.js.ejs",
    "content": "<%_ \n    const groupBy = function (xs, key) {\n    return xs.reduce(function (rv, x) {\n        (rv[x[key]] = rv[x[key]] || []).push(x);\n        return rv;\n    }, {});\n    };\n\n    let modelDependency = groupBy(DELETE_DEPENDENCY, 'model');\n_%>\nconst response = require('../../utils/response');\n\nconst getDependencyCount =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})=> async (filter) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj.id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    const <%-modelName%>Cnt =  await <%-modelDbName%>.count(<%-modelFilterName%>);\n                <%_  }\n            _%>\n                let result = { <%_  for (modelName in modelDependency) {  _%> <%-modelName%> : <%-modelName%>Cnt,  <%_  }  _%>}\n                return result;\n        }else{\n            return {  <%-MODEL_NAME%> : 0};\n        }\n    <%_}else{_%>\n    const <%-MODEL_NAME%>Cnt =  await <%-MODEL_NAME%>Db.count(filter);\n    return {<%-MODEL_NAME%> : <%-MODEL_NAME%>Cnt}\n    <%_}_%>\n}\n\nconst deleteWithDependency =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>})=> async (filter) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj.id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    await <%-modelDbName%>.deleteMany(<%-modelFilterName%>);\n                <%_  }\n            _%>\n\n                let result = await <%-MODEL_NAME%>Db.deleteMany(filter);\n                return response.success({data :result });\n        }else{\n            return response.badRequest({message :\"No <%-MODEL_NAME%> found.\" });\n        }\n    <%_}else{_%>\n    let result =  await <%-MODEL_NAME%>Db.deleteMany(filter);\n    return response.success({data :result });\n    <%_}_%>\n}\n\nconst softDeleteWithDependency =({<%_ DB_DEPENDENCY_INJECTION.forEach((model) => {_%><%- model %>Db<%_ if(DB_DEPENDENCY_INJECTION[DB_DEPENDENCY_INJECTION.length - 1] != model ){%>,<%_} }); %>}) => async (filter,updateBody) =>{\n    <%_if(DELETE_DEPENDENCY && DELETE_DEPENDENCY.length){_%>\n        let <%-MODEL_NAME%> = await <%-MODEL_NAME%>Db.findMany(filter, {id:1});\n        if(<%-MODEL_NAME%>.length){\n            let <%-MODEL_NAME%>Ids = <%-MODEL_NAME%>.map((obj) => obj.id);\n            <%_ \n                \n                for (modelName in modelDependency) {\n                    const modelDbName = modelName + 'Db';\n                    const modelFilterName = `${modelName}Filter`;\n                    let filterKeyArray = [];\n                    (modelDependency[modelName]).forEach((element) => {\n                    filterKeyArray.push(element.refId)\n                    });_%>\n\n                const <%-modelFilterName%> = {\"$or\": [{<%_filterKeyArray.forEach((element, index) => {_%><%-element%> : {\"$in\" : <%-MODEL_NAME%>Ids } <%_if( index+1 !== filterKeyArray.length ){ _%> },{ <%_ } _%>\n                    <%_ })  _%>  }]}\n                    await <%-modelDbName%>.updateMany(<%-modelFilterName%>,updateBody);\n                <%_  }\n            _%>\n\n                let result = await <%-MODEL_NAME%>Db.updateMany(filter,updateBody);\n                return response.success({data : result});\n        }else{\n            return response.badRequest({message : \"No <%-MODEL_NAME%> found.\"});\n        }\n    <%_}else{_%>\n    let result = await <%-MODEL_NAME%>.updateMany(filter,updateBody);\n    return response.success({data : result});\n    <%_}_%>\n}\nmodule.exports = {getDependencyCount, deleteWithDependency,softDeleteWithDependency}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/generateRandomNumber.js",
    "content": "const generateRandomNumber = (length = 4) => {\n  const numbers = '12345678901234567890';\n  let result = '';\n  for (let i = length; i > 0; i -= 1) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\nmodule.exports = generateRandomNumber;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/generateToken.js",
    "content": "/* eslint-disable */\nconst jwt = require('jsonwebtoken');\nconst { JWT } = require('../constants/authConstant');\n\nasync function generateToken (user, secret) {\n  return jwt.sign({\n    id: user.id,\n    username: user.username,\n  }, secret, { expiresIn: JWT.EXPIRES_IN });\n}\n\nmodule.exports = generateToken;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/getSelectObject.js",
    "content": "/**\n * getSelectObject : to return a object of select from string, array\n * @param {string/array/obj} select : selection attributes\n * @returns {object} : object of select to be passed with filter\n */\nconst getSelectObject = (select) => {\n  let selectArray = [];\n  if (typeof select === 'string') {\n    selectArray = select.split(' ');\n  } else if (Array.isArray(select)) {\n    selectArray = select;\n  } else if (typeof select === 'object') {\n    return select;\n  }\n  const selectObject = {};\n  if (selectArray.length) {\n    for (let index = 0; index < selectArray.length; index += 1) {\n      const element = selectArray[index];\n      if (element.startsWith('-')) {\n        Object.assign(selectObject, { [element.substring(1)]: -1 });\n      } else {\n        Object.assign(selectObject, { [element]: 1 });\n      }\n    }\n  }\n  return selectObject;\n};\n\nmodule.exports = getSelectObject;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/makeDirectory.js",
    "content": "const fs = require('fs');\n/**\n *\n * Function used to create directory.\n *\n * @param  {string} dirPath\n * @returns  {boolean}\n */\nconst makeDirectory = async (directoryPath) => {\n  if (!fs.existsSync(directoryPath)) {\n    fs.mkdirSync(directoryPath, { recursive: true });\n    return true;\n  }\n  return true;\n};\n\nmodule.exports = makeDirectory;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/messages.js",
    "content": "const responseCode = require('./responseCode');\n\nmodule.exports = {\n  successResponse: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.success,\n    data: {\n      status: 'SUCCESS',\n      message: data.message || 'Your request is successfully executed',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  failureResponse: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.internalServerError,\n    data: {\n      status: 'FAILURE',\n      message: data.message || 'Internal server error.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  badRequest: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.badRequest,\n    data: {\n      status: 'BAD_REQUEST',\n      message: data.message || 'The request cannot be fulfilled due to bad syntax.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  isDuplicate: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.validationError,\n    data: {\n      status: 'VALIDATION_ERROR',\n      message: data.message || 'Data duplication found.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  recordNotFound: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.success,\n    data: {\n      status: 'RECORD_NOT_FOUND',\n      message: data.message || 'Record not found with specified criteria.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  insufficientParameters: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.badRequest,\n    data: {\n      status: 'BAD_REQUEST',\n      message: data.message || 'Insufficient parameters.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  inValidParam: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.validationError,\n    data: {\n      status: 'VALIDATION_ERROR',\n      message: data.message || `Invalid Data, Validation Failed.`,\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  unAuthorizedRequest: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.unAuthorizedRequest,\n    data: {\n      status: 'UNAUTHORIZED',\n      message: data.message || 'You are not authorized to access the request',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  loginSuccess: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.success,\n    data: {\n      status: 'SUCCESS',\n      message: data.message || 'Login Successful',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  loginFailed: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.badRequest,\n    data: {\n      status: 'BAD_REQUEST',\n      message: data.message || `Login Failed.`,\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  invalidRequest: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.success,\n    data: {\n      status: 'FAILURE',\n      message: data.message || 'Invalid Data, Validation Failed.',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n\n  requestValidated: (data = {}) => ({\n    headers: data.headers || { 'Content-Type': 'application/json' },\n    statusCode: data.statusCode || responseCode.success,\n    data: {\n      status: 'SUCCESS',\n      message: data.message || 'Your request is successfully executed',\n      data: data.data && Object.keys(data.data).length ? data.data : null,\n    },\n  }),\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/replaceAll.js",
    "content": "/**\n * replaceAll: find and replace all occurrence of a string in a searched string\n * @param {string} string  : string to be replace\n * @param {string} search  : string which you want to replace\n * @param {string} replace : string with which you want to replace a string\n * @return {string} : replaced new string\n */\n\nfunction replaceAll (string, search, replace) {\n  return string.split(search).join(replace);\n}\n\nmodule.exports = replaceAll;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/response/index.js",
    "content": "const responseStatus = require('./responseStatus');\n\nmodule.exports = {\n  success: (data = {}) => ({\n    status: responseStatus.success,\n    message: data.message || 'Your request is successfully executed',\n    data: data.data || {},\n  }),\n\n  failure: (data = {}) => ({\n    status: responseStatus.failure,\n    message: data.message || 'Some error occurred while performing action.',\n    data: data.data || {},\n  }),\n\n  internalServerError: (data = {}) => ({\n    status: responseStatus.serverError,\n    message: data.message || 'Internal server error.',\n    data: data.data || {},\n  }),\n\n  badRequest: (data = {}) => ({\n    status: responseStatus.badRequest,\n    message: data.message || 'The request cannot be fulfilled due to bad syntax.',\n    data: data.data || {},\n  }),\n\n  recordNotFound: (data = {}) => ({\n    status: responseStatus.recordNotFound,\n    message: data.message || 'Record(s) not found with specified criteria.',\n    data: data.data || {},\n  }),\n\n  validationError: (data = {}) => ({\n    status: responseStatus.validationError,\n    message: data.message || `Invalid Data, Validation Failed.`,\n    data: data.data || {},\n  }),\n\n  unAuthorized: (data = {}) => ({\n    status: responseStatus.unauthorized,\n    message: data.message || 'You are not authorized to access the request',\n    data: data.data || {},\n  }),\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/response/responseCode.js",
    "content": "module.exports = {\n  success: 200,\n  badRequest: 400,\n  internalServerError: 500,\n  unAuthorized: 401,\n  notFound: 404,\n  validationError: 422,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/response/responseHandler.js",
    "content": "const responseCode = require('./responseCode');\n\nmodule.exports = (res, body = {}) => {\n  const headers = body.headers || { 'Content-Type': 'application/json' };\n  let statusCode;\n\n  switch (body.status) {\n  case 'SUCCESS':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'FAILURE':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'SERVER_ERROR':\n    statusCode = body.statusCode || responseCode.internalServerError;\n    break;\n  case 'BAD_REQUEST':\n    statusCode = body.statusCode || responseCode.badRequest;\n    break;\n  case 'RECORD_NOT_FOUND':\n    statusCode = body.statusCode || responseCode.success;\n    break;\n  case 'VALIDATION_ERROR':\n    statusCode = body.statusCode || responseCode.validationError;\n    break;\n  case 'UNAUTHORIZED':\n    statusCode = body.statusCode || responseCode.unAuthorized;\n    break;\n  default:\n    statusCode = responseCode.internalServerError;\n  }\n  return res.set(headers).status(statusCode).send(body);\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/response/responseStatus.js",
    "content": "module.exports = {\n  success: 'SUCCESS',\n  failure: 'FAILURE',\n  serverError: 'SERVER_ERROR',\n  badRequest: 'BAD_REQUEST',\n  recordNotFound: 'RECORD_NOT_FOUND',\n  validationError: 'VALIDATION_ERROR',\n  unauthorized: 'UNAUTHORIZED',\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/responseCode.js",
    "content": "module.exports = {\n  success: 200,\n  badRequest: 400,\n  internalServerError: 500,\n  unAuthorized: 401,\n  notFound: 404,\n  validationError: 422,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/utils/validateRequest.js",
    "content": "const joi = require('joi');\n\nexports.validateParamsWithJoi = (body, schemaKeys) => {\n  const schema = joi.object(schemaKeys);\n\n  const { error } = schema.validate(body, { abortEarly: false });\n\n  if (error && error.details) {\n    const message = error.details.map((el) => el.message).join('\\n');\n    return {\n      isValid: false,\n      message,\n    };\n  }\n  return { isValid: true };\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/validation/genericValidator.js",
    "content": "function makeValidator (schema) {\n  return function validator (payload) {\n    const { error } = schema.validate(payload, { abortEarly: false });\n    if (error) {\n      const message = error.details.map((el) => el.message).join('\\n');\n      return { error: message };\n    }\n    return { error: false };\n  };\n}\n\nmodule.exports = makeValidator;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/validation/index.js",
    "content": "const schemaValidation = (schema) => (data) => {\n  const { error } = schema.validate(data);\n  if (error) {\n    const message = error.details.map((el) => el.message).join('\\n');\n    return {\n      isValid: false,\n      message,\n    };\n  }\n  return { isValid: true };\n};\n\nmodule.exports = schemaValidation;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/validation/validateSchema.js.ejs",
    "content": "\n<%let flag=0%>\nconst joi = require(\"joi\")\n<%_ if(typeof VARIABLES !== \"undefined\") {\n  for(let i=0;i< VARIABLES.length; i++) {_%>\n    <%-VARIABLES[i]%>\n  <%_ } \n} _%>\n<%_if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){_%>\n  const {USER_ROLE} = require('../../constants/authConstant');\n  const {convertObjectToEnum} = require(\"../../utils/convertObjectToEnum\")   \n<%flag=1%>\n<%_}_%>\n<%_if(ENUM_VALIDATION){_%>\n<%_if(!IS_AUTH){_%>\n  const {convertObjectToEnum} = require(\"../utils/common\")   \n<%_}_%>        \n<%_for(let enumIndex of ENUM_VALIDATION){_%>\n  const <%-enumIndex%>Default=require('../constants/<%-enumIndex%>');    \n<%_}_%>       \n<%_}_%>    \n    \nconst createSchema = joi.object(<%-VALIDATION_KEY%>).unknown(true);\nconst updateSchema = joi.object(<%-UPDATE_VALIDATION_KEY%>).unknown(true);\n\nmodule.exports = {createSchema, updateSchema};"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/views/emailTemplate.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <!-- message -->\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear ,</b>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/views/index.ejs",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n  <link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\" rel=\"stylesheet\">\n  <link rel=\"icon\" type=\"image/png\" href=\"https://dxuoui1db8w1y.cloudfront.net/index.png?o=g\">\n  <title>welcome to node.js</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n\n    body {\n      font-family: 'Courier Prime', monospace;\n      height: 100vh;\n      background-color: #181818;\n      display: flex;\n    }\n    .sidebar{\n      height: 100vh;\n    }\n    .main-section{\n      padding: 100px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    h1{\n      color: #ffffff;\n      font-weight: 100;\n      font-size: 4vw;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <img class=\"sidebar\" src=\"https://dxuoui1db8w1y.cloudfront.net/sidebar.jpg?o=g\" alt=\"sidebar\">\n  </div>\n  <div class=\"main-section\">\n    <div>\n      <div style=\"display: flex; justify-content: space-between; margin-bottom: 50px;\">\n        <img src=\"https://dxuoui1db8w1y.cloudfront.net/dhiwise.png?o=g\" alt=\"dhiwise\" style=\"width: 130px;\">\n      </div>\n    <h1><br>Welcome to <span style=\"color: #3E863D;\">Node.Js</span><br>application </h1>\n  </div>\n  </div>\n</body>\n\n</html>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/views/resetPassword.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <%-message%>\n                    </div>\n                </div>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/views/resetPasswordLink.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        Reset Password Link\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,<%-message%></b>\n                </p>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    <a href=\"<%-link%>\"><%-linkText%></a>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/cleanCodeSequelize/views/sendOTP.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        OTP\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,</b>\n                </p>\n            </td>\n        </tr>\n        <% if(otp) { %>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    Your OTP code is <strong> <%- otp %></strong>\n                </p>\n            </td>\n        </tr>\n        <% } %>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/logs/error.log.ejs",
    "content": "ERRORS IN MODELS:\n<% ERRORS.forEach(function(errorObj){ %>\nERR at model : <%- errorObj.model %>\nERR at attribute : <%- errorObj.attribute %>\n<%if(errorObj.value){%>ERR at value : <%- errorObj.value %><%}%>\n<%if(errorObj.message){%>ERR message : <%- errorObj.message %><%}%>\n<%if(errorObj.suggestion){%>suggestion : <%- errorObj.suggestion %><%}%>\n<% }); %>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  parserOptions: {\n    ecmaVersion: 12,\n    sourceType: 'module',\n  },\n  rules: {\n    semi: ['error', 'always'],\n    indent: ['error', 2],\n    'no-irregular-whitespace': ['error', {\n      skipStrings: true,\n      skipComments: true,\n      skipRegExps: true,\n      skipTemplates: true,\n    }],\n    'multiline-comment-style': ['error', 'starred-block'],\n    'object-property-newline': ['error', {\n      allowAllPropertiesOnSameLine: false,\n      allowMultiplePropertiesPerLine: false,\n    }],\n    'object-curly-newline': ['error', {\n      minProperties: 2,\n      multiline: true,\n    }],\n    'no-multiple-empty-lines': ['error', {\n      max: 1,\n      maxEOF: 0,\n    }],\n    'no-param-reassign': 'off',\n    'no-underscore-dangle': 'off',\n    'class-methods-use-this': 'off',\n    'max-len': [2, {\n      code: 1000,\n      ignorePattern: '^import .*',\n    }],\n    'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],\n    'space-infix-ops': ['error', { int32Hint: false }],\n    'space-before-function-paren': ['error', {\n      anonymous: 'always',\n      named: 'always',\n      asyncArrow: 'always',\n    }],\n    'keyword-spacing': ['error', {\n      before: true,\n      after: true,\n    }],\n    'object-curly-spacing': ['error', 'always'],\n    quotes: ['error', 'single', { allowTemplateLiterals: true }],\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/.gitignore",
    "content": "node_modules\n.dhiwise"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/README.ejs",
    "content": "# NodeJS,Mongoose,Express Project in MVC Architecture\n\n**supported version of nodejs > 12**,\n**supported version of mongoose-4.0**\n\n- This is a Web application, developed using MVC pattern with Node.js, ExpressJS, and Mongoose ODM. \n- Basic boilerplate for web applications, built on Express.js using the Model–View–Controller architectural pattern.\n- MongoDB database is used for data storage, with object modeling provided by Mongoose.\n\n# Initial\n- Configure a basic server in app.js.\n- Organize the routes with Express Router.\n- Use the mainRoutes in app as middleware.\n- Set a final use after the routes, to display a 404 message for the unhandled requests.\n1. Install needed Node.js modules:\n    ```$ npm install```\n2. execute server:\n    ```$ npm start```\n\t<%_if(IS_AUTH){_%>\n3. When the app will run successfully,\n<%_if(ROLE_WISE_CREDENTIALS){_%>\n<%_for (let i in ROLE_WISE_CREDENTIALS){_%>\n\n       - One user with <%-i%> role,\n\t   # Default <%-i%> credentials\n\t   **username** : <%-ROLE_WISE_CREDENTIALS[i][USER_FIELD]%>\n\t   **password** : <%-ROLE_WISE_CREDENTIALS[i][PASSWORD_FIELD]%>\n\n<%_}_%> \n<%_}_%>\t \n\t<%_}_%>\n\n# Default folder structure:\n\n\t--project_folder\n\t\t--config\n\t\t--controller\n\t\t--logs\n\t\t--middleware\n\t\t--models\n\t\t--postman\n\t\t--public\n\t\t--routes\n\t\t--services\n\t\t--utils\n\t\t--views\n\t\t--app.js\n\t\t--.env\n\t\t--.gitignore\n\t\t--.eslintrc.js\n# app.js\n- entry point of application.\n# config\n- passport strategy for all platforms.\n- based on Auth Model - authentication files has been generated.\n- Auth constant File that has authentication configuration constants\n- Used .env file and configure the db connection string to use in the project.\n# controller\n- includes controller files per model\n- Controllers are separated per Platform\n\n     \t  -controller\n     \t        -admin\n     \t          -modelController.js\n     \t        -device\n     \t          -modelController.js\n     \t        -desktop\n     \t          -modelController.js\n     \t        -client\n     \t          -modelController.js\n# logs\n- Log file\n# middleware\n- User authentication Middleware based on Roles and permission for Routes' access\n- Custom Policy files\n# models\n- Mongoose Models , as per user defined schema \n# postman\n- Postman collection File for Platform based APIs that are generated.\n- Import this JSON in Postman to test the APIs.\n# public \n- You can add static files like like images, pdf etc.\n# routes\n- based on platform,separate folder is generated,within those folders model wise route files are that has model crud APIs' routes.\n- index.js file, main file which includes all platform routes.\n- added index files in app.js to access the routes of the application.\n# services\n     \t-auth.js\n       \t\t-Logic for JWT Tokenization for user to login into Application using username and password along with otp if required.\n# utils\n\t     -validation\n     \t\t-joi validations files.\n     \t\t-files are separated by models.\n     \t -common.js\n       \t\t-converted object to enum function.\n     \t -dbService.js\n       \t\t -common Database functionalities\n     \t  \t -getAllDocuments(find all documents)\n     \t  \t -updateDocuments(update single documents in db)\n     \t  \t -deleteDocuments(delete single documents in db)\n     \t  \t -createDocuments(create single documents in db)\n     \t  \t -getDocumentByQuery(find single document)\n\t\t\t -getSingleDocumentById(find by id)\n     \t  \t -softDelete\n     \t  \t -findExistData\n     \t  \t -bulkInsert(insert multiple documents in db)\n     \t  \t -bulkUpdate(update multiple documents in db)\n     \t  \t -countDocument\n\t\t\t -Aggregation\n     \t -messages.js\n  \t\t     -static messages that are sent with response - contains status and Data\n\t      -responseCode.js\n  \t\t     -codes for responses\n\t      -validateRequest.js\n  \t\t     -validate schema based on joi validation\n# views\n- add ejs files"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/__test__/auth.test.js.ejs",
    "content": "/**\n * auth.test.js\n * @description :: contains test cases of APIs for authentication module.\n */\n\n<%_\nif(typeof(AUTH_MODEL_JSON) !== 'undefined'){\n  Object.keys(AUTH_MODEL_JSON).forEach(function(field){\n    if(AUTH_MODEL_JSON[field].type === 'Schema.Types.ObjectId' && AUTH_MODEL_JSON[field].ref !== undefined){\n      var newString = new String()\n      newString=JSON.stringify(AUTH_MODEL_JSON[field].ref);\n      newString = newString.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\" );\n      newString = newString.charAt(0).toUpperCase() + newString.slice(1);\n      FAKE_DATA_OF_AUTH[field] = `@@inserted${newString}.insertedId@@`\n    }  \n  })\n}\n_%>\n\nconst dotenv = require('dotenv');\ndotenv.config();\nprocess.env.NODE_ENV = 'test';\nconst db = require('mongoose');\nconst request = require('supertest');\nconst { MongoClient, ObjectId } = require('mongodb');\nconst app = require('../../app.js');\nconst authConstant=require('../../constants/authConstant');\nconst uri = 'mongodb://127.0.0.1:27017';\n\nconst client = new MongoClient(uri, {\n    useUnifiedTopology: true,\n    useNewUrlParser: true\n});\n\n<%_if(typeof(MODELS) !== 'undefined'){_%>\n<%_ Object.keys(MODELS).forEach(function(model) { _%>\nlet inserted<%-MODELS[model].charAt(0).toUpperCase() + MODELS[model].slice(1);%> = {};\n<%_ }); _%> \n<%_}_%>\n\n/**\n * @description : model dependencies resolver\n */\nbeforeAll(async function(){\n  try {\n    await client.connect();\n    const db = client.db(<%=DB_NAME%>);\n\n    <%_if(typeof(FAKE_DATA) !== 'undefined'){_%>\n    <%_ Object.keys(FAKE_DATA).forEach(function(model){_%>\n    const <%-model%> = db.collection(<%=model%>);\n    inserted<%-model.charAt(0).toUpperCase() + model.slice(1); %> = await <%-model%>.insertOne(<%=JSON.parse(JSON.stringify(FAKE_DATA[model]))%>)\n    <%_})_%>\n    <%_}_%>\n  }\n  catch (err) {\n      console.error(`we encountered ${err}`);\n  }\n  finally {\n      client.close();\n  }\n})\n\n// test cases\n\ndescribe('POST /register -> if email and username is given', () => {\n  test('should register a <%-AUTH_MODEL%>', async () => {\n    let registeredUser = await request(app)\n      .post('/<%-PLATFORM%>/auth/register')\n      <%_var finalStr=new String(); \n      FAKE_DATA_OF_AUTH.role=`@@authConstant.USER_ROLE.${ROLE}@@`;\n        finalStr=JSON.stringify(FAKE_DATA_OF_AUTH); \n        finalStr=finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\" ); \n      _%>\n      .send(<%-finalStr%>);\n    expect(registeredUser.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(registeredUser.body.status).toBe('SUCCESS');\n    expect(registeredUser.body.data).toMatchObject({\n      id: expect.any(String)\n    });\n    expect(registeredUser.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username and password is correct', () => {\n  test('should return <%-AUTH_MODEL%> with authentication token', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n      expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n      expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n      expect(<%-AUTH_MODEL%>.body.data).toMatchObject({\n          id: expect.any(String),\n          token: expect.any(String)\n      }); \n      expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username is incorrect', () => {\n  test('should return unauthorized status and <%-AUTH_MODEL%> not exists', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: 'wrong.username',\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if password is incorrect', () => {\n  test('should return unauthorized status and incorrect password', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: 'wrong@password'\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if username or password is empty string or has not passed in body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Insufficient parameters');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /forgot-password -> if email has not passed from request body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ email: '' });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Insufficient parameters');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is not available in database ', () => {\n  test('should return record not found status', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': 'unavailable.email@hotmail.com', });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('RECORD_NOT_FOUND');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Record not found with specified criteria.');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is valid and OTP sent successfully', () => {\n  test('should return success message', async () => {\n    const expectedOutputMessages = [\n      'otp successfully send.',\n      'otp successfully send to your email.',\n      'otp successfully send to your mobile number.'\n    ];\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': <%_if(FAKE_DATA_OF_AUTH['email'] !== undefined) {_%><%=FAKE_DATA_OF_AUTH['email']%><%_}else{_%>'valid.mail@hotmail.com'<%_}_%>_%>, });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n    expect(expectedOutputMessages).toContain(<%-AUTH_MODEL%>.body.message);\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /validate-otp -> otp is sent in request body and OTP is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .post('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'otp': foundUser.body.data.resetPasswordLink.code, }).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('POST /validate-otp -> if OTP is incorrect or OTP has expired', () => {\n  test('should return invalid OTP', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({ 'otp': '12334' });\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid OTP');\n  });\n});\n\ndescribe('POST /validate-otp -> if request body is empty or otp has not been sent in body', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM.toLowerCase()%>/auth/validate-otp')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('PUT /reset-password -> code is sent in request body and code is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .put('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'code': foundUser.body.data.resetPasswordLink.code, 'newPassword':'newPassword'}).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('PUT /reset-password -> if request body is empty or code/newPassword is not given', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM.toLowerCase()%>/auth/reset-password')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('PUT /reset-password -> if code is invalid', () => {\n  test('should return invalid code', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM.toLowerCase()%>/auth/reset-password')\n      .send({\n        'code': '123',\n        'newPassword': 'testPassword'\n      });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid Code');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\nafterAll(function (done) {\n  db.connection.db.dropDatabase(function () {\n      db.connection.close(function () {\n          done();\n      });\n  });\n});\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/app.js.ejs",
    "content": "/**\n * app.js\n * Use `app.js` to run your app.\n * To start the server, run: `node app.js`.\n */\n\nconst express = require('express');\nconst cors = require('cors');\nconst path = require('path');\nconst dotenv = require('dotenv');\ndotenv.config();\nglobal.__basedir = __dirname;\nrequire('./config/db.js');\n<%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\nconst listEndpoints = require('express-list-endpoints')\n<%_}_%>\n<%_ if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){ _%>\nconst passport = require(\"passport\")\n<%_ } _%>\n\n<% Object.keys(modules).sort().forEach(function (variable) { -%>\nlet <%- variable %> = require('<%- modules[variable] %>');\n<% }); -%>\n<% Object.keys(localModules).sort().forEach(function (variable) { -%>\nconst <%- variable %> = require('<%- localModules[variable] %>');\n<% }); -%>\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\nconst {<%-platform.toLowerCase()%>PassportStrategy} = require(\"./config/<%-platform%>PassportStrategy\");\n<%_ } _%>\n<%_ } _%>\nconst app = express();\nconst corsOptions = {\n    origin: process.env.ALLOW_ORIGIN,\n}\napp.use(cors(corsOptions));\n\n//template engine\napp.set('view engine', 'ejs'); \napp.set('views', path.join(__dirname, 'views'));\napp.use(require('./utils/response/responseHandler'));\n\n<%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n//all routes \nconst routes =  require(\"./routes/index\")\n<%_ } _%>\n\n<%_uses.forEach(function (use) {_%>\napp.use(<%- use %>);\n<%_});_%>\n<%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\napp.use(routes)\n<%_ } _%>\n\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\n<%-platform.toLowerCase()%>PassportStrategy(passport);\n<%_ } _%>\n<%_ } _%>\n\n<% mounts.forEach(function (mount) { -%>\napp.use(<%= mount.path %>, <%- mount.code %>);\n<% }); -%>\n\napp.get('/', (req, res) => {\n  res.render('index');\n})\n\nif (process.env.NODE_ENV !== 'test' ) {\n    <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    const seeder = require('./seeders');\n    const allRegisterRoutes = listEndpoints(app);\n    seeder(allRegisterRoutes).then(()=>{console.log(\"Seeding done.\")});\n    <%_}else if(typeof SEEDER !== \"undefined\" && SEEDER){_%>\n    const seeder = require('./seeders');\n    seeder().then(()=>{console.log(\"Seeding done.\")});\n    <%_}_%>\n    app.listen(process.env.PORT,()=>{\n        console.log(`your application is running on ${process.env.PORT}`)\n    });\n} else {\n    module.exports = app;\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/config/constant.js.ejs",
    "content": "/**\n * authConstant.js\n * @description :: constants used in authentication\n */\n\nconst JWT={\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>_SECRET:\"myjwt<%- plt.toLowerCase() %>secret\",\n<%_ }); _%>\n    EXPIRES_IN: <%-TOKEN_EXPIRE_TIME%>\n}\n\nconst USER_ROLE ={\n    <%_ USER_ROLE.forEach(function (role,index) { _%>\n        <%- role %>:<%- index+=1 %>,\n    <%_ }); _%>\n}\n\nconst PLATFORM = {\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>:<%- index+1 %>,\n<%_ }); _%>\n}\n\nlet LOGIN_ACCESS ={\n<% Object.keys(LOGIN_ACCESS).map(function (key,index) { -%>\n    [USER_ROLE.<%- key %>]:<%_ let Arr=[]; LOGIN_ACCESS[key].forEach(function(plt,index){ _%>\n    <%_Arr.push(`PLATFORM.${plt.toUpperCase()}`);_%>\n<%_ }) _%><%-JSON.stringify(Arr).toString().replace(/\"/g, \"\");%>,        \n<% }); -%>\n}\n\nconst DEFAULT_ROLE= 1\n\n<%_if(LOGIN_RETRY_LIMIT){_%>\nconst MAX_LOGIN_RETRY_LIMIT = <%=LOGIN_RETRY_LIMIT.max%>;\nconst LOGIN_REACTIVE_TIME = <%=LOGIN_RETRY_LIMIT.reActiveTime%>;   \n<%_}_%>    \n\n<%_if(RESET_PASSWORD){_%>\nconst FORGOT_PASSWORD_WITH = <%-RESET_PASSWORD%>\n<%_}_%>\n<%_if(DEVICE_ALLOWED_REQUIRED){_%>\nconst NO_OF_DEVICE_ALLOWED = <%-NO_OF_DEVICE%>\n<%_}_%>\n\nmodule.exports = {\n    JWT,\n    USER_ROLE,\n    DEFAULT_ROLE,\n    PLATFORM,\n    <%_if(LOGIN_RETRY_LIMIT){_%>\n    MAX_LOGIN_RETRY_LIMIT,\n    LOGIN_REACTIVE_TIME,\n    <%_}_%>\n    <%_if(RESET_PASSWORD){_%>\n    FORGOT_PASSWORD_WITH,\n    <%_}_%>\n    <%_if(DEVICE_ALLOWED_REQUIRED){_%>\n    NO_OF_DEVICE_ALLOWED,\n    <%_}_%>\n    LOGIN_ACCESS\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/config/db.js.ejs",
    "content": "/**\n * db.js\n * @description :: exports database connection using mongoose\n */\n \nconst mongoose = require(\"mongoose\")\nconst uri = process.env.NODE_ENV === 'test' ? process.env.DB_TEST_URL : process.env.DB_URL;\nmongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });\nvar db = mongoose.connection\n\ndb.once(\"open\", () => {\n    console.log(\"Connection Successful\")\n})\n\ndb.on(\"error\", () => {\n    console.log(\"Error in mongodb connection\")\n})\n\nmodule.exports = mongoose"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/config/passport.js.ejs",
    "content": "/**\n * <%-STRATEGY%>PassportStrategy.js\n */\n\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\nconst <%- MODEL %> = require(\"../model/<%- MODEL%>\")\n\n/**\n * @description : exports authentication strategy for <%-STRATEGY.toLowerCase()%> using passport.js\n * @params {object} passport : passport object for authentication\n * @return {callback} : returns callback to be used in middleware\n */\nconst <%-STRATEGY.toLowerCase()%>PassportStrategy = (passport) => {\n    const options = {};\n    options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();\n    options.secretOrKey = JWT.<%-STRATEGY.toUpperCase()%>_SECRET;\n    passport.use('<%-STRATEGY.toLowerCase()%>-rule',\n        new Strategy(options, (payload, done) => {\n            <%- MODEL%>.findOne({ _id: payload.id }, (err, user) => {\n                if (err) {\n                    return done(err, false);\n                }\n                if (user) {\n                    return done(null, {\n                        ...user.toJSON()\n                    });\n                }\n                return done('No User Found', {});\n            });\n        })\n    );\n}\n\nmodule.exports = {\n    <%-STRATEGY.toLowerCase()%>PassportStrategy,\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/config/requestConstant.js.ejs",
    "content": "/**\n * <%-FILE_NAME%>.js\n */\n\nmodule.exports=<%=JSON.parse(CONSTANTS)%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/controllers/authController.js.ejs",
    "content": "/**\n * authController.js\n * @description :: exports authentication methods\n */\n\nconst authService =  require(\"../../services/auth\")\nconst <%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%> = require(\"../../model/<%-USER_MODEL%>\");\nconst dbService = require(\"../../utils/dbService\");\nconst userTokens = require(\"../../model/userTokens\");\nconst dayjs = require(\"dayjs\");\nconst <%-USER_MODEL %>SchemaKey = require(\"../../utils/validation/<%-USER_MODEL%>Validation\");\nconst validation = require(\"../../utils/validateRequest\");\n<%_if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\nconst emailService = require(\"../../services/email/emailService\")\n<%_}else if(NOTIFICATION_TYPE===\"SMS\"){_%>\nconst sendSMS = require(\"../../services/sms/smsService\");\nconst ejs = require(\"ejs\")\n<%_}_%>\nconst { uniqueValidation } = require('../../utils/common');\nconst { PLATFORM } = require(\"../../constants/authConstant\");\n\n/**\n * @description : user registration \n * @param {object} req : request for register\n * @param {object} res : response for register\n * @return {object} : response for register {status, message, data}\n */\nconst register = async(req, res) => {\n    try {\n        let validateRequest = validation.validateParamsWithJoi(\n            req.body,\n            <%-USER_MODEL %>SchemaKey.schemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message :  `Invalid values in parameters, ${validateRequest.message}`});\n        } \n        const data = new <%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>({\n            ...req.body\n        });\n        let unique = await uniqueValidation(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>,req.body);   \n        if (!unique){ \n            return res.validationError({message:'User Registration Failed, Duplicate Data found'});\n        } \n        const result = await dbService.createDocument(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>,data);\n        <%_if(NOTIFICATION_TYPE===\"SMS\"){_%>\n        // send sms to user for successfully registered.\n        let renderData = {\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n            <%_}else{_%>\n            ...result\n            <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-REGISTER_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n            to:result.<%=MOBILE_FIELD%>,\n            message:msg\n        }\n        await sendSMS(smsObj);\n        <%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\n        // send email to user for successfully registered.\n        let mailObj = {\n            subject: \"Register User\",\n            to: result.<%-EMAIL_FIELD%>,\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:{\n                <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n                <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n            }\n            <%_}else if(!REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:result\n            <%_}_%>\n        };\n        await emailService.sendEmail(mailObj);\n        <%_}_%>\n        return res.success({data:result});\n    } catch (error) {\n        if(error.name === \"ValidationError\"){\n            return res.validationError({message:error.message});\n        }\n        if(error.code && error.code == 11000){\n            return res.validationError({message:error.message});\n        }\n        return res.internalServerError();\n    }  \n}\n\n/**\n * @description : send email or sms to user with OTP on forgot password\n * @param {object} req : request for forgotPassword\n * @param {object} res : response for forgotPassword\n * @return {object} : response for forgotPassword {status, message, data}\n */ \nconst forgotPassword = async (req, res) => {\n    const params = {...req.body};\n    try {\n        if (!params.email) {\n            return res.badRequest();\n        }\n        let where = {<%-EMAIL_FIELD%>: params.email};\n        params.email = params.email.toString().toLowerCase();\n        let found = await dbService.getDocumentByQuery(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>,where);\n        if (!found) {\n            return res.recordNotFound();\n        }\n        let {resultOfEmail,resultOfSMS} = await authService.sendResetPasswordNotification(found);\n        if(resultOfEmail && resultOfSMS){\n            return res.success({message:\"otp successfully send.\"});\n        }else if(resultOfEmail && !resultOfSMS) {\n            return res.success({message:\"otp successfully send to your email.\"});\n        } else if (!resultOfEmail && resultOfSMS) { \n            return res.success({message:\"otp successfully send to your mobile number.\"});\n        }else{\n            return res.internalServerError({message:\"otp can not be sent due to some issue try again later\"});\n        }\n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\n/**\n * @description : validate OTP\n * @param {object} req : request for validateResetPasswordOtp\n * @param {object} res : response for validateResetPasswordOtp\n * @return {object} : response for validateResetPasswordOtp  {status, message, data}\n */\nconst validateResetPasswordOtp = async (req, res) => {\n    const params = req.body;\n    try {\n        if (!params || !params.otp) {\n            return res.badRequest();\n        }\n        let found = await dbService.getDocumentByQuery(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>, { 'resetPasswordLink.code': params.otp });\n        if (!found || !found.resetPasswordLink.expireTime) {\n            return res.failure({message:\"Invalid OTP\"});\n        }\n        if (dayjs(new Date()).isAfter(dayjs(found.resetPasswordLink.expireTime))) {\n            return res.failure({message:\"Your reset password link is expired or invalid\"});\n        }\n        await dbService.updateDocument(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>, found.id, { resetPasswordLink: {} })\n        return res.success({message:'Otp verified'});\n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\n/**\n * @description : reset password with code and new password\n * @param {object} req : request for resetPassword\n * @param {object} res : response for resetPassword\n * @return {object} : response for resetPassword {status, message, data}\n */ \nconst resetPassword = async (req, res) => {\n    const params = req.body;\n    try {\n        if (!params.code || !params.newPassword) {\n            return res.badRequest();\n        }\n        let found = await dbService.getDocumentByQuery(<%-USER_MODEL.charAt(0).toUpperCase() + USER_MODEL.slice(1);%>, { 'resetPasswordLink.code': params.code });\n        if (!found || !found.resetPasswordLink.expireTime) {\n            return res.failure({message:\"Invalid Code\"});\n        }\n        if (dayjs(new Date()).isAfter(dayjs(found.resetPasswordLink.expireTime))) {// link expire\n            return res.failure({message:\"Your reset password link is expired or invalid\"});\n        }\n        let result = await authService.resetPassword(found, params.newPassword);\n        if(result.flag){\n            return res.failure({message:result.data});\n        }\n        return res.success({message:result.data});\n        \n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\n/**\n * @description : login with username and password\n * @param {object} req : request for login \n * @param {object} res : response for login\n * @return {object} : response for login {status, message, data}\n */\nconst login = async(req,res)=>{\n    try {\n        let {username,password} = req.body;\n        if(!username || !password){\n            return res.badRequest();\n        }\n            <%_if(ROLE_PERMISSION){_%>\n            let roleAccess = false;\n            if (req.body.includeRoleAccess){\n                roleAccess = req.body.includeRoleAccess;\n            }\n            let result = await authService.loginUser(username, password,PLATFORM.<%-PLATFORM_NAME.toUpperCase()%>, roleAccess);\n            <%_} else {_%>\n            let result = await authService.loginUser(username,password,PLATFORM.<%-PLATFORM_NAME.toUpperCase()%>); \n            <%_}_%>\n            if(result.flag){\n                return res.badRequest({message:result.data});\n            }\n            return res.success({data:result.data,message:result.message});\n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\n/**\n * @description : logout user\n * @param {object} req : request for logout\n * @param {object} res : response for logout\n * @return {object} : response for logout {status, message, data}\n */\nconst logout = async (req, res) => {\n    try {\n        let userToken = await dbService.getDocumentByQuery(userTokens, { token: (req.headers.authorization).replace('Bearer ', '') ,userId:req.user.id});\n        let updatedDocument = {\n            isTokenExpired: true\n        }\n        await dbService.updateDocument(userTokens,userToken.id, updatedDocument);\n        return res.success({message:'Logged Out Successfully'});\n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\nmodule.exports = {\n    register,\n    forgotPassword,\n    validateResetPasswordOtp,\n    resetPassword,\n    login,\n    logout\n}\n    \n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/controllers/controller.js.ejs",
    "content": "const <%-DB_MODEL_FC%> = require(\"../../model/<%-DB_MODEL%>\")\nconst <%-DB_MODEL %>SchemaKey = require(\"../../utils/validation/<%-DB_MODEL%>Validation\");\nconst validation = require(\"../../utils/validateRequest\");\nconst dbService = require(\"../../utils/dbService\");\n<%_ if(IS_AUTH){ _%>\nconst auth = require(\"../../services/auth\");\n<%_ } _%>\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteDependentService = require(\"../../utils/deleteDependent\");\n<%_ } _%>\n<%_ var methods = [] _%>\n<%_\nif(typeof(UNIQ_TASK_MODELS)!== 'undefined'){\nlet models = UNIQ_TASK_MODELS\nfor(let model of models){\n    if(model!==DB_MODEL){\n    model = model.charAt(0).toUpperCase() + model.slice(1);\n_%>\nconst <%-model%> = require(\"../../model/<%-model%>\")\n<%_ } } } _%>\n<%_if(IS_CQ){_%>\nconst customQueryService = require(\"../../services/customQueryService\")\n<%_}_%>\n\n<%_for(let i=0;i< SUPPORT_API.length;i++){_%>\n<%_ if(SUPPORT_API[i].method==\"create\") {_%>\n    <%_methods.push('add'+DB_MODEL_FC) _%> \n/**\n* @description : create document of <%-DB_MODEL_FC%> in mongodb collection.\n* @param {object} req : request including body for creating document.\n* @param {object} res : response of created document\n* @return {object} : created <%-DB_MODEL_FC%>. {status, message, data}\n*/ \nconst add<%-DB_MODEL_FC%> = async(req, res) => {\n    try {\n        let dataToCreate = {...req.body || {}};\n        let validateRequest = validation.validateParamsWithJoi(dataToCreate,<%-DB_MODEL %>SchemaKey.schemaKeys);\n        if (!validateRequest.isValid) {\n            return res.validationError({message : `Invalid values in parameters, ${validateRequest.message}`});\n        }\n        <%_if(SUPPORT_API[i].isLogin){_%>\n        dataToCreate.<%-SUPPORT_API[i].addedBy%> = req.user.id\n        <%_}_%> \n        dataToCreate = new <%-DB_MODEL_FC%>(dataToCreate);\n        let result = await dbService.createDocument(<%-DB_MODEL_FC %>,dataToCreate);\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    } catch (error) {\n        if(error.name === \"ValidationError\"){\n            return res.validationError({message:error.message});\n        }\n        if(error.code && error.code == 11000){\n            return res.validationError({message:error.message});\n        }\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n    <%_methods.push('bulkInsert'+DB_MODEL_FC) _%>\n/**\n* @description : create multiple documents of <%-DB_MODEL_FC%> in mongodb collection.\n* @param {object} req : request including body for creating documents.\n* @param {object} res : response of created documents.\n* @return {object} : created <%-DB_MODEL_FC%>s. {status, message, data}\n*/\nconst bulkInsert<%-DB_MODEL_FC %> = async(req,res)=>{\n    try{\n        let dataToCreate = req.body && req.body.data ? [...req.body.data] : []; \n        <%_if(SUPPORT_API[i].isLogin){_%>\n        for(let i=0;i< dataToCreate.length;i++){\n            dataToCreate[i].<%-SUPPORT_API[i].addedBy%> = req.user.id\n        }\n        <%_}_%>\n        let result =await dbService.bulkInsert(<%-DB_MODEL_FC %>,dataToCreate);\n        return res.success({data:result});\n    }catch(error){\n        if(error.name === \"ValidationError\"){\n            return res.validationError({message:error.message});\n        }\n        if(error.code && error.code == 11000){\n            return res.validationError({message:error.message});\n        }\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"update\") {_%>\n    <%_methods.push('update'+DB_MODEL_FC) _%>\n/**\n* @description : update document of <%-DB_MODEL_FC%> with data by id.\n* @param {object} req : request including id in request params and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>.\n* @return {object} : updated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst update<%-DB_MODEL_FC%> = async(req,res) => {\n    try {\n        let dataToUpdate = {...req.body}\n        let validateRequest = validation.validateParamsWithJoi(\n            dataToUpdate,\n            <%-DB_MODEL%>SchemaKey.updateSchemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message :  `Invalid values in parameters, ${validateRequest.message}`});\n        }\n        <%_if(SUPPORT_API[i].isLogin){_%>\n        delete dataToUpdate.<%-SUPPORT_API[i].addedBy%>;\n        dataToUpdate.<%-SUPPORT_API[i].updatedBy%> = req.user.id\n        <%_}_%>\n        let query = {_id:req.params.id}\n        <%_         \n        let nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){\n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                    query = {...query,...<%=JSON.parse(element.filter)%>}  \n                <%_}}\n            }                \n        }\n        _%>\n        let result = await dbService.findOneAndUpdateDocument(<%-DB_MODEL_FC%>,query,dataToUpdate);\n        if(!result){\n            return res.recordNotFound();\n        }\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    }\n    catch(error){\n        if(error.name === \"ValidationError\"){\n            return res.validationError({message:error.message});\n        }\n        if(error.code && error.code == 11000){\n            return res.validationError({message:error.message});\n        }\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"bulkUpdate\") {_%>\n    <%_methods.push('bulkUpdate'+DB_MODEL_FC) _%>\n/**\n* @description : update multiple records of <%-DB_MODEL_FC%> with data by filter.\n* @param {object} req : request including filter and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>s.\n* @return {object} : updated <%-DB_MODEL_FC%>s. {status, message, data}\n*/\nconst bulkUpdate<%-DB_MODEL_FC%>=async(req,res)=>{\n    try {\n        let filter= req.body && req.body.filter ? {...req.body.filter} : {};\n        let dataToUpdate = req.body && req.body.data ? {...req.body.data} : {};\n        <%_if(SUPPORT_API[i].isLogin){_%>\n        dataToUpdate.<%-SUPPORT_API[i].updatedBy%>=req.user.id\n        <%_}_%>\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        filter = {...filter,...<%=JSON.parse(element.filter)%>}                 \n                    <%_}}\n                }                \n            }\n        _%>   \n        let result = await dbService.bulkUpdate(<%-DB_MODEL_FC%>,filter,dataToUpdate);\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n        \n    }\n    catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"partialUpdate\") {_%>\n    <%_methods.push('partialUpdate'+DB_MODEL_FC) _%>\n/**\n* @description : partially update document of <%-DB_MODEL_FC%> with data by id;\n* @param {object} req : request including id in request params and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>.\n* @return {object} : updated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst partialUpdate<%-DB_MODEL_FC%> = async(req,res) => {\n    try {\n        let dataToUpdate = {...req.body}\n        <%_if(SUPPORT_API[i].isLogin){_%>\n        delete dataToUpdate.<%-SUPPORT_API[i].addedBy%>;\n        dataToUpdate.<%-SUPPORT_API[i].updatedBy%> = req.user.id\n        <%_}_%>\n        let query = {_id:req.params.id}\n        <%_         \n        let nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){\n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length > 0){ \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                    query = {...query,...<%=JSON.parse(element.filter)%>}  \n                <%_}}\n            }                \n        }\n        _%>\n        let result = await dbService.findOneAndUpdateDocument(<%-DB_MODEL_FC%>,query,dataToUpdate);\n        if(!result){\n            return res.recordNotFound();\n        }\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message})\n    }\n}\n\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"findAll\") {_%>\n    <%_methods.push('findAll'+DB_MODEL_FC) _%>\n/**\n* @description : find all documents of <%-DB_MODEL_FC%> from collection based on query and options.\n* @param {object} req : request including option and query. {query, options : {page, limit, pagination, populate}, isCountOnly}\n* @param {object} res : response contains data found from collection.\n* @return {object} : found <%-DB_MODEL_FC%>(s). {status, message, data}\n*/\nconst findAll<%-DB_MODEL_FC%> = async(req,res) => {\n    try {\n        let query= req.body && req.body.query ? {...req.body.query} : {};\n        let options= req.body && req.body.options ? {...req.body.options} : {};\n        <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                       query = {...query,...<%=JSON.parse(element.filter)%>}              \n                    <%_}}\n                }                \n            }\n        _%>\n        if(req.body.isCountOnly){\n            let totalRecords = await dbService.countDocument(<%-DB_MODEL_FC%>, query);\n            return res.success({data: { totalRecords }});\n        }\n        else {\n            <%_if(typeof VIRTUAL !== \"undefined\"){\n                let populate = [];\n                for(let v of VIRTUAL){\n                    populate.push({\n                        path:v.fieldName\n                    })\n                }\n                _%>\n            if (!options.populate) options.populate = [];\n            options.populate = options.populate.concat(<%= populate %>);\n            <%_}_%>\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n                if(options.select && options.select.length){\n                    options.select = <%=SUPPORT_API[i].fields%>.filter(Set.prototype.has, new Set(options.select));\n                }else{\n                    options.select=<%=SUPPORT_API[i].fields%>\n                }\n            <%_}_%>\n            let result = await dbService.getAllDocuments( <%-DB_MODEL_FC%>,query,options);\n            if (result && result.data && result.data.length){\n                return res.success({data:result});   \n            }\n            return res.recordNotFound();\n        }\n    }\n    catch(error){\n        return res.internalServerError({message:error.message});\n    }\n}\n\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"findById\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC) _%>\n/**\n* @description : find document of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains document retrieved from table.\n* @return {object} : found <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst get<%-DB_MODEL_FC%> = async(req,res) => {\n    try {\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = { _id: req.params.id };\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        let select = <%=SUPPORT_API[i].fields%>\n        <%_}_%> \n        let result = await dbService.getDocumentByQuery(<%-DB_MODEL_FC%>,query<%_if(SUPPORT_API[i].fieldSelection){_%>,select<%_}_%>);\n        if(!result){\n        return res.recordNotFound();\n        }\n        <%_if(typeof VIRTUAL !== \"undefined\"){\n        let populate = [];\n        for(let v of VIRTUAL){\n            populate.push({\n                path:v.fieldName\n            })\n        }\n        _%>\n        result = await result.populate(<%-JSON.stringify(populate)%>).execPopulate();\n        <%_}_%>\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message})\n    }\n}\n\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"count\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC+'Count') _%>\n/**\n* @description : returns total number of documents of <%-DB_MODEL_FC%>.\n* @param {object} req : request including where object to apply filters in req body \n* @param {object} res : response that returns total number of documents.\n* @return {object} : number of documents. {status, message, data}\n*/\nconst get<%-DB_MODEL_FC%>Count = async(req,res) => {\n    try {\n        let where = req.body && req.body.where ? {...req.body.where  } : {};\n        <%_ \n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){\n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n            for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>   \n                where = {...where, ...<%=JSON.parse(element.filter)%>};                                     \n            <%_}}\n        }}\n        _%> \n        let totalRecords = await dbService.countDocument(<%-DB_MODEL_FC%>,where);\n        return res.success({data: { totalRecords } });\n    }\n    catch(error){\n        return res.internalServerError({message:error.message});\n    }\n}\n\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"delete\") {_%>\n    <%_methods.push('delete'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : delete document of <%-DB_MODEL_FC%> from table.\n* @param {object} req : request including id as req param.\n* @param {object} res : response contains deleted document.\n* @return {object} : deleted <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst delete<%-DB_MODEL_FC%> =async(req,res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = { _id : req.params.id};\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>};                \n                    <%_}}\n                }\n            }\n        _%>\n        let result;\n        if (req.body.isWarning) {\n            result = await deleteDependentService.count<%-DB_MODEL_FC%>(query);\n        } else {\n            result = await deleteDependentService.delete<%-DB_MODEL_FC%>(query);\n        }\n        return res.success({data:result});    \n    }\n    catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n<%_} else {_%>\n/**\n* @description : delete document of <%-DB_MODEL_FC%> from table.\n* @param {object} req : request including id as req param.\n* @param {object} res : response contains deleted document.\n* @return {object} : deleted <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst delete<%-DB_MODEL_FC%> =async(req,res) => {\n    try {\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = {_id:req.params.id}\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>};               \n                    <%_}}\n                }\n            }\n        _%>\n        const result = await dbService.findOneAndDeleteDocument(<%-DB_MODEL_FC%>, query);\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message});\n    }\n}\n\n<%_}_%>\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"deleteMany\") {_%>\n    <%_methods.push('deleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : delete documents of <%-DB_MODEL_FC%> in table by using ids.\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains no of documents deleted.\n* @return {object} : no of documents deleted. {status, message, data}\n*/\nconst deleteMany<%-DB_MODEL_FC%> =async(req, res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return res.badRequest();\n        } \n        let query = {_id:{$in:req.body.ids}};\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>};               \n                    <%_}}\n                }\n            }\n        _%>\n        let result;\n        if (req.body.isWarning) {\n            result = await deleteDependentService.count<%-DB_MODEL_FC%>(query);   \n        }\n        else{\n            result = await deleteDependentService.delete<%-DB_MODEL_FC%>(query);\n        }\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result}); \n    }\n    catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n<%_} else {_%>\n/**\n* @description : delete documents of <%-DB_MODEL_FC%> in table by using ids.\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains no of documents deleted.\n* @return {object} : no of documents deleted. {status, message, data}\n*/\nconst deleteMany<%-DB_MODEL_FC%> =async(req, res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return res.badRequest();\n        } \n        let query = {_id:{$in:req.body.ids}};\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>};               \n                    <%_}}\n                }\n            }\n        _%>\n        let result = await dbService.deleteMany(<%-DB_MODEL_FC%>,query);\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result}); \n    }\n    catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_}_%>\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"softDelete\") {_%>\n    <%_methods.push('softDelete'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : deactivate document of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains updated document of <%-DB_MODEL_FC%>.\n* @return {object} : deactivated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDelete<%-DB_MODEL_FC%> = async(req,res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = {_id:req.params.id}\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = {...query,...<%=JSON.parse(element.filter)%>};               \n                    <%_}}\n                }\n            }\n        _%>\n        let result = await deleteDependentService.softDelete<%-DB_MODEL_FC%>(query<%_if(SUPPORT_API[i].isLogin){_%>,req.user<%_}_%>);\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n<%_} else {_%>\n/**\n* @description : deactivate document of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains updated document of <%-DB_MODEL_FC%>.\n* @return {object} : deactivated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDelete<%-DB_MODEL_FC%> = async(req,res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = {_id:req.params.id}\n        <%_\n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){  \n        nestedCalls = SUPPORT_API[i].NESTED_CALLS\n        if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                    query = {...query,...<%=JSON.parse(element.filter)%>};                      \n                <%_}}\n            }\n        }\n        _%>\n        let result = await dbService.findOneAndUpdateDocument(<%-DB_MODEL_FC%>, query,{ isDeleted: true});\n        if(!result){\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_}_%>\n<%_}_%>\n<%_ if(SUPPORT_API[i].method==\"softDeleteMany\") {_%>\n    <%_methods.push('softDeleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : deactivate multiple documents of <%-DB_MODEL_FC%> from table by ids;\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains updated documents of <%-DB_MODEL_FC%>.\n* @return {object} : number of deactivated documents of <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDeleteMany<%-DB_MODEL_FC%> = async(req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return res.badRequest();\n        } \n        let query = {_id:{$in:req.body.ids}};\n        <%_\n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){  \n        nestedCalls = SUPPORT_API[i].NESTED_CALLS\n        if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                    query = {...query,...<%=JSON.parse(element.filter)%>};                      \n                <%_}}\n            }\n        }\n        _%>\n        let result = await deleteDependentService.softDelete<%-DB_MODEL_FC%>(query<%_if(SUPPORT_API[i].isLogin){_%>,req.user<%_}_%>);\n        if (!result) {\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n<%_} else {_%>\n/**\n* @description : deactivate multiple documents of <%-DB_MODEL_FC%> from table by ids;\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains updated documents of <%-DB_MODEL_FC%>.\n* @return {object} : number of deactivated documents of <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDeleteMany<%-DB_MODEL_FC%> = async(req,res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return res.badRequest();\n        } \n        let query = {_id:{$in:req.body.ids}};\n        <%_\n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){  \n        nestedCalls = SUPPORT_API[i].NESTED_CALLS\n        if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                    query = {...query,...<%=JSON.parse(element.filter)%>};                      \n                <%_}}\n            }\n        }\n        _%>\n        let result = await dbService.bulkUpdate(<%-DB_MODEL_FC%>,query, { isDeleted: true,<%_if(SUPPORT_API[i].isLogin){_%>updatedBy:req.user.id<%_}_%>});\n        if (!result) {\n            return res.recordNotFound();\n        }\n        return res.success({data:result});\n        \n    }catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n\n<%_}_%>\n<%_}_%>\n<%_}_%>\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){\n    methods.push('changePassword')\n    methods.push('updateProfile')\n    methods.push('getLoggedInUserInfo')%>\n    /**\n    * @description : change password\n    * @param {object} req : request including user credentials.\n    * @param {object} res : response contains updated user document.\n    * @return {object} : updated user document {status, message, data}\n    */\n    const changePassword = async(req, res) => {\n        try {\n            let params = req.body;\n            if (!params.newPassword || !params.oldPassword) {\n                return res.validationError({message:'Please Provide new Password and Old password'});\n            }\n            let result = await auth.changePassword({...params,userId:req.user.id});\n            if(result.flag){\n                return res.failure({message:result.data});\n            }\n            return res.success({message:result.data});\n        } catch (error) {\n            return res.internalServerError({message:error.message});\n        }\n    }\n\n/**\n* @description : update user profile.\n* @param {object} req : request including user profile details to update in request body.\n* @param {object} res : updated user document.\n* @return {object} : updated user document. {status, message, data}\n*/\nconst updateProfile = async(req, res) => {\n    try {\n        let profileData = {...req.body};\n        let validateRequest = validation.validateParamsWithJoi(\n            profileData,\n            <%-DB_MODEL %>SchemaKey.updateSchemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message :  `Invalid values in parameters, ${validateRequest.message}`});\n        }\n        delete profileData.password;\n        delete profileData.createdAt;\n        delete profileData.updatedAt;\n        delete profileData.id;\n        let result = await dbService.findOneAndUpdateDocument(<%-DB_MODEL_FC%>,{ _id:req.user.id },profileData);\n        if (!result){\n            return res.recordNotFound();\n        }            \n        return res.success({data:result});\n    }\n    catch (error){\n        if (error.name === 'ValidationError'){\n            return res.validationError({message:error.message});\n        }\n        if (error.code && error.code == 11000){\n            return res.validationError({message:error.message});\n        }\n        return res.internalServerError({message:error.message});\n    }\n};\n\n/**\n * @description : get information of logged-in User.\n * @param {Object} req : authentication token is required\n * @param {Object} res : Logged-in user information\n * @return {Object} : Logged-in user information {status, message, data}\n */\nconst getLoggedInUserInfo = async (req, res) => {\n  try{\n    const query = { _id: req.user.id, isDeleted: false, isActive:true }\n    let foundUser = await dbService.getSingleDocument(<%-DB_MODEL_FC%>, query);\n    if (!foundUser) {\n      return res.recordNotFound();\n    }\n    return res.success({ data: foundUser });\n  }catch(error){\n    return res.internalServerError({message:error.message})\n  }\n};\n\n\n<%_}_%>\n\n<%_if(CUSTOM_ROUTES){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=>{\n    methods.push(v.functionName)\n_%>\n/**\n* @description : <%-v.functionName%> \n* @param {object} req : request\n* @param {object} res : response \n* @return {object} : response of <%-v.functionName%> {status, message, data}\n*/\nconst <%-v.functionName%>=async(req,res)=>{\n    try {\n        <%_if(typeof(v.queryBuilder) !== \"undefined\" && v.queryBuilder.length > 0){_%>\n        let combinedOutput={};\n        <%_ for(let i=0;i< v.queryBuilder.length;i++){_%>\n        <%_ if(v.queryBuilder[i].queryMode === \"find\"){ _%>\n            <%_ if(v.queryBuilder[i].filter){ \n                v.queryBuilder[i].model = v.queryBuilder[i].model.charAt(0).toUpperCase() + v.queryBuilder[i].model.slice(1);_%>\n            combinedOutput.<%-v.queryBuilder[i].outputVariable%> =  await customQueryService.find(<%-v.queryBuilder[i].model%>,{filter:<%-JSON.stringify(JSON.parse(v.queryBuilder[i].filter))%>});\n            <%_}_%>\n        <%_}_%>   \n        <%_}_%>\n        return res.success({data:combinedOutput});\n        <%_}_%>\n    } catch (error) {\n    return res.internalServerError({message:error.message});\n    }  \n}\n<%_ })_%>\n<%_}_%>\n\n\nmodule.exports = {\n    <%-methods.join()%>\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/controllers/fileUploadController.js.ejs",
    "content": "/**\n  * fileUploadController.js\n  * @description :: exports methods related file upload\n  */\n\n<%_if(S3_UPLOAD){_%>\nconst fs = require('fs');\nconst path = require('path');\nconst formidable = require('formidable');\nconst AWS = require('aws-sdk');\n<%_if(S3_UPLOAD_PRIVATE){_%>\nconst AmazonS3URI = require('amazon-s3-uri');\n<%_}_%>\n\nlet allowedFileTypes = <%=VALIDATION_TYPES%>;<%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\nlet maxFileSize = <%=max_size%>; //In Megabyte\n\n/**\n  * @description : uploads file using formidable.\n  * @param {object} req : request of file upload API\n  * @param {object} res : response of file upload API.\n  * @return {object} : response of file upload. {status, message, data}\n  */\nconst upload = async (req,res) => {\n  try {\n\n    // Setting up formidable options.\n    const form = new formidable.IncomingForm();\n    form.multiples = true;\n    form.maxFileSize = 300 * 1024 * 1024; //300 MB\n    form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n    const uploadFileRes = await new Promise(async (resolve, reject) => {\n      form.parse(req, async function (err, fields, files) {\n        \n        if (err) {\n          reject(err);\n        }\n\n        let uploadSuccess = [];\n        let uploadFailed = [];\n        let fileCount = 1;\n\n        let fileArr = [];\n        if (!files['file[]']) {\n          reject({\n            'message': 'Select at least one file to upload.',\n            'name': 'validationError'\n          });\n        }\n        if (!Array.isArray(files['file[]'])) {\n          fileArr.push(files['file[]']);\n          files['file[]'] = fileArr;\n        }\n\n        for (let file of files['file[]']) {\n          let response = await uploadFiles(file,fields,fileCount++);\n          if (response.status == false) {\n            uploadFailed.push({\n              'name': file.name,\n              'error': response.message,\n              'status': false\n            });\n          } else {\n            uploadSuccess.push({\n              'name': file.name,\n              'path': response.data,\n              'status': true\n            });\n          }\n        }\n\n        resolve({\n          uploadSuccess,\n          uploadFailed\n        });\n      });\n    });\n    \n    if (uploadFileRes.uploadSuccess.length > 0) {\n      let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n      return res.success({\n        message: message,\n        data: uploadFileRes\n      });\n    } else {\n      let message = 'Failed to upload files.';\n      return res.failure({\n        message: message,\n        data: uploadFileRes\n      });\n    }\n  } catch (error){\n    if (error.name && error.name == 'validationError') {\n      return res.validationError({ message: error.message });\n    } else {\n      return res.internalServerError();\n    }\n  }\n};\n\n<%_if(S3_UPLOAD_PRIVATE){_%>\n/**\n  * @description : generate pre signed url for file\n  * @param {string} uri : url of file\n  * @return {object} : response for generate pre signed url\n  */\nconst generatePreSignedURL = async (req, res) => {\n    try {\n        if (req.body && req.body.uri){\n          let uri = req.body.uri;\n            let S3Config = {\n                AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n                AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n                AWS_S3_REGION: process.env.AWS_S3_REGION,\n                AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n            };\n\n            const s3 = new AWS.S3({\n                region: S3Config.AWS_S3_REGION,\n                accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n                secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n            });\n\n            try {\n              const {\n                region, bucket, key\n              } = AmazonS3URI(uri);\n\n              let options = {\n                Bucket: bucket,\n                Key: key,\n                Expires: Number(process.env.AWS_URL_EXPIRATION) || 15 * 60 //in seconds,\n              };\n\n              await s3.getSignedUrl('getObject', options, (err, url) => {\n                if (err) {\n                    return res.failure({message: err});\n                } else {\n                    return res.success({data: url });\n                }\n              });\n            } catch (err) {\n              return res.failure({ message: `${uri} is not a valid S3 uri` });\n            }\n        }else {\n            return res.badRequest();\n        }\n    } catch (error) {\n        return res.internalServerError();\n    }\n}\n\n<%_}_%>\n/**\n  * @description : upload files\n  * @param {object} file : file to upload\n  * @param {object} fields : fields for file\n  * @param {number} fileCount : total number of files to upload\n  * @return {object} : response for file upload\n  */\nconst uploadFiles = async (file,fields,fileCount) => {\n\n  let extension = path.extname(file.name);\n  extension = extension.split('.').pop();\n\n  fileType = file.type;\n\n  if (allowedFileTypes.length) {\n    //Check allowed extension;\n    if (!allowedFileTypes.includes(extension)) {\n      return {\n        status: false,\n        message: 'Filetype not allowed.'\n      };\n    }\n  }\n\n  // Check File Size\n  const fileSize = ((file.size / 1024) / 1024);\n  if (maxFileSize < fileSize) {\n    return {\n      status: false,\n      message: `Allow file size upto ${maxFileSize} MB.`\n    };\n  }\n\n  let fileName = file.name;\n  //Create Requested Directory,if given in request parameter.\n  if (fields && fields.folderName) {\n    fileName = fields.folderName + '/' + fileName;\n  }\n  else if (fields && fields.fileName) {\n    fileName = fields.fileName + '-' + fileCount + path.extname(file.name);\n  }\n\n  const response = await new Promise(async (resolve, reject) => {\n    resolve(await uploadToS3(file,fileName));\n  });\n\n  return response;\n\n}\n\n/**\n  * @description : upload file to AWS s3\n  * @param {object} file : file to upload\n  * @param {string} fileName : name of file\n  * @return {object} : response for file upload to AWS s3\n  */\nconst uploadToS3 = async (file, fileName) => {\n  let S3Config = {\n    AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n    AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n    AWS_S3_REGION: process.env.AWS_S3_REGION,\n    AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n  };\n\n  const s3 = new AWS.S3({\n    region: S3Config.AWS_S3_REGION,\n    accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n    secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n  });\n\n  let params = {\n    Bucket: S3Config.AWS_S3_BUCKET_NAME,\n    Body: fs.createReadStream(file.path),\n    Key: fileName,\n  };\n\n  const response = await new Promise(async (resolve, reject) => {\n    s3.putObject(params, function (err, data) {\n      if (err) {\n        resolve({\n          status: false,\n          message: err.message\n        });\n      } else {\n        resolve({\n          status: true,\n          data: 'https://' + process.env.AWS_S3_BUCKET_NAME + '.s3.' + S3Config.AWS_S3_REGION + '.amazonaws.com/' + fileName\n        });\n      }\n    });\n  });\n\n  return response;\n}\nmodule.exports = { upload<%_if(S3_UPLOAD_PRIVATE){_%>,generatePreSignedURL<%_}_%> };\n\n<%_} else { _%>\nconst fs = require('fs');\nconst path = require('path');\nconst formidable = require('formidable');\nconst validUrl = require('valid-url');\n\nlet defaultDirectory = 'public/assets';\nlet allowedFileTypes = <%=VALIDATION_TYPES%>;<%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\nlet maxFileSize = <%=max_size%>; //In Megabyte\n\n/**\n  * @description : uploads file using formidable.\n  * @param {object} req : request of file upload API\n  * @param {object} res : response of file upload API.\n  * @return {object} : response of file upload. {status, message, data}\n  */\nconst upload = async (req, res) => {\n  try {\n    // Create Directory if not exist.\n    await makeDirectory(defaultDirectory);\n\n    // Setting up formidable options.\n    const form = new formidable.IncomingForm();\n    form.multiples = true;\n    form.maxFileSize = 300 * 1024 * 1024; //300 MB\n    form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n    //Upload File one by one\n    const uploadFileRes = await new Promise(async (resolve, reject) => {\n\n      form.parse(req, async function (err, fields, files) {\n\n        if (err) {\n          reject(err);\n        }\n\n        let uploadSuccess = [];\n        let uploadFailed = [];\n        let fileCount = 1;\n\n        let fileArr = [];\n        if (!files['file[]']) {\n          reject({\n            'message': 'Select at least one file to upload.',\n            'name': 'validationError'\n          });\n        }\n        if (!Array.isArray(files['file[]'])) {\n          fileArr.push(files['file[]']);\n          files['file[]'] = fileArr;\n        }\n\n        for (let file of files['file[]']) {\n\n          let response = await uploadFiles(file, fields, fileCount++);\n\n          if (response.status == false) {\n            uploadFailed.push({\n              'name': file.name,\n              'error': response.message,\n              'status': false\n            });\n          } else {\n            let url = response.data;\n            if (!validUrl.isUri(response.data)) {\n              response.data = response.data.replace('/public', '');\n              url = `${response.data}`;\n            }\n            uploadSuccess.push({\n              'name': file.name,\n              'path': url,\n              'status': true\n            });\n          }\n        }\n        resolve({\n          uploadSuccess,\n          uploadFailed\n        });\n      });\n    });\n    \n    if (uploadFileRes.uploadSuccess.length > 0) {\n      let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n      return res.success({\n        message: message,\n        data: uploadFileRes\n      });\n    } else {\n      let message = 'Failed to upload files.';\n      return res.failure({\n        message: message,\n        data: uploadFileRes\n      });\n    }\n  } catch (error) {\n    if (error.name && error.name == 'validationError') {\n      return res.validationError({ message: error.message });\n    } else {\n      return res.internalServerError();\n    }\n  }\n}\n\n/**\n * @description : create directory to specified path\n * @param {string} directoryPath : location where directory will be created\n * @return {boolean} : returns true if directory is created or false\n */\nconst makeDirectory = async (directoryPath) => {\n\n  if (!fs.existsSync(directoryPath)) {\n    fs.promises.mkdir(directoryPath, { recursive: true }, (err) => {\n      if (err) {\n        return false;\n      };\n      return true;\n    });\n  }\n  return true;\n}\n\n/**\n * @description : upload files\n * @param {object} file : file to upload\n * @param {object} fields : fields for file\n * @param {number} fileCount : total number of files to upload\n * @return {object} : response for file upload\n */\nconst uploadFiles = async  (file, fields, fileCount) => {\n\n  let tempPath = file.path;\n  let unlink;\n  let fileName = file.name;\n\n  let extension = path.extname(file.name);\n  extension = extension.split('.').pop();\n\n  fileType = file.type;\n\n  if (allowedFileTypes.length) {\n    //Check allowed extension;\n    if (!allowedFileTypes.includes(extension)) {\n      return {\n        status: false,\n        message: 'Filetype not allowed.'\n      };\n    }\n  }\n\n  // Check File Size\n  const fileSize = ((file.size / 1024) / 1024);\n  if (maxFileSize < fileSize) {\n    return {\n      status: false,\n      message: `Allow file size upto ${maxFileSize} MB.`\n    };\n  }\n\n  //Create New path\n  let newPath = defaultDirectory + '/' + new Date().getTime() + path.extname(file.name);\n\n  //Create Requested Directory,if given in request parameter.\n  if (fields && fields.folderName) {\n    let newDir = defaultDirectory + '/' + fields.folderName;\n    const createDir = await makeDirectory(newDir);\n    if (createDir) {\n      if (fields.fileName) {\n        newPath = newDir + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n        fileName = fields.fileName;\n      }\n    }\n  }\n  else if (fields && fields.fileName) {\n    newPath = defaultDirectory + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n    fileName = fields.fileName;\n  }\n  \n  const response = await new Promise(async (resolve, reject) => {\n    fs.readFile(tempPath, function (err, data) {\n      fs.writeFile(newPath, data, async function (err) {\n  \n        //Remove file from temp\n        unlink = await unlinkFile(tempPath);\n  \n        if (unlink.status == false) {\n          reject(unlink);\n        } else {\n          resolve({\n            status: true,\n            message: 'File upload successfully.',\n            data: '/' + newPath\n          });\n        }\n      });\n    });\n  });\n\n  return response;\n}\n\n/**\n  * @description : unlink(delete) file from specified path\n  * @param {string} path : location of file \n  * @return {object} : return unlink file status {status, message}\n  */\nconst unlinkFile = async (path) => {\n\n  fs.unlink(path, function (err) {\n    if (err) {\n      return {\n        status: false,\n        message: err.message\n      };\n    }\n  });\n\n  return { status: true };\n}\n\nmodule.exports = { upload };\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/customEnv.ejs",
    "content": "<%_for(const [key,value] of Object.entries(CUSTOM_ENV)) {_%>\n<%-key%>=<%-value%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/controller.js.ejs",
    "content": "/**\n * @description :: exports API action methods\n */\n\n<%_\nif(typeof(MODEL_PATHS) !== 'undefined' ){\nlet models = MODEL_PATHS\nObject.keys(models).forEach(function(key) { _%>\nconst <%-key%> = require(\"<%-models[key]%>\")\n<%_ }); } _%>\n<%_ if(typeof(UNIQ_TASK_MODELS)!== 'undefined'){\nlet models = UNIQ_TASK_MODELS\nfor(const model of models){ _%>\nconst <%-model%> = require(\"../../model/<%-model%>\");\n<%_} } _%>    \n\n<%_if(IS_CQ){_%>\nconst customQueryService = require(\"../../services/customQueryService\")\n<%_}_%>\n\n<%_ROUTES.forEach((v,i)=>{_%>\n/** \n  * @description : <%-v.descriptions%>\n  * @param {object} req : request for <%-v.functionName%>\n  * @param {object} res : response for <%-v.functionName%>\n  * @return {object} : response for <%-v.functionName%>\n  */\nconst <%-v.functionName%>=async (req,res)=>{\ntry {\n    <%_if(typeof(v.queryBuilder) !== \"undefined\" && v.queryBuilder.length > 0){_%>\n    let combinedOutput={};\n    <%_ for(let i=0;i< v.queryBuilder.length;i++){_%>\n    <%_ if(v.queryBuilder[i].queryMode === \"find\"){ _%>\n        <%_ if(v.queryBuilder[i].filter){ _%>\n        combinedOutput.<%-v.queryBuilder[i].outputVariable%> =  await customQueryService.find(<%-v.queryBuilder[i].model%>,{filter:<%-JSON.stringify(JSON.parse(v.queryBuilder[i].filter))%>});\n        <%_}_%>\n    <%_}_%>   \n    <%_}_%>\n    return res.success({data:combinedOutput});\n    <%_}_%>\n} catch (error) {\n  return res.internalServerError();\n}\n}    \n<%_})_%>\n\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/existIndexRoute.js.ejs",
    "content": "<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v%>/index\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/indexRoutes.js.ejs",
    "content": "<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.platform.toLowerCase()%>Route\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/platformIndexRoutes.js.ejs",
    "content": "/**\n * index.js\n * @description :: API routes\n */\n\nconst express = require(\"express\")\nconst router =  express.Router()\n\n<%_ CONTROLLERS.forEach((controller)=>{ _%>\nrouter.use(\"/\",require(\"./<%-controller.toLowerCase()%>Routes\"));\n<%_ }) _%>\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/route.js.ejs",
    "content": "const express = require(\"express\");\nconst router = express.Router();\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_if(typeof(SERVICE_NAME) !== 'undefined' && typeof(PLATFORM) !== 'undefined'){ _%>\nconst <%- SERVICE_NAME%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-SERVICE_NAME%>Controller\");    \n<%_}_%>\n<%_\nif(typeof(CONTROLLER_IMPORTS) !== 'undefined' ){\nObject.keys(CONTROLLER_IMPORTS).forEach(function(key) { _%>\nconst <%-key%> = require(\"<%-CONTROLLER_IMPORTS[key]%>\")\n<%_ }); } _%>\n<%_\nif(POLICIES && POLICIES.length){\n POLICIES.forEach((policy)=>{_%>\nconst <%-policy%> = require(\"../../middleware/<%-policy%>\")\n<%_}) } _%>\n<%_ ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n<%_}else{_%>\n<%-policy%>,<%_}_%>\n<%_})_%>\n<%_}_%><%_if(typeof(v.controllerFileName)!=='undefined'){_%><%-v.controllerFileName%><%_}else{_%><%-v.controller%>Controller<%_}_%>.<%-v.functionName%>)\n<%_})_%>\n    \nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/individualRoutes/service.js.ejs",
    "content": "<%_ROUTES.forEach((v,i)=>{_%>\n/* \n* <%-v.descriptions%>\n*/\nconst <%-v.functionName%>=()=>{\n    try {\n        return true;\n    } catch (error) {\n        throw error;\n    }\n}    \n<%_ })_%>\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/middleware/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: middleware that checks authentication and authorization of user\n */\n\nconst passport = require('passport');\nconst { LOGIN_ACCESS,PLATFORM } = require('../constants/authConstant');\nconst userTokens = require('../model/userTokens');\nconst dbService = require(\"../utils/dbService\");\n\n/**\n * @description : returns callback that verifies platform access of user\n * @param {object} req : request of route.\n * @param {callback} resolve : resolve callback for succeeding method.\n * @param {callback} reject : reject callback for error.\n * @param {integer} platform : platform from constants which user wants to login.\n */\nconst verifyCallback = (req, resolve, reject, platform) => async (err, user, info) => {\n    if (err || info || !user) {\n        return reject(\"Unauthorized User\");\n    }\n    req.user = user;\n    if (!user.isActive) {\n        return reject(\"User is deactivated\");\n    }\n    let userToken = await dbService.getDocumentByQuery(userTokens,{token:(req.headers.authorization).replace('Bearer ',''),userId:user.id});\n    if (!userToken){\n        return reject('Token not found');\n    }\n    if (userToken.isTokenExpired){\n        return reject('Token is Expired');\n    }\n    if (user.role) {\n        let allowedPlatforms = LOGIN_ACCESS[user.role] ? LOGIN_ACCESS[user.role] : [];\n        if (!allowedPlatforms.includes(platform)) {\n            return reject('Unauthorized user');\n        }\n    }\n    resolve();\n};\n\n/**\n * @description : authentication middleware for request.\n * @param {object} req : request of route.\n * @param {object} res : response of route.\n * @param {callback} next : executes the next middleware succeeding the current middleware.\n * @param {integer} platform : platform from constants which user wants to login.\n */\nconst auth = (platform) => async (req, res, next) => {\n<% var c = 0; %>\n<%_ PLATFORM.forEach((v)=>{ c++; _%>\n    <%_ if(c===1){ _%>\n    if(platform == PLATFORM.<%- v.toUpperCase() %>){\n        return new Promise((resolve, reject) => {\n            passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(req, resolve, reject, platform))(\n                req,\n                res,\n                next\n            );\n        })\n        .then(() => next())\n        .catch((err) => {\n            return res.unAuthorized();\n        });\n    }\n    <%_ }else{ _%>\n    else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n        return new Promise((resolve, reject) => {\n            passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(req, resolve, reject, platform))(\n                req,\n                res,\n                next\n            );\n        })\n        .then(() => next())\n        .catch((err) => {\n            return res.unAuthorized();\n        });\n    }\n    <%_ } _%> \n<%_ }) _%>\n};\n\nmodule.exports = auth;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/middleware/checkRolePermission.js.ejs",
    "content": "/**\n * checkRolePermission.js\n * @description :: middleware that checks access of APIs of logged-in user\n */\n\nconst mongoose = require('mongoose');\nconst UserRole = require('../model/userRole');\nconst RouteRole = require('../model/routeRole');\nconst ProjectRoute = require('../model/projectRoute');\nconst { replaceAll } = require('../utils/common');\n\nconst checkRolePermission = async (req, res, next) => {\n  if (!req.user) {\n    return res.unAuthorized({message:'Authorization token required!'});\n  }\n    const loggedInUserId = req.user.id;\n    let rolesOfUser = await UserRole.find({\n      userId: loggedInUserId,\n      isActive: true,\n      isDeleted: false,\n    }, {\n      roleId: 1,\n      _id: 0,\n    });\n    if (rolesOfUser && rolesOfUser.length) {\n      rolesOfUser = rolesOfUser.map((role) => mongoose.Types.ObjectId(role.roleId));\n      const route = await ProjectRoute.findOne({\n        route_name: replaceAll((req.route.path.toLowerCase()).substring(1), '/', '_'),\n        uri: req.route.path.toLowerCase(),\n      });\n      if (route) {\n        const allowedRoute = await RouteRole.find({\n          routeId: route._id,\n          roleId: { $in: rolesOfUser },\n          isActive: true,\n          isDeleted: false,\n        });\n        if (allowedRoute && allowedRoute.length) {\n          next();\n        } else {\n          return res.unAuthorized({message:'You are not having permission to access this route!'});\n        }\n      } else {\n        next();\n      }\n    } else {\n      next();\n    }\n  return undefined;\n};\n\nmodule.exports = checkRolePermission;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/middleware/loginUser.js.ejs",
    "content": "/**\n * loginUser.js\n * @description :: middleware that verifies JWT token\n */\n\nconst jwt = require(\"jsonwebtoken\");\n<%_ PLATFORM.forEach((v)=>{ _%>\nconst <%-v.toLowerCase()%>Secret = require(\"../constants/authConstant\").JWT.<%-v.toUpperCase()%>_SECRET;\n<%_ }) _%>\nconst { PLATFORM } = require('../constants/authConstant'); \n\nconst authenticateJWT = (platform) => async (req, res, next) => {\n    const authHeader = req.headers.authorization;\n    if (authHeader) {\n        const token = authHeader.split(' ')[1];\n        let secret = '';\n        <%_ var c = 0; PLATFORM.forEach((v)=>{ c++;  _%>\n            <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                secret = <%-v.toLowerCase()%>Secret;\n            }\n            <%_ }else{ _%>\n            else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n                secret = <%-v.toLowerCase()%>Secret;\n            }\n            <%_ } _%> \n        <%_  }) _%>\n        jwt.verify(token,secret, (err, user) => {\n            if (err) {\n                return res.unAuthorized();\n            }\n            req.user = user;\n            next();\n        });\n    } else {\n        return res.unAuthorized();\n    }\n};\nmodule.exports = authenticateJWT"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/middleware/sampleMiddleware.js.ejs",
    "content": "/**\n <%-POLICY.functionName%>.js\n */\n\n<%_if(POLICY.code){_%>\n<%-POLICY.code%>\n<%_}else{_%>\nconst <%-POLICY.functionName%>=(req,res,next)=>{\n    try {\n        next();        \n    } catch (error) {\n        throw error;\n    }\n}\n\nmodule.exports=<%-POLICY.functionName%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/models/model.js.ejs",
    "content": "/**\n  * <%-DB_MODEL %>.js\n  * @description :: model of a database collection <%-DB_MODEL %>\n  */\n\n<%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n<%_if(typeof FLAG !== \"undefined\"){_%>    \nconst dayjs = require('dayjs');\n<%_}_%>\n<%_}_%>\nconst mongoose = require(\"mongoose\");\n<%_ if(ATTRS_WITH_SEQ){ _%>\nconst autoIncrement = require('mongoose-sequence')(mongoose);\n<%_ } _%>\nconst mongoosePaginate = require('mongoose-paginate-v2');\nvar idValidator = require('mongoose-id-validator');\n<%_ if(DB_UNIQUE) { _%>\nconst uniqueValidator = require('mongoose-unique-validator');\n<%_ } _%>\n<%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH !== \"undefined\") && (USER && IS_AUTH)){ _%>\nconst bcrypt = require(\"bcrypt\");\nconst{USER_ROLE} = require(\"../constants/authConstant\");\nconst {convertObjectToEnum} = require(\"../utils/common\")\n<%_ } _%>\n<%_if(MODEL_ENUM){_%>\n<%_let a=[]_%>    \n<%_for(let i in MODEL_ENUM){_%>\n<%_for(let j in MODEL_ENUM[i]){_%>    \n<%_if(typeof (MODEL_ENUM[i][j])==='object'){_%>\n<%_if(!a.includes(MODEL_ENUM[i][j].enumFile)){_%>\n<%_a.push(MODEL_ENUM[i][j].enumFile)_%>\nconst <%-MODEL_ENUM[i][j].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i][j].enumFile%>\")\n<%_}_%>    \n<%_}else{_%>\n<%_if(!a.includes(MODEL_ENUM[i].enumFile)){_%>\n<%_a.push(MODEL_ENUM[i].enumFile)_%>\nconst <%-MODEL_ENUM[i].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i].enumFile%>\")\n<%_}_%>        \n        \n<%_}_%>        \n<%_}_%>   \n<%_}_%>\n<%_}_%>\n<%_ if(typeof VARIABLES !== \"undefined\") {\nfor(let i=0;i< VARIABLES.length; i++) {_%>\n<%-VARIABLES[i]%>\n<%_ } } _%>\nconst myCustomLabels = {\n    totalDocs: 'itemCount',\n    docs: 'data',\n    limit: 'perPage',\n    page: 'currentPage',\n    nextPage: 'next',\n    prevPage: 'prev',\n    totalPages: 'pageCount',\n    pagingCounter: 'slNo',\n    meta: 'paginator',\n};\nmongoosePaginate.paginate.options = {\n    customLabels: myCustomLabels\n};\nconst Schema = mongoose.Schema;\nconst schema = new Schema(\n<%_ var model = DB_SCHEMA _%>\n<%_ var modelArr = Object.keys(model)_%>\n{\n<%_ for(let v in model){ _%>\n<%_if(COMMENT && COMMENT.attributeComment && COMMENT.attributeComment[v]){_%>\n// <%-COMMENT.attributeComment[v].comment%>\n<%_}else{_%>\n\n<%_}_%>\n<%_ let jsonStr = JSON.stringify(model[v]);\n        var finalStr = new String();\n        finalStr = jsonStr.toString().replace(/\"/g, \"\");\n        finalStr = finalStr.replace(/@@/g, '\"');\n        finalStr = finalStr.replace(/##/g, \"\").replace(/^\"(.*)\"$/, '$1');\n    _%>\n<%_ if(modelArr[modelArr.length-1]!==v){ _%>\n    <%-v%>:<%-finalStr%>,\n<%_}else{_%>\n    <%-v%>:<%-finalStr%>\n<%_ } _%>\n<%_ } _%>\n    },\n    { timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } }\n);\n<%_ \nif(ATTRS_WITH_SEQ){\n    for(const [attributeName, value] of Object.entries(ATTRS_WITH_SEQ) ){\n        if(value.isAutoIncrement){ _%>\nschema.plugin(autoIncrement, {\n    inc_field: \"<%-attributeName%>\",\n    id:\"<%-DB_MODEL%>_<%-attributeName%>_sequence\",\n    inc_amount: 1, \n    start_seq: 1,\n    prefix: \"\",\n    suffix: \"\",\n    length: 6\n    });\n<%_     }\n    } \n}\n_%>\n<%_if(INDEXES && INDEXES.length){_%>\n<%_for(const index of INDEXES){ _%>\n<%_if(index.indexFields && JSON.stringify(index.indexFields)!=='{}'){ _%>\nschema.index(<%-JSON.stringify(index.indexFields)%><%_if(index.options && JSON.stringify(index.options)!=='{}'){_%>,<%-JSON.stringify(index.options)%><%_}_%>)\n<%_} }_%>\n<%_}_%>\n<%_if(VIRTUAL_RELATION && VIRTUAL_RELATION.length>0){_%>\n    <%_for(const VIRTUAL_REL of VIRTUAL_RELATION){ _%>\n    schema.virtual(<%= VIRTUAL_REL.fieldName %>, {\n        ref: <%= VIRTUAL_REL.ref %>,\n        localField: <%= VIRTUAL_REL.localField %>,\n        foreignField: <%= VIRTUAL_REL.foreignField %>,\n        justOne: <%= VIRTUAL_REL.justOne %>\n    });\n<%_}\n}\n_%> \n<%_if(HOOKS!=='null' && HOOKS){_%>\n<%_if(HOOKS['pre']!==undefined){_%>   \n<%HOOKS['pre'].forEach(function (variable) { -%>\n<%_if(variable['operation']!=='init'){_%>\nschema.pre('<%-variable['operation']%>',async function(next){\n    <%-variable['code']%>\n    next();\n});\n<%_}else{_%>\nschema.pre('init',async function(docs,next){\n    <%-variable['code']%>\n});\n<%_}_%>        \n<% }); -%>\n    \n<%_}if(HOOKS['post']!==undefined){_%>   \n<%HOOKS['post'].forEach(function (variable) { -%>\n<%_if(variable['operation']!=='init'){_%>\nschema.post('<%-variable['operation']%>',async function(docs,next){\n    <%-variable['code']%>\n    next();\n});\n<%_}else{_%>\nschema.post('init',async function(docs,next){\n    <%-variable['code']%>\n});\n<%_}_%>\n<% }); -%>    \n<%_}_%>\n<%_}_%>\nschema.pre('save', async function(next) {\n    this.isDeleted = false;\n    this.isActive = true;\n    <%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH!==\"undefined\") && (USER && IS_AUTH)){ _%>\n    if(this.<%-PASSWORD%>){\n        this.<%-PASSWORD%> = await bcrypt.hash(this.<%-PASSWORD%>, 8);\n    }\n    <%_ } _%>\n    next();\n});\n\nschema.pre('insertMany', async function (next, docs) {\n    if (docs && docs.length){\n        for (let index = 0; index < docs.length; index++) {\n        const element = docs[index];\n        element.isDeleted = false;\n        element.isActive = true;\n        }\n    }\n    next();\n});\n\n<%_ if((typeof USER !== \"undefined\" && typeof IS_AUTH!==\"undefined\") && (USER && IS_AUTH)){ %>\nschema.methods.isPasswordMatch = async function (password) {\n    const user = this;\n    return bcrypt.compare(password, user.<%-PASSWORD%>);\n};\n<%_ } _%>\nschema.method(\"toJSON\", function () {\n    const { _id, __v, ...object } = this.toObject({virtuals:true});\n    object.id = _id;\n    <%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n    <%_for(index of CONCAT_HOOK){_%>\n    <%_for(formateIndex in index){_%>\n    <%_if(typeof (index[formateIndex])==='object'){_%>\n    if(object.<%-formateIndex%>){\n        object.<%-formateIndex%>=<%=index[formateIndex].true%>;\n    }else{\n        object.<%-formateIndex%>=<%=index[formateIndex].false%>;\n    }\n    <%_}else{_%> \n    <%_if(index[formateIndex].includes('concat')){_%>\n    if(object.<%-STRING_ATT[0]%> && object.<%-STRING_ATT[1]%>){\n        object.<%-formateIndex%>=<%-index[formateIndex]%>;\n    }\n    <%STRING_ATT.shift()%>\n    <%STRING_ATT.shift()%>\n    <%_}else{_%>        \n    object.<%-formateIndex%>=<%-index[formateIndex]%>;\n    <%_}_%>\n    <%_}_%>\n    <%_}_%>   \n    <%_}_%>   \n    <%_}_%> \n    <%_if(IS_PRIVATE_ATTR !== null && IS_PRIVATE_ATTR === true) {_%>\n        <%_if(PRIVATE_ATTRS !== null && PRIVATE_ATTRS) {_%>\n            <%_Object.keys(PRIVATE_ATTRS).map((t) => {_%>            \n                <%_if(PRIVATE_ATTRS[t]) {_%>            \n                    delete object.<%-t%>\n                <%_}_%>        \n            <%_});_%>        \n        <%_}_%>    \n    <%_}_%>\n    <%_if(IS_PRIVATE_ARRAY_PROPERTY !== null && IS_PRIVATE_ARRAY_PROPERTY === true) {_%>\n        <%_if(ARRAY_PRIVATE_PROPERTY !== null && ARRAY_PRIVATE_PROPERTY) {_%>\n            <%_if(Object.keys(ARRAY_PRIVATE_PROPERTY).length > 0) {_%>\n                <%_Object.keys(ARRAY_PRIVATE_PROPERTY).map((k) => {_%>\n                    if (object.<%-k%>.length > 0){\n                        let _<%-k%> = object.<%-k%>.filter(data => {\n                            delete data.<%-ARRAY_PRIVATE_PROPERTY[k]%>;\n                            return data;\n                        });\n                        object.<%-k%> = _<%-k%>;\n                    }\n                <%_});_%>\n            <%_}_%>    \n        <%_}_%>\n    <%_}_%>\n     \n    return object;\n});\nschema.plugin(mongoosePaginate);\nschema.plugin(idValidator);\n<%if (DB_UNIQUE) { %>\nschema.plugin(uniqueValidator,{ message: 'Error, expected {VALUE} to be unique.' });\n<% } %>\nconst <%- DB_MODEL %> = mongoose.model(\"<%- DB_MODEL %>\",schema,\"<%- DB_MODEL %>\");\nmodule.exports = <%- DB_MODEL %>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: routes of authentication APIs\n */\n\nconst express =  require(\"express\");\nconst routes  =  express.Router();\n<%_if(SOCIAL_PLATFORMS.length){ _%>\nconst session = require('express-session');\n<%_}_%>\nconst auth = require('../../middleware/auth');\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n\nconst authController =  require(\"../../controller/<%-PLATFORM%>/authController\")\nroutes.route(\"/register\").post(authController.register);\nroutes.post(\"/login\",authController.login);\nroutes.route(\"/forgot-password\").post(authController.forgotPassword);\nroutes.route(\"/validate-otp\").post(authController.validateResetPasswordOtp);\nroutes.route(\"/reset-password\").put(authController.resetPassword);\n<%_if(SOCIAL_PLATFORMS.length) { \n    SOCIAL_PLATFORMS.forEach(s=>{ _%>\nroutes.get(\"/login/<%-s.toLowerCase()%>\",(req,res)=>{\n    req.session.platform = <%=PLATFORM%>\n    res.redirect(`http://localhost:${process.env.PORT}/auth/<%-s.toLowerCase()%>`);\n})       \n<%_})_%>\n<%_}_%>\nroutes.route('/logout').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), authController.logout); \n\nmodule.exports = routes;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/commonIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n\n<%_ PLATFORM.forEach((p) =>{ _%>\nrouter.use(require(\"./<%-p%>Routes\"));\n<%_})_%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/index.js.ejs",
    "content": "/**\n * index.js\n * @description :: index route of platforms\n*/\n\nconst express = require(\"express\")\nconst router =  express.Router()\n<%_ if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimit=require('express-rate-limit');\n<%_ } _%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimiter=rateLimit({\n    windowMs:<%-REACTIVE_TIME%>*60*1000,\n    max:<%-LOGIN_RATE%>,\n    message: \"Too many API calls from this IP, please try again after a <%-REACTIVE_TIME%> minutes\"\n});\n<%_}_%>\n\n<%_for(let module in PLATFORM){_%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nrouter.use(rateLimiter,require(\"./<%-module%>/index\"));  \n<%_} else {_%> \nrouter.use(require(\"./<%-module%>/index\"));\n<%_}_%>\n<%_}_%>\n\n<%_if(typeof(CUSTOM_ROUTE) !== 'undefined'){_%>\n<%_Object.keys(CUSTOM_ROUTE).forEach(function(cr){_%>\nrouter.use(\"/\",require(\"<%-CUSTOM_ROUTE[cr]%>\"));\n<%_})_%>\n<%_}_%>\n\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/modelRoutes.js.ejs",
    "content": "/**\n * <%-DB_MODEL%>Routes.js\n * @description :: CRUD API routes for <%-DB_MODEL%>\n */\n\nconst express = require('express');\nconst router = express.Router();\nconst <%-DB_MODEL%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-DB_MODEL%>Controller\")\n<%_ if(IS_AUTH){ _%>\nconst auth = require(\"../../middleware/auth\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_ } _%>\n<%_ if(CUSTOM_POLICY && CUSTOM_POLICY.length){ \n    if(CUSTOM_POLICY.includes('auth') && IS_AUTH===true){ let arrayIndex = CUSTOM_POLICY.indexOf('auth'); delete CUSTOM_POLICY[arrayIndex]; CUSTOM_POLICY=CUSTOM_POLICY.filter(Boolean);}\n    _%>\n<%_ for(let i=0;i < CUSTOM_POLICY.length;i++){ _%>\nconst <%-CUSTOM_POLICY[i]-%> = require('../../middleware/<%-CUSTOM_POLICY[i]-%>');\n<%_ } _%>  \n<%_ } _%>  \n<%_ if(CONTROLLERS_TO_IMPORT && CONTROLLERS_TO_IMPORT.length){ _%>\n<%_ for(let i=0;i < CONTROLLERS_TO_IMPORT.length;i++){ \n    if(CONTROLLERS_TO_IMPORT[i] != DB_MODEL){ _%>\nconst <%-CONTROLLERS_TO_IMPORT[i]-%>Controller = require('../../controller/<%-PLATFORM%>/<%-CONTROLLERS_TO_IMPORT[i]-%>Controller');\n<%_ } }_%>  \n<%_ } _%> \n\n<%_ for(let i=0;i < SUPPORT_API.length;i++){ _%>\n<%_ if(SUPPORT_API[i].method==\"create\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/create\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%>\n<%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/create\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/addBulk\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/addBulk\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/list\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/list\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/:id\").get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/:id\").get(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"count\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/count\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/count\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ } _%><%_ } _%>\n<%_if(SUPPORT_API[i].method==\"update\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){  _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/update/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);    \n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/update/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);    \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"bulkUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/updateBulk\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/updateBulk\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"partialUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/partial-update/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%>\n<%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/partial-update/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%>\n<%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"deleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/deleteMany\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/deleteMany\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"delete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/delete/:id\").delete(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/delete/:id\").delete(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDelete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDelete/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDelete/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDeleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDeleteMany\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDeleteMany\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_}_%>\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/me\").get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.getLoggedInUserInfo);\nrouter.route(\"/<%-ROUTE_PREFIX%>/change-password\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.changePassword);\nrouter.route(\"/<%-ROUTE_PREFIX%>/update-profile\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.updateProfile);\n<%_ } _%> \n<%_ } _%> \n<%_if(CUSTOM_ROUTES && CUSTOM_ROUTES.length){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%-policy%>,\n<%_})_%>\n<%_}_%><%-v.controller%>Controller.<%-v.functionName%>)\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/platformIndexRoutes.js.ejs",
    "content": "/**\n * index.js\n * @description :: index route file of <%-PLATFORM_NAME.toLowerCase()%> platform.\n */\n\nconst express =  require(\"express\")\nconst router =  express.Router()\n<%_ if(IS_AUTH){ _%>\nrouter.use(\"/<%-PLATFORM_NAME.toLowerCase()%>/auth\",require(\"./auth\"));\n<%_}_%>\n<%_ for(let i in PLATFORM){ _%>\nrouter.use(require(\"./<%-i%>Routes\"));\n<%_}_%>  \n<%_if(typeof ROUTES!==\"undefined\"){_%>\n<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.controller%>Routes\"));\n<%_})_%>\n<%_}_%>\n<%_if(typeof(CUSTOM_ROUTES) !== 'undefined'){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.controller%>Routes\"));\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/routes/uploadRoutes.js.ejs",
    "content": "/**\n * uploadRoutes.js\n * @description :: routes of upload/download attachment\n */\n\nconst express = require('express');\nconst router = express.Router();\nconst fileUploadController = require(\"../../controller/<%-PLATFORM%>/fileUploadController\");\n<%_ if(IS_AUTH){ _%>\nconst auth = require(\"../../middleware/auth\");\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n<%_ } _%>\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/upload\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.upload);\n<%_ }else{ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/upload\",fileUploadController.upload);\n<%_ } _%>\n<%_ if(S3_UPLOAD_PRIVATE){_%>\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.generatePreSignedURL);\n<%_ } else { _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\",fileUploadController.generatePreSignedURL);\n<%_ } _%>\n<%_ } _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/seeders/index.js.ejs",
    "content": "/**\n * seeder.js\n * @description :: functions that seeds mock data to run the application\n */\n \n\n<%_if(IS_AUTH){_%>\n    const bcrypt = require('bcrypt')\n    const <%-AUTH_MODEL_FC%> = require('../model/<%-AUTH_MODEL%>');\n    const authConstant=require('../constants/authConstant');\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    <%_for(const model of ROLE_PERMISSION_MODELS){\n      let model_FC=(model).charAt(0).toUpperCase() + (model).slice(1); _%>\n      const <%-model_FC%> = require('../model/<%-model%>')\n    <%_}_%>\n    const { replaceAll } = require('../utils/common');\n  <%_}_%>\n<%_}_%>\nconst dbService = require('../utils/dbService');\n\n<%_if(IS_AUTH){_%>\n  /* seeds default users */\n  async function seedUser() {\n    try{\n      let userToBeInserted = {}\n      <%_for(let i in USER_EXIST_CONDITION){_%>\n        <%_var finalStr = new String();\n        USER[i].role=`@@authConstant.USER_ROLE.${ROLE_NAME[i]}@@`;\n        finalStr = JSON.stringify(USER[i]);\n        finalStr = finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\");\n        _%>\n        userToBeInserted = <%-finalStr%>\n        userToBeInserted.<%-PASSWORD_FIELD%> = await  bcrypt.hash(userToBeInserted.<%-PASSWORD_FIELD%>, 8)\n        let <%-ROLE_NAME[i].toLowerCase()%> = await dbService.findOneAndUpdateDocument(<%-AUTH_MODEL_FC%>, <%-JSON.stringify(USER_EXIST_CONDITION[i])%>, userToBeInserted,  {\n          upsert: true,\n          new: true\n        })\n      <%_}_%>\n      console.info('Users seeded 🍺');\n    } catch(error){\n      console.log('User seeder failed due to ', error.message)\n    }\n  }\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    /* seeds roles */\n    async function seedRole() {\n      try {\n        const roles = <%=ROLES%>;\n        const insertedRoles = await dbService.findAllDocuments(Role, { code: { '$in': roles.map(role => role.toUpperCase()) } });\n        const rolesToInsert = [];\n        roles.forEach(role => {\n          if (!insertedRoles.find(insertedRole => insertedRole.code === role.toUpperCase())) {\n            rolesToInsert.push({\n              name: role,\n              code: role.toUpperCase(),\n              weight: 1\n            });\n          }\n        });\n        if (rolesToInsert.length) {\n          const result = await dbService.bulkInsert(Role, rolesToInsert);\n          if (result) console.log('Role seeded 🍺');\n          else console.log('Role seeder failed!');\n        } else {\n          console.log('Role is up to date 🍺');\n        }\n      } catch (error) {\n        console.log('Role seeder failed due to ', error.message);\n      }\n    }\n\n    /* seeds routes of project */\n    async function seedProjectRoutes(routes) {\n      try {\n        if (routes  && routes.length) {\n          let routeName = '';\n          const dbRoutes = await dbService.findAllDocuments(ProjectRoute, {});\n          let routeArr = [];\n          let routeObj = {};\n          routes.forEach(route => {\n            routeName = `${replaceAll((route.path).toLowerCase(), '/', '_')}`;\n            route.methods.forEach(method => {\n              routeObj = dbRoutes.find(dbRoute => dbRoute.route_name === routeName && dbRoute.method === method);\n              if (!routeObj) {\n                routeArr.push({\n                  'uri': route.path.toLowerCase(),\n                  'method': method,\n                  'route_name': routeName,\n                });\n              }\n            });\n          });\n          if (routeArr.length) {\n            const result = await dbService.bulkInsert(ProjectRoute, routeArr);\n            if (result) console.info('ProjectRoute model seeded 🍺');\n            else console.info('ProjectRoute seeder failed.');\n          } else {\n            console.info('ProjectRoute is up to date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('ProjectRoute seeder failed due to ', error.message);\n      }\n    }\n\n    /* seeds role for routes */\n    async function seedRouteRole() {\n      try{\n        const routeRoles =[ \n          <%_for(let i=0;i<ROUTE_ROLE_ARRAY.length;i++){_%>\n          <%=ROUTE_ROLE_ARRAY[i]%>,\n          <%_}_%>\n\n        ];\n        if (routeRoles && routeRoles.length) {\n          const routes = [...new Set(routeRoles.map(routeRole => routeRole.route.toLowerCase()))];\n          const routeMethods = [...new Set(routeRoles.map(routeRole => routeRole.method))];\n          const roles = <%=ROLES%>;\n          const insertedProjectRoute = await dbService.findAllDocuments(ProjectRoute, {\n            uri: { '$in': routes },\n            method: { '$in': routeMethods },\n            'isActive': true,\n            'isDeleted': false\n          });\n          const insertedRoles = await dbService.findAllDocuments(Role, {\n            code: { '$in': roles.map(role => role.toUpperCase()) },\n            'isActive': true,\n            'isDeleted': false\n          });\n          let projectRouteId = '';\n          let roleId = '';\n          let createRouteRoles = routeRoles.map(routeRole => {\n            projectRouteId = insertedProjectRoute.find(pr => pr.uri === routeRole.route.toLowerCase() && pr.method === routeRole.method);\n            roleId = insertedRoles.find(r => r.code === routeRole.role.toUpperCase());\n            if (projectRouteId && roleId) {\n              return {\n                roleId: roleId.id,\n                routeId: projectRouteId.id\n              };\n            }\n          });\n          createRouteRoles = createRouteRoles.filter(Boolean);\n          const routeRolesToBeInserted = [];\n          let routeRoleObj = {};\n\n          await Promise.all(\n            createRouteRoles.map(async routeRole => {\n              routeRoleObj = await dbService.getDocumentByQuery(RouteRole, {\n                routeId: routeRole.routeId,\n                roleId: routeRole.roleId,\n              });\n              if (!routeRoleObj) {\n                routeRolesToBeInserted.push({\n                  routeId: routeRole.routeId,\n                  roleId: routeRole.roleId,\n                });\n              }\n            })\n          );\n          if (routeRolesToBeInserted.length) {\n            const result = await dbService.bulkInsert(RouteRole, routeRolesToBeInserted);\n            if (result) console.log('RouteRole seeded 🍺');\n            else console.log('RouteRole seeder failed!');\n          } else {\n            console.log('RouteRole is up to date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('RouteRole seeder failed due to ', error.message)\n      }\n    }\n\n    /* seeds roles for users */\n    async function seedUserRole (){\n      try {\n        const userRoles = <%-JSON.stringify(USER_ROLE_ARRAY)%>;\n        const defaultRole = await dbService.getDocumentByQuery(Role, { code: <%=DEFAULT_ROLE%> });\n        const insertedUsers = await dbService.findAllDocuments(User, { username: { '$in': userRoles.map(userRole => userRole.username) } });\n        let user = {};\n        const userRolesArr = [];\n        userRoles.map(userRole => {\n          user = insertedUsers.find(user => user.username === userRole.username && user.isPasswordMatch(userRole.password) && user.isActive && !user.isDeleted);\n          if (user) {\n            userRolesArr.push({\n              userId: user.id,\n              roleId: defaultRole.id\n            });\n          }\n        });\n        let userRoleObj = {};\n        const userRolesToBeInserted = [];\n        if (userRolesArr.length) {\n          await Promise.all(\n            userRolesArr.map(async userRole => {\n              userRoleObj = await dbService.getDocumentByQuery(UserRole, {\n                userId: userRole.userId,\n                roleId: userRole.roleId\n              });\n              if (!userRoleObj) {\n                userRolesToBeInserted.push({\n                  userId: userRole.userId,\n                  roleId: userRole.roleId\n                });\n              }\n            })\n          );\n          if (userRolesToBeInserted.length) {\n            const result = await dbService.bulkInsert(UserRole, userRolesToBeInserted);\n            if (result) console.log('UserRole seeded 🍺');\n            else console.log('UserRole seeder failed');\n          } else {\n            console.log('UserRole is up to date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('UserRole seeder failed due to ', error.message);\n      }\n    }\n  <%_}_%>\n<%_}_%>\n\nasync function seedData(<%_if(IS_AUTH && SHOULD_ADD_ROLE_PERMISSION){_%>allRegisterRoutes<%_}_%>){\n<%_if(IS_AUTH){_%>\n  await seedUser();\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    await seedRole();\n    await seedProjectRoutes(allRegisterRoutes);\n    await seedRouteRole();\n    await seedUserRole();\n  <%_}_%>\n<%_}_%>\n};\nmodule.exports = seedData;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/services/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: service functions used in authentication\n */\n\nconst <%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%> = require(\"../model/<%-MODEL%>\")\nconst dbService = require(\"../utils/dbService\");\nconst userTokens = require(\"../model/userTokens\");\nconst { JWT,LOGIN_ACCESS,\n    PLATFORM<%_if(LOGIN_RETRY_LIMIT){_%>,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME<%_}_%>\n    <%_if(RESET_PASSWORD){_%>,FORGOT_PASSWORD_WITH<%_}_%>\n    <%_if(MAX_DEVICE_ALLOWED){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\");\nconst jwt = require(\"jsonwebtoken\");\nconst common = require(\"../utils/common\");\nconst dayjs = require(\"dayjs\");\nconst bcrypt = require(\"bcrypt\");\nconst emailService = require(\"./email/emailService\");\nconst smsService = require(\"./sms/smsService\");\n<%_if(FORGOT_WITH_LINK){_%>\nconst uuid = require(\"uuid\").v4;\n<%_}_%>\n<%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS'){_%>\nconst ejs = require(\"ejs\");\n<%_}_%>\n\n/**\n* @description : service to generate JWT token for authentication.\n* @param {object} user : user who wants to login.\n* @param {string} secret : secret for JWT.\n* @return {string}  : returns JWT token.\n*/\nconst generateToken = async (user,secret) => {\n    return jwt.sign( {id:user.id,'<%-LOGIN_WITH[0]%>':user.<%-LOGIN_WITH[0]%>}, secret, {\n        expiresIn: JWT.EXPIRES_IN * 60\n    });\n}\n\n    /**\n    * @description : service of login user.\n    * @param {string} username : username of user.\n    * @param {string} password : password of user.\n    * @param {string} platform : platform of requested route to login.\n        <%_if(ROLE_PERMISSION) {_%>\n    * @param {boolean} roleAccess: a flag to request role access of user.\n        <%_}_%>\n    * @return {object} : returns authentication status. {flag, data}\n    */\n    const loginUser=async(username,password,platform<%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n            try {\n                <%_ if(LOGIN_WITH.length>1){ _%>\n                let where = <%-MULTIPLE_LOGIN%>\n                <%_ }else{_%>\n                let where ={'<%-LOGIN_WITH[0]%>':username}\n                <%_}_%>                  \n                let user = await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,where);\n                if (user) {\n                    <%_if(MAX_DEVICE_ALLOWED){_%>\n                        const userToken = await dbService.countDocument(userTokens, { $and:[{ tokenExpiredTime: { $gt: dayjs().toISOString() }, },{ isTokenExpired: 0, },{ userId:user.id }] } );\n                        if(userToken >= NO_OF_DEVICE_ALLOWED){\n                            return {\n                                flag: true,\n                                data: \"You have reached your device limit\"\n                            }\n                        }\n                    <%_}_%>\n                    <%_if(LOGIN_RETRY_LIMIT){_%>\n                    if(user.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT){\n                        let now = dayjs();\n                        if (user.loginReactiveTime){\n                            let limitTime = dayjs(user.loginReactiveTime);\n                            if (limitTime > now){\n                              let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                              if (!(limitTime > expireTime)){\n                                return {\n                                  flag:true,\n                                  data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,limitTime)}.`\n                                }; \n                              }   \n                              await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{\n                                loginReactiveTime:expireTime.toISOString(),\n                                <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1  \n                              });\n                              return {\n                                flag:true,\n                                data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                              }; \n                            }else {\n                                user = await dbService.findOneAndUpdateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,{ _id:user.id },{\n                                  loginReactiveTime:'',\n                                  <%-LOGIN_RETRY_LIMIT.key%>:0\n                                },{ new:true });\n                              }\n                          } else {\n                            // send error\n                            let expireTime = dayjs().add(LOGIN_REACTIVE_TIME,'minute');\n                            await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{\n                              loginReactiveTime:expireTime.toISOString(),\n                              <%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%> + 1 \n                            });\n                            return {\n                              flag:true,\n                              data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                            }; \n                          } \n                    }\n                    <%_}_%>\n                    const isPasswordMatched = await user.isPasswordMatch(password);\n                    if (isPasswordMatched) {\n                        const {password,...userData}=user.toJSON()\n                        let token;\n                        if(!user.role){\n                            return {flag:true, data:'You have not assigned any role'}\n                        }\n                        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n                            <%_if(i===0){_%>\n                            if(platform == PLATFORM.<%-PLATFORMS[i].toLowerCase()%>){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}else{_%>\n                            else if(platform == PLATFORM.<%-PLATFORMS[i].toLowerCase()%>){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}_%>\n                        <%_}_%>                          \n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        if(user.<%-LOGIN_RETRY_LIMIT.key%>){\n                            await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{<%-LOGIN_RETRY_LIMIT.key%>:0,loginReactiveTime:''});\n                        }\n                        <%_}_%>\n                        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n                        await dbService.createDocument(userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n                        let userToReturn = { ...userData, token };\n                        <%_if(ROLE_PERMISSION){_%>\n                            let roleAccessData = {};\n                            if (roleAccess){\n                            roleAccessData = await common.getRoleAccessData(user.id);\n                            userToReturn = {\n                                ...userToReturn,\n                                roleAccess: roleAccessData\n                            };\n                            }\n                        <%_}_%>\n                        return {flag:false,data:userToReturn}\n                    } else {\n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{<%-LOGIN_RETRY_LIMIT.key%>:user.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                        <%_}_%>\n                        return {flag:true,data:'Incorrect Password'}\n                    }\n                } else {\n                    return {flag:true,data:'User not exists'}\n                }\n            } catch (error) {\n                throw new Error(error.message)\n            }\n    }\n\n    /**\n    * @description : service to change password.\n    * @param {object} params : object of new password, old password and user id.\n    * @return {object}  : returns status of change password. {flag,data}\n    */\n    const changePassword=async(params)=>{\n        try {\n            let password = params.newPassword;\n            let oldPassword = params.oldPassword;\n            let where = {_id:params.userId};\n            let user = await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,where);\n            if (user && user.id) {\n                let isPasswordMatch = await user.isPasswordMatch(oldPassword);\n                if(!isPasswordMatch){\n                    return {\n                        flag:true,\n                        data:'Incorrect old password'\n                    }\n                }\n                password = await bcrypt.hash(password, 8);\n                let updatedUser = dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{<%-PASSWORD%>:password});\n                if (updatedUser) {\n                    return {flag:false,data:'Password changed successfully'};                \n                }\n                return {flag:true,data:'password can not changed due to some error.please try again'}\n            }\n            return {flag:true,data:'User not found'}\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n\n    /**\n    * @description : service to send notification on reset password.\n    * @param {object} user : user document\n    * @return {}  : returns status where notification is sent or not\n    */\n    const sendResetPasswordNotification=async (user) => {\n        let resultOfEmail=false;\n        let resultOfSMS=false;\n        try {\n            <%_if(FORGOT_WITH_LINK){_%>\n            let token = uuid();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,\n                { resetPasswordLink: { code: token, expireTime: expires } });\n            if(FORGOT_PASSWORD_WITH.LINK.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                    let updatedUser= await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,{_id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                };\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = { \n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:updatedUser\n                };\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = \"Click on the link below to reset your password.\";\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/\",\n                    data: {\n                        link: `http://localhost:${process.env.PORT}` + viewType + token,\n                        linkText: \"Reset Password\",\n                        message:msg\n                    }\n                };\n                <%_}_%>\n                try {\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;\n                } catch (error) {\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.LINK.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%>\n                let updatedUser= await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,{_id:user.id}); \n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.mobileNo,\n                    message:msg\n                }\n                try {\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                } catch (error) {\n                    console.log(error);\n                }\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = `Click on the link to reset your password.\n                http://localhost:${process.env.PORT}${viewType + token}`;\n                let smsObj = {\n                    to:user.mobileNo,\n                    message:msg\n                }\n                try {\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                } catch (error) {\n                    console.log(error);\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            <%_if(FORGOT_WITH_OTP){_%>\n            let otp = common.randomNumber();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,user.id,{ resetPasswordLink: { code: otp, expireTime: expires } });\n            if(FORGOT_PASSWORD_WITH.OTP.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,{_id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>',    \n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                }\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>',\n                    data:updatedUser\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/',\n                    data: {\n                        isWidth: true,\n                        name: \"username\",\n                        email: user.<%-EMAIL_FIELD%> || '-',\n                        message: otpMsg,\n                        otp: otp\n                    }\n                };\n                <%_}_%>\n                try {\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;\n                } catch (error) {\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.OTP.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,{_id:user.id}); \n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.mobileNo,\n                    message:msg\n                }\n                try {\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                } catch (error) {\n                    console.log(error);\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let smsObj = {\n                    message: otpMsg,\n                    to: user.mobileNo,\n                };\n                try {\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                } catch (error) {\n                    console.log(error);\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            return {resultOfEmail,resultOfSMS};\n        } catch (error) {\n            throw new Error(error.message);\n        }\n    }\n\n    /**\n    * @description : service to reset password.\n    * @param {object} user : user document\n    * @param {string} newPassword : new password to be set.\n    * @return {}  : returns status whether new password is set or not. {flag, data}\n    */\n    const resetPassword=async (user, newPassword) => {\n        try {\n            let where = { _id: user.id };  \n            const dbUser = await dbService.getDocumentByQuery(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>,where);\n            if (!dbUser) {\n                return {\n                    flag: true,\n                    data: \"User not found\",\n                };\n            }\n            newPassword = await bcrypt.hash(newPassword, 8);\n            await dbService.updateDocument(<%-MODEL.charAt(0).toUpperCase() + MODEL.slice(1)%>, user.id, {\n                <%-PASSWORD%>: newPassword,\n                resetPasswordLink: null,\n                <%_if(LOGIN_RETRY_LIMIT){_%>\n                <%-LOGIN_RETRY_LIMIT.key%>:0\n                <%_}_%>\n            });\n            let mailObj = {\n                subject: 'Reset Password',\n                to: user.<%-EMAIL_FIELD%>,\n                template: '/views/successfullyResetPassword',\n                data: {\n                    isWidth: true,\n                    email: user.<%-EMAIL_FIELD%> || '-',\n                    message: \"Password Successfully Reset\"\n                }\n            };\n            await emailService.sendMail(mailObj);\n            return {\n                flag: false,\n                data: \"Password reset successfully\",\n            };\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    }\n\nmodule.exports = {\n    loginUser,\n    changePassword,\n    resetPassword,\n    sendResetPasswordNotification\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/services/customQueryService.js.ejs",
    "content": "/**\n * customQueryService.js\n * @description :: exports functions used in manipulating data from database\n */\n\n/**\n * @description : uses model instance and other parameters to find the desire data from collection\n * @param {object} model : mongoose model instance of collection\n * @param {object} : filter,populate,skip,limit,select and sort to be applied with query\n * @return {object} : found document(s).\n */   \nconst find = async (model, { filter = {}, populate, skip, limit, select, sort }) => {\n    let query = model.find(filter)\n    if (select) {\n        query = query.select(select)\n    }\n    if (populate) {\n        query = query.populate(populate)\n    }\n    if (skip) {\n        query = query.skip(skip)\n    }\n    if (limit) {\n        query = query.limit(limit)\n    }\n    if (sort) {\n        query = query.sort(sort)\n    }\n    return await query.exec()\n}\n\n/**\n * @description : create a new document into the collection\n * @param {object} model : mongoose model instance of collection\n * @param {object} data  : data to be created\n * @param {object} option : mongoose options used with create method\n * @return {object} : created document(s)\n */  \nconst create = async(model,data,options={})=>{\n    try {\n        if(data && data.length){\n            return await model.create(data,options)\n        }else{\n            return await model.create([data],options)\n        }\n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\n/**\n * @description : find and update the document of collection\n * @param {object} model  : mongoose model instance of collection\n * @param {object} filter : filter to find the data \n * @param {object} data   : data to update\n * @param {object} option : mongoose options used with findOneAndUpdate method\n * @return {object} : updated document.\n */ \nconst findOneAndUpdate = async(model,filter,data,options={new:true})=>{\n    try {\n        return await model.findOneAndUpdate(filter,data,options)        \n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\n/**\n * @description : find and remove the document from collection\n * @param {object} model  : mongoose model instance of collection\n * @param {object} filter : filter to find the document \n * @param {object} option : mongoose options used with findOneAndDelete method\n * @return {object} : removed document.\n */ \nconst findOneAndDelete = async(model,filter,options={})=>{\n    try {\n        return await model.findOneAndDelete(filter,options)        \n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\n/**\n * @description : find and update multiple documents into the collection\n * @param {object} model  : mongoose model instance of collection\n * @param {object} filter : filter to find the document to be updated\n * @param {object} data   : data to update\n * @param {object} option : mongoose options used with updateMany method\n * @return {array} : updated document(s).\n */ \nconst updateMany = async(model,filter,data,options={})=>{\n    try {\n        const documentsToBeUpdated =  await model.find(filter);\n        await model.updateMany(filter,data,options);\n        return documentsToBeUpdated;\n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\n/**\n * @description : removes multiple documents from collection\n * @param {object} model  : mongoose model instance of collection\n * @param {object} filter : filter to find the document \n * @param {object} option : mongoose options used with deleteMany method\n * @return {array} : removed document(s).\n */ \nconst deleteMany = async(model,filter,options={})=>{\n    try {\n        const documentsToBeDeleted = await model.find(filter);\n        await model.deleteMany(filter,options);\n        return documentsToBeDeleted;\n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\n/**\n * @description : find the aggregate data of collection\n * @param {object} model  : mongoose model instance of collection\n * @param {array} queries : pipeline to be applied for aggregation \n * @return {array} : found document(s).\n */ \nconst aggregate = async(model, queries)=>{\n    try {\n        return await model.aggregate(queries)\n    } catch (error) {\n        throw new Error(error.message)\n    }\n}\n\nmodule.exports = {\n    find,\n    create,\n    findOneAndUpdate,\n    findOneAndDelete,\n    updateMany,\n    deleteMany,\n    aggregate\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/services/emailService.js.ejs",
    "content": "/** \n * emailService.js\n * @description :: exports function used in sending mails using mailgun provider\n */\n\nconst nodemailer = require('nodemailer');\nconst ejs = require(\"ejs\")\nmodule.exports = {\n    sendMail: async (obj) => {\n        let transporter = nodemailer.createTransport({\n            service: 'Mailgun',\n            auth: {\n                user: '',\n                pass: ''\n            }\n        });\n        if (!Array.isArray(obj.to)) {\n            obj.to = [obj.to];\n        }\n        const htmlText = await ejs.renderFile(`${__basedir}${obj.template}/html.ejs`, obj.data);\n\n        return await Promise.all(obj.to.map((emailId) => {\n            var mailOpts = {\n                from: obj.from || \"noreply@yoyo.co\",\n                to: emailId,\n                subject: obj.subject,\n                html: htmlText\n            };\n            transporter.sendMail(mailOpts, function (err, response) {\n                if (err) {\n                    //ret.message = \"Mail error.\";\n                } else {\n                    //ret.message = \"Mail send.\";\n                }\n            });\n        }));\n    }\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/services/smsService.js.ejs",
    "content": "/** \n * smsService.js\n * @description :: exports function used in sending sms using gupshup provider\n */\n\nconst axios = require('axios')\nconst sendSMS = async (obj) => {\n    console.log('SMS---', obj);\n    if (obj.to) {\n        obj.mobiles = obj.to;\n    }\n    let mobiles;\n    if (Array.isArray(obj.mobiles)) {\n        obj.mobiles = obj.mobiles.map((m) => {\n            let tmpNo = m.split('+');\n            return tmpNo[1] ? tmpNo[1] : tmpNo[0];\n        });\n        mobiles = obj.mobiles.join(',');\n    }\n    else {\n        let tmpNo = obj.mobiles.split('+');\n        mobiles = tmpNo[1] ? tmpNo[1] : tmpNo[0];\n    }\n    const message = obj.message\n    const userid = \"\"\n    const password = escape(\"You Password\")\n    const v = 1.1\n    const method = \"sendMessage\"\n    const msg_type = \"text\"\n    const send_to = mobiles\n    return await new Promise((resolve, reject) => {\n        axios(\n            {\n                url: `http://enterprise.smsgupshup.com/GatewayAPI/rest?msg=${message}&v=${v}&userid=${userid}&password=${password}&method=${method}&send_to=${send_to}&msg_type=${msg_type}`,\n                method: 'GET',\n            })\n            .then(function (response) {\n                let response1 = response.data.split('|');\n                console.log(response.data)\n                if (response1.length) {\n                    if (response1[0].trim() === 'error') {\n                        reject(response)\n                    } else {\n                        resolve(response)\n                    }\n                }\n            })\n            .catch(function (error) {\n                reject(error)\n            });\n    });\n}\nmodule.exports = {sendSMS}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/common.js.ejs",
    "content": "/**\n * common.js\n * @description: exports helper methods for project.\n */\n\n<%_if(IS_AUTH && ROLE_PERMISSION){ _%>\nconst mongoose = require('mongoose');\nconst UserRole = require('../model/userRole');\nconst RouteRole = require('../model/routeRole');\n<%_}_%>\n<%_if(IS_AUTH){ _%>\nconst dbService = require('./dbService');\n<%_}_%>\n\n/**\n * convertObjectToEnum : converts object to enum\n * @param {object} object : object to be converted\n * @return {array} : converted array\n */\nfunction convertObjectToEnum (object) {\n  const enumArr = [];\n  Object.values(object).map((val) => enumArr.push(val));\n  return enumArr;\n}\n\n/**\n * randomNumber : generate random numbers for given length\n * @param {number} length : length of random number to be generated (default 4)\n * @return {number} : generated random number\n */\nfunction randomNumber (length = 4) {\n  const numbers = '12345678901234567890';\n  let result = '';\n  for (let i = length; i > 0; i -= 1) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\n/**\n * replaceAll: find and replace all occurrence of a string in a searched string\n * @param {string} string  : string to be replace\n * @param {string} search  : string which you want to replace\n * @param {string} replace : string with which you want to replace a string\n * @return {string} : replaced new string\n */\nfunction replaceAll (string, search, replace) { \n  return string.split(search).join(replace); \n}\n\n<%_if(IS_AUTH){ _%>\n/**\n * uniqueValidation: check unique validation while user registration\n * @param {object} model : mongoose model instance of collection\n * @param {object} data : data, coming from request\n * @return {boolean} : validation status\n */\nasync function uniqueValidation (Model,data){\n    <%_if (LOGIN_WITH.length > 1) {_%>\n    let filter = {$or:[]};\n    <%_for(let i in LOGIN_WITH){_%>\n    if(data && data[\"<%-LOGIN_WITH[i]%>\"]){\n        filter['$or'].push(\n        <%_for(let j in LOGIN_WITH){_%>\n        {\"<%-LOGIN_WITH[j]%>\":data[\"<%-LOGIN_WITH[i]%>\"]},\n        <%_}_%>\n        )\n    }\n    <%_}_%>\n    <%_} else {_%>\n    let filter = {};\n    if(data && data[\"<%-LOGIN_WITH[0]%>\"]){\n        filter = { \"<%-LOGIN_WITH[0]%>\": data[\"<%-LOGIN_WITH[0]%>\"] }\n    }\n    <%_}_%>\n    filter.isActive = true;\n    filter.isDeleted = false;\n    let found = await dbService.getDocumentByQuery(Model,filter);\n    if(found){\n        return false;\n    }\n    return true;\n}\n<%_}_%>\n\n<%_if(IS_AUTH){_%>\n/**\n * getDifferenceOfTwoDatesInTime : get difference between two dates in time\n * @param {date} currentDate  : current date\n * @param {date} toDate  : future date\n * @return {string} : difference of two date in time\n */\nfunction getDifferenceOfTwoDatesInTime(currentDate,toDate){\n  let hours = toDate.diff(currentDate,'hour');\n  currentDate =  currentDate.add(hours, 'hour');\n  let minutes = toDate.diff(currentDate,'minute');\n  currentDate =  currentDate.add(minutes, 'minute');\n  let seconds = toDate.diff(currentDate,'second');\n  currentDate =  currentDate.add(seconds, 'second');\n  if (hours){\n    return `${hours} hour, ${minutes} minute and ${seconds} second`; \n  }\n  return `${minutes} minute and ${seconds} second`; \n}\n<%_}_%>\n\n<%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n/** \n * getRoleAccessData: returns role access of User\n * @param {objectId} userId : id of user to find role data\n * @return {object} : role access of user for APIs of model\n */\nasync function getRoleAccessData (userId) {\n  let userRole = await dbService.getAllDocuments(UserRole, { userId: userId },{pagination:false});\n  let routeRole = await dbService.getAllDocuments(RouteRole, { roleId: { $in: userRole.data ? userRole.data.map(u=>u.roleId) : [] } },{ pagination:false,populate:['roleId','routeId'] });\n  let models = mongoose.modelNames();\n  let Roles = routeRole.data ? routeRole.data.map(rr => rr.roleId && rr.roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (Roles.length){\n    Roles.map(role => {\n      roleAccess[role] = {};\n      models.forEach(model => {\n        if (routeRole.data && routeRole.data.length) {\n          routeRole.data.map(rr => {\n            if (rr.routeId && rr.routeId.uri.includes(`/${model.toLowerCase()}/`) && rr.roleId && rr.roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr.routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr.routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr.routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr.routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return roleAccess;\n}\n<%_}_%>\n\nmodule.exports = {\n  convertObjectToEnum,\n  randomNumber,\n  replaceAll,\n  <%_if(IS_AUTH){ _%>\n  uniqueValidation,\n  getDifferenceOfTwoDatesInTime,\n  <%_}_%>\n  <%_if(IS_AUTH && ROLE_PERMISSION){ _%>\n  getRoleAccessData,\n  <%_}_%>\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/dbService.js",
    "content": "/*\n * @description : create any mongoose document\n * @param  {object} model : mongoose model\n * @param  {object} data : {}\n * @return Promise\n */\nconst createDocument = (model, data) => new Promise((resolve, reject) => {\n  model.create(data, (err, result) => {\n    if (err) reject(err);\n    else resolve(result);\n  });\n});\n\n/*\n * @description : update any existing mongoose document\n * @param  {object} model : mongoose model\n * @param {ObjectId} id : mongoose document's _id\n * @param {object} data : {}\n * @return Promise\n */\nconst updateDocument = (model, id, data) => new Promise((resolve, reject) => {\n  model.updateOne({ _id: id }, data, {\n    runValidators: true,\n    context: 'query',\n  }, (err, result) => {\n    if (err) reject(err);\n    else resolve(result);\n  });\n});\n\n/*\n * @description : delete any existing mongoose document\n * @param  {object} model : mongoose model\n * @param  {ObjectId} id : mongoose document's _id\n * @return Promise\n */\nconst deleteDocument = (model, id) => new Promise((resolve, reject) => {\n  model.deleteOne({ _id: id }, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : find all the mongoose document\n * @param  {object} model : mongoose model\n * @param {object} query : {}\n * @param {object} options : {}\n * @return Promise\n */\nconst getAllDocuments = (model, query, options) => new Promise((resolve, reject) => {\n  model.paginate(query, options, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : find single mongoose document\n * @param  {object} model : mongoose model\n * @param  {ObjectId} id : mongoose document's _id\n * @param  {Array} select : [] *optional\n * @return Promise\n */\nconst getSingleDocumentById = (model, id, select = []) => new Promise((resolve, reject) => {\n  model.findOne({ _id: id }, select, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : find existing mongoose document\n * @param  {object} model  : mongoose model\n * @params {object} data   : {\n *                   \"query\":{\n *                       \"and\":[{\"Name\":\"Dhiraj\"},{\"Salary\":300}],\n *                        \"or\":[{\"Name\":\"Dhiraj\"},{\"Salary\":300}]\n *                   }\n * }\n * @return Promise\n */\nconst findExistsData = (model, data) => {\n  // let { model } = data;\n  const { query } = data;\n  const { and } = query;\n  const { or } = query;\n  const q = {};\n\n  if (and) {\n    q.$and = [];\n    for (let index = 0; index < and.length; index += 1) {\n      q.$and.push(and[index]);\n    }\n  }\n  if (or) {\n    q.$or = [];\n    for (let index = 0; index < or.length; index += 1) {\n      q.$or.push(or[index]);\n    }\n  }\n\n  return new Promise((resolve, reject) => {\n    model.find(q, (err, result) => {\n      if (err) reject(err);\n      else resolve(result);\n    });\n  });\n};\n\n/*\n * @description : soft delete ( partially delete ) mongoose document\n * @param  {object} model : mongoose model\n * @param  {ObjectId} id : mongoose document's _id\n * @return Promise\n */\n// eslint-disable-next-line no-async-promise-executor\nconst softDeleteDocument = (model, id) => new Promise(async (resolve, reject) => {\n  const result = await getSingleDocumentById(model, id);\n  result.isDeleted = true;\n  model.updateOne({ _id: id }, result, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * bulkInsert     : create document in bulk mongoose document\n * @param  {object} model  : mongoose model\n * @param  {object} data   : {}\n * @return Promise\n */\nconst bulkInsert = (model, data) => new Promise((resolve, reject) => {\n  model.insertMany(data, (err, result) => {\n    if (result !== undefined && result.length > 0) {\n      resolve(result);\n    } else {\n      reject(err);\n    }\n  });\n});\n\n/*\n * @description     : update existing document in bulk mongoose document\n * @param  {object} model  : mongoose model\n * @param  {object} filter : {}\n * @param  {object} data   : {}\n * @return Promise\n */\nconst bulkUpdate = (model, filter, data) => new Promise((resolve, reject) => {\n  model.updateMany(filter, data, (err, result) => {\n    if (result !== undefined) {\n      resolve(result);\n    } else {\n      reject(err);\n    }\n  });\n});\n\n/*\n * @description : count total number of records in particular model\n * @param  {object} model : mongoose model\n * @param {object} where  : {}\n * @return Promise\n */\nconst countDocument = (model, where) => new Promise((resolve, reject) => {\n  model.where(where).countDocuments((err, result) => {\n    if (result !== undefined) {\n      resolve(result);\n    } else {\n      reject(err);\n    }\n  });\n});\n\n/*\n * @description : find document by dynamic query\n * @param  {object} model : mongoose model\n * @param  {object} where : {}\n * @param  {Array} select : [] *optional\n */\nconst getDocumentByQuery = (model, where, select = []) => new Promise((resolve, reject) => {\n  model.findOne(where, select, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : find existing document and update mongoose document\n * @param  {object} model   : mongoose model\n * @param  {object} filter  : {}\n * @param  {object} data    : {}\n * @param  {object} options : {} *optional\n * @return Promise\n */\nconst findOneAndUpdateDocument = (model, filter, data, options = { new: true }) => new Promise((resolve, reject) => {\n  model.findOneAndUpdate(filter, data, options, (err, result) => {\n    if (err) reject(err);\n    else resolve(result);\n  });\n});\n\n/*\n * @description : find existing document and delete mongoose document\n * @param  {object} model  : mongoose model\n * @param  {object} filter  : {}\n * @param  {object} options : {} *optional\n * @return Promise\n */\nconst findOneAndDeleteDocument = (model, filter, options = { new: true }) => new Promise((resolve, reject) => {\n  model.findOneAndDelete(filter, options, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : delete multiple document\n * @param  {object} model  : mongoose model\n * @param  {object} filter  : {}\n * @param  {object} options : {} *optional\n * @return Promise\n */\nconst deleteMany = (model, filter, options = {}) => new Promise((resolve, reject) => {\n  model.deleteMany(filter, options, (err, data) => {\n    if (err) reject(err);\n    else resolve(data);\n  });\n});\n\n/*\n * @description : find all the mongoose document\n * @param  {Object} model   : mongoose model\n * @param {Object} query    : {}\n * @param {Object} options  : {}\n * @return Promise\n */\nconst findAllDocuments = (model, filter = {}, options = {}) => new Promise((resolve, reject) => {\n  let query = model.find(filter);\n  if (options.select) {\n    query = query.select(options.select);\n  }\n  if (options.populate) {\n    query = query.populate(options.populate);\n  }\n  if (options.lean) {\n    query = query.lean();\n  }\n  query.exec((error, data) => {\n    if (error) reject(error);\n    else resolve(data);\n  });\n});\n\nmodule.exports = {\n  createDocument,\n  getAllDocuments,\n  updateDocument,\n  deleteDocument,\n  getSingleDocumentById,\n  findExistsData,\n  softDeleteDocument,\n  bulkInsert,\n  bulkUpdate,\n  countDocument,\n  getDocumentByQuery,\n  findOneAndUpdateDocument,\n  findOneAndDeleteDocument,\n  deleteMany,\n  findAllDocuments,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/deleteDependentService1.js.ejs",
    "content": "/**\n * deleteDependent.js\n * @description :: exports deleteDependent service for project.\n */\n\n<%_ \nfunction getRandomInt(max) {\n    return Math.floor(Math.random() * max);\n}\nfunction getRandomInt(length = 4){\n        let numbers = '12345678901234567890';\n        let result = '';\n        for (let i = length; i > 0; --i) {\n            result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n        }\n        return result;\n    }\n_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nlet <%-model_FC%> = require(\"../model/<%-model%>\")\n<%_}_%>\nlet dbService = require(\"../utils/dbService\");\n\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst delete<%-model_FC%> = async (filter) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.find(filter, {_id:1});\n        if(<%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj._id);\n            <%_(DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}`\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {\"$in\": <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await delete<%-eModel%>(<%-modelFilter%>);\n            <%_})_%>\n            return await <%-model_FC%>.deleteMany(filter)\n        }else{\n            return \"No <%-model%> found.\"\n        }\n    <%_}else{_%>\n        return await <%-model_FC%>.deleteMany(filter);\n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst count<%-model_FC%> = async (filter) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.find(filter, {_id:1});\n        if(<%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj._id);\n            <%_ let newCntModelName = [];\n            (DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}Cnt`\n                newCntModelName.push(modelNewName)\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {\"$in\": <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await count<%-eModel%>(<%-modelFilter%>);\n            <%_})_%>\n            const <%-model%>Cnt =  await <%-model_FC%>.countDocuments(filter)\n            let response = {<%-model%> : <%-model%>Cnt  }\n            response = {\n                ...response,\n                <%_ newCntModelName.forEach((cntModel)=>{_%>\n                    ...<%-cntModel%>,\n                <%_})_%>\n            }\n            return response;\n        }\n    <%_}else{_%>\n        const <%-model%>Cnt =  await <%-model_FC%>.countDocuments(filter);\n        return {<%-model%> : <%-model%>Cnt}\n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst softDelete<%-model_FC%> = async (filter,loggedInUser) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.find(filter, {_id:1});\n        if(<%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj._id);\n            <%_(DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}`\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {\"$in\": <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await softDelete<%-eModel%>(<%-modelFilter%>);\n            <%_})_%>\n            if(loggedInUser && loggedInUser.id)\n                return await <%-model_FC%>.updateMany(filter, {isDeleted:true,updatedBy:loggedInUser.id})\n            else\n                return await <%-model_FC%>.updateMany(filter,{isDeleted:true})\n        }else{\n            return \"No <%-model%> found.\"\n        }\n    <%_}else{_%>\n        if(loggedInUser && loggedInUser.id)\n        return await <%-model_FC%>.updateMany(filter, {isDeleted:true,updatedBy:loggedInUser.id});\n    else\n        return await <%-model_FC%>.updateMany(filter,{isDeleted:true})\n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n\n\nmodule.exports ={\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    delete<%-model_FC%>,\n    <%_}_%>\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    count<%-model_FC%>,\n    <%_}_%>\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    softDelete<%-model_FC%>,\n    <%_}_%>\n}\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/response/index.js",
    "content": "const responseStatus = require('./responseStatus');\n\nmodule.exports = {\n  success: (data = {}) => ({\n    status: responseStatus.success,\n    message: data.message || 'Your request is successfully executed',\n    data: data.data || {},\n  }),\n\n  failure: (data = {}) => ({\n    status: responseStatus.failure,\n    message: data.message || 'Some error occurred while performing action.',\n    data: data.data || {},\n  }),\n\n  internalServerError: (data = {}) => ({\n    status: responseStatus.serverError,\n    message: data.message || 'Internal server error.',\n    data: data.data || {},\n  }),\n\n  badRequest: (data = {}) => ({\n    status: responseStatus.badRequest,\n    message: data.message || 'Request parameters are invalid or missing.',\n    data: data.data || {},\n  }),\n\n  recordNotFound: (data = {}) => ({\n    status: responseStatus.recordNotFound,\n    message: data.message || 'Record(s) not found with specified criteria.',\n    data: data.data || {},\n  }),\n\n  validationError: (data = {}) => ({\n    status: responseStatus.validationError,\n    message: data.message || `Invalid Data, Validation Failed.`,\n    data: data.data || {},\n  }),\n\n  unAuthorized: (data = {}) => ({\n    status: responseStatus.unauthorized,\n    message: data.message || 'You are not authorized to access the request',\n    data: data.data || {},\n  }),\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/response/responseCode.js",
    "content": "module.exports = {\n  success: 200,\n  badRequest: 400,\n  internalServerError: 500,\n  unAuthorized: 401,\n  notFound: 404,\n  validationError: 422,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/response/responseHandler.js",
    "content": "/**\n * responseHandler.js\n * @description :: exports all handlers for response format.\n */\nconst responseBody = require('./index');\nconst responseCode = require('./responseCode');\n\n/**\n *\n * @param {obj} req : request from controller.\n * @param {obj} res : response from controller.\n * @param {*} next : executes the middleware succeeding the current middleware.\n */\nconst responseHandler = (req, res, next) => {\n  res.success = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.success(data));\n  };\n  res.failure = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.failure(data));\n  };\n  res.internalServerError = (data = {}) => {\n    res.status(responseCode.internalServerError).json(responseBody.internalServerError(data));\n  };\n  res.badRequest = (data = {}) => {\n    res.status(responseCode.badRequest).json(responseBody.badRequest(data));\n  };\n  res.recordNotFound = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.recordNotFound(data));\n  };\n  res.validationError = (data = {}) => {\n    res.status(responseCode.validationError).json(responseBody.validationError(data));\n  };\n  res.unAuthorized = (data = {}) => {\n    res.status(responseCode.unAuthorized).json(responseBody.unAuthorized(data));\n  };\n  next();\n};\n\nmodule.exports = responseHandler;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/response/responseStatus.js",
    "content": "module.exports = {\n  success: 'SUCCESS',\n  failure: 'FAILURE',\n  serverError: 'SERVER_ERROR',\n  badRequest: 'BAD_REQUEST',\n  recordNotFound: 'RECORD_NOT_FOUND',\n  validationError: 'VALIDATION_ERROR',\n  unauthorized: 'UNAUTHORIZED',\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/validateRequest.js",
    "content": "/**\n * validateRequest.js\n * @description :: exports methods for validating parameters of request body using joi validation.\n */\n\n/**\n * @description : validate request body parameter with joi.\n * @param {object} payload : body from request.\n * @param {object} schemaKeys : model wise schema keys. ex. user validation.\n * @returns : returns validation with message {isValid, message}\n */\nexports.validateParamsWithJoi = (payload, schemaKeys) => {\n  const { error } = schemaKeys.validate(payload, { abortEarly: false });\n  if (error) {\n    const message = error.details.map((el) => el.message).join('\\n');\n    return {\n      isValid: false,\n      message,\n    };\n  }\n  return { isValid: true };\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/utils/validation/validateSchema.js.ejs",
    "content": "/**\n * <%-MODEL_NAME%>Validation.js\n * @description :: validate each post and put request as per <%-MODEL_NAME%> model\n */\n\nconst joi = require(\"joi\");\n<%_if(ENUM_VALIDATION){_%>\n<%_for(let enumIndex of ENUM_VALIDATION){_%>\nconst <%-enumIndex%>Default=require('../../constants/<%-enumIndex%>');    \n<%_}_%>       \n<%_}_%>    \n<%_if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){_%>\nconst {USER_ROLE} = require(\"../../constants/authConstant\");\nconst {convertObjectToEnum} = require(\"../common\");   \n<%_}_%>\n<%_ if(typeof VARIABLES !== \"undefined\") {\nfor(let i=0;i< VARIABLES.length; i++) {_%>\n<%-VARIABLES[i]%>\n<%_ } } _%>\n\n/** validation keys and properties of <%-MODEL_NAME%> */\nexports.schemaKeys = joi.object(<%-VALIDATION_KEY%>).unknown(true);\n\n/** validation keys and properties of <%-MODEL_NAME%> for updation */\nexports.updateSchemaKeys = joi.object(<%-UPDATE_VALIDATION_KEY%>).unknown(true);\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/views/emailTemplate.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <!-- message -->\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear ,</b>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/views/index.ejs",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n  <link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\" rel=\"stylesheet\">\n  <link rel=\"icon\" type=\"image/png\" href=\"https://dxuoui1db8w1y.cloudfront.net/index.png?o=g\">\n  <title>welcome to node.js</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n\n    body {\n      font-family: 'Courier Prime', monospace;\n      height: 100vh;\n      background-color: #181818;\n      display: flex;\n    }\n    .sidebar{\n      height: 100vh;\n    }\n    .main-section{\n      padding: 100px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    h1{\n      color: #ffffff;\n      font-weight: 100;\n      font-size: 4vw;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <img class=\"sidebar\" src=\"https://dxuoui1db8w1y.cloudfront.net/sidebar.jpg?o=g\" alt=\"sidebar\">\n  </div>\n  <div class=\"main-section\">\n    <div>\n      <div style=\"display: flex; justify-content: space-between; margin-bottom: 50px;\">\n        <img src=\"https://dxuoui1db8w1y.cloudfront.net/dhiwise.png?o=g\" alt=\"dhiwise\" style=\"width: 130px;\">\n      </div>\n    <h1><br>Welcome to <span style=\"color: #3E863D;\">Node.Js</span><br>application </h1>\n  </div>\n  </div>\n</body>\n\n</html>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/views/resetPassword.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <%-message%>\n                    </div>\n                </div>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/views/resetPasswordLink.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        Reset Password Link\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,<%-message%></b>\n                </p>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    <a href=\"<%-link%>\"><%-linkText%></a>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvc/views/sendOTP.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        OTP\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,</b>\n                </p>\n            </td>\n        </tr>\n        <% if(otp) { %>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    Your OTP code is <strong> <%- otp %></strong>\n                </p>\n            </td>\n        </tr>\n        <% } %>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    browser: true,\n    es2021: true,\n  },\n  parserOptions: {\n    ecmaVersion: 12,\n    sourceType: 'module',\n  },\n  rules: {\n    semi: ['error', 'always'],\n    indent: ['error', 2],\n    'no-irregular-whitespace': ['error', {\n      skipStrings: true,\n      skipComments: true,\n      skipRegExps: true,\n      skipTemplates: true,\n    }],\n    'multiline-comment-style': ['error', 'starred-block'],\n    'object-property-newline': ['error', {\n      allowAllPropertiesOnSameLine: false,\n      allowMultiplePropertiesPerLine: false,\n    }],\n    'object-curly-newline': ['error', {\n      minProperties: 2,\n      multiline: true,\n    }],\n    'no-multiple-empty-lines': ['error', {\n      max: 1,\n      maxEOF: 0,\n    }],\n    'no-param-reassign': 'off',\n    'no-underscore-dangle': 'off',\n    'class-methods-use-this': 'off',\n    'max-len': [2, {\n      code: 1000,\n      ignorePattern: '^import .*',\n    }],\n    'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],\n    'space-infix-ops': ['error', { int32Hint: false }],\n    'space-before-function-paren': ['error', {\n      anonymous: 'always',\n      named: 'always',\n      asyncArrow: 'always',\n    }],\n    'keyword-spacing': ['error', {\n      before: true,\n      after: true,\n    }],\n    'object-curly-spacing': ['error', 'always'],\n    quotes: ['error', 'single', { allowTemplateLiterals: true }],\n  },\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/.gitignore",
    "content": "node_modules\n.dhiwise"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/README.ejs",
    "content": "# NodeJS, Sequelize, Express Project in MVC Architecture\n\n**supported version of nodejs > 12**,\n**Supported version of sequelize-6.6.5**\n\n- This is a Web application, developed using MVC pattern with Node.js, ExpressJS, and Sequelize ORM. \n- Basic boilerplate for web applications, built on Express.js using the Model–View–Controller architectural pattern.\n- SQL database is used for data storage, with object modeling provided by Sequelize.\n- Supported SQL Databases are - MSSQL, MySql, PostgreSQL\n\n# Initial\n- Configure a basic server in app.js.\n- Organize the routes with Express Router.\n- Use the mainRoutes in app as middleware.\n- Set a final use after the routes, to display a 404 message for the unhandled requests.\n1. Install needed Node.js modules:\n     ```$ npm install```\n2. execute server:\n     ```$ npm start```\n\t<%_if(IS_AUTH){_%>\n3. When the app will run successfully,\n<%_if(ROLE_WISE_CREDENTIALS){_%>\n<%_for (let i in ROLE_WISE_CREDENTIALS){_%>\n\n\t\t- One user with <%-i%> role,\n\t\t# Default <%-i%> credentials\n\t\t**username** : <%-ROLE_WISE_CREDENTIALS[i][USER_FIELD]%>\n\t\t**password** : <%-ROLE_WISE_CREDENTIALS[i][PASSWORD_FIELD]%>\n\t\t\n<%_}_%> \n<%_}_%>\t \n<%_}_%>\n\t \n# Default folder structure:\n\n\t--project_folder\n\t\t--config\n\t\t--controller\n\t\t--logs\n\t\t--middleware\n\t\t--model\n\t\t--postman\n\t\t--public\n\t\t--routes\n\t\t--services\n\t\t--utils\n\t\t--views\n\t\t--app.js\n\t\t--.env\n\t\t--.gitignore\n\t\t--.eslintrc.js\n# app.js\n- entry point of application.\n# config\n- passport strategy for all platforms.\n- based on Auth Model - authentication files has been generated.\n- Auth constant File that has authentication configuration constants\n- Used .env file and configure the db connection string to use in the project.\n# controller\n- includes controller files per model\n- Controllers are separated per Platform\n\n     \t  -controller\n     \t        -admin\n     \t          -modelController.js\n     \t        -device\n     \t          -modelController.js\n     \t        -desktop\n     \t          -modelController.js\n     \t        -client\n     \t          -modelController.js\n# logs\n- Log file\n# middleware\n- User authentication Middleware based on Roles and permission for Routes' access\n- Custom Policy files\n# model\n- Sequelize Models , as per user defined schema \n# postman\n- Postman collection File for Platform based APIs that are generated.\n- Import this JSON in Postman to test the APIs.\n# public \n- You can add static files like like images, pdf etc.\n# routes\n- based on platform,separate folder is generated,within those folders model wise route files are that has model crud APIs' routes.\n- index.js file, main file which includes all platform routes.\n- added index files in app.js to access the routes of the application.\n# services\n     \t-auth.js\n       \t\t-Logic for JWT Tokenization for user to login into Application using username and password along with otp if required.\n# utils\n\t     -validation\n     \t\t-joi validations files.\n     \t\t-files are separated by models.\n     \t -common.js\n       \t\t-converted object to enum function.\n     \t -dbService.js\n       \t\t -common Database functionalities\n     \t  \t -findAll(find all records)\n     \t  \t -updateByPk(update single record in db by primary key)\n     \t  \t -deleteByPk(delete single record in db)\n     \t  \t -createOne(Insert single record in db)\n     \t  \t -findOne(find single record by query)\n     \t  \t -softDeleteByPk\n     \t  \t -updateMany(update records that matches query)\n             -deleteMany(delete record that matches query)\n     \t  \t -createMany(insert multiple records in db)\n     \t  \t -count (count records that matches query)\n     \t -messages.js\n  \t\t     -static messages that are sent with response - contains status and Data\n\t      -responseCode.js\n  \t\t     -codes for responses\n\t      -validateRequest.js\n  \t\t     -validate schema based on joi validation\n# views\n- add ejs files"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/__test__/auth.test.js.ejs",
    "content": "/**\n * auth.test.js\n * @description :: contains test cases of APIs for authentication module.\n */\n \nconst dotenv = require('dotenv');\ndotenv.config();\nprocess.env.NODE_ENV = 'test';\nconst request = require('supertest');\nconst db = require('../../config/dbConnection')\nconst app = require('../../app.js');\nconst authConstant=require('../../constants/authConstant');\nconst routes = require('../../routes');\napp.use(routes);\n\nbeforeAll(async function () {\n  await db.sync({})\n})\n\nafterAll(async function(){\n  await db.dropAllSchemas()\n  await db.drop()\n  await db.close()\n})\n\ndescribe('POST /register -> if email and username is given', () => {\n  test('should register a <%-AUTH_MODEL%>', async () => {\n    let registeredUser = await request(app)\n      .post('/<%-PLATFORM%>/auth/register')\n      <%_var finalStr=new String(); \n      FAKE_DATA_OF_AUTH.role=`@@authConstant.USER_ROLE.${ROLE}@@`;\n        finalStr=JSON.stringify(FAKE_DATA_OF_AUTH); \n        finalStr=finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\" ); \n      _%>\n      .send(<%-finalStr%>);\n    expect(registeredUser.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(registeredUser.body.status).toBe('SUCCESS');\n    expect(registeredUser.body.data).toMatchObject({\n      id: expect.any(Number)\n    });\n    expect(registeredUser.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username and password is correct', () => {\n  test('should return <%-AUTH_MODEL%> with authentication token', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n      expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n      expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n      expect(<%-AUTH_MODEL%>.body.data).toMatchObject({\n          id: expect.any(Number),\n          token: expect.any(String)\n      }); \n      expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /login -> if username is incorrect', () => {\n  test('should return unauthorized status and <%-AUTH_MODEL%> not exists', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: 'wrong.username',\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if password is incorrect', () => {\n  test('should return unauthorized status and incorrect password', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: 'wrong@password'\n        }\n      );\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /login -> if username or password is empty string or has not passed in body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send({});\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.body.message).toBe('Insufficient parameters');\n    expect(user.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /forgot-password -> if email has not passed from request body', () => {\n  test('should return bad request status and insufficient parameters', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ email: '' });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('BAD_REQUEST');\n    expect(user.body.message).toBe('Insufficient parameters');\n    expect(user.statusCode).toBe(400);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is not available in database', () => {\n  test('should return record not found status', async () => {\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': 'unavailable.email@hotmail.com', });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('RECORD_NOT_FOUND');\n    expect(user.body.message).toBe('Record not found with specified criteria.');\n    expect(user.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /forgot-password -> if email passed from request body is valid and OTP sent successfully', () => {\n  test('should return success message', async () => {\n    const expectedOutputMessages = [\n      'otp successfully send.',\n      'otp successfully send to your email.',\n      'otp successfully send to your mobile number.'\n    ];\n    let user = await request(app)\n      .post('/<%-PLATFORM%>/auth/forgot-password')\n      .send({ 'email': <%_if(FAKE_DATA_OF_AUTH['email'] !== undefined) {_%><%=FAKE_DATA_OF_AUTH['email']%><%_}else{_%>'valid.mail@hotmail.com'<%_}_%>_%>, });\n\n    expect(user.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(user.body.status).toBe('SUCCESS');\n    expect(expectedOutputMessages).toContain(user.body.message);\n    expect(user.statusCode).toBe(200);\n  });\n});\n\ndescribe('POST /validate-otp -> otp is sent in request body and OTP is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .post('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'otp': foundUser.body.data.resetPasswordLink.code, }).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('POST /validate-otp -> if OTP is incorrect or OTP has expired', () => {\n  test('should return invalid OTP', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({ 'otp': '12334' });\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid OTP');\n  });\n});\n\ndescribe('POST /validate-otp -> if request body is empty or otp has not been sent in body', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .post('/<%-PLATFORM%>/auth/validate-otp')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('PUT /reset-password -> code is sent in request body and code is correct', () => {\n  test('should return success', () => {\n    return request(app)\n      .post('/<%-PLATFORM%>/auth/login')\n      .send(\n        {\n          username: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.username[0]]%>,\n          password: <%=FAKE_DATA_OF_AUTH[USER_LOGIN_WITH.password]%>\n        }).then(login => () => {\n          return request(app)\n            <%_if(PLATFORM.toLowerCase() === 'admin'){_%>\n            .get(`/<%-PLATFORM%>/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}else{_%>\n            .get(`/<%-PLATFORM%>/api/v1/<%-AUTH_MODEL%>/${login.body.data.id}`)\n            <%_}_%>\n            .set({\n              Accept: 'application/json',\n              Authorization: `Bearer ${login.body.data.token}`\n            }).then(foundUser => {\n              return request(app)\n                .put('/<%-PLATFORM%>/auth/validate-otp')\n                .send({ 'code': foundUser.body.data.resetPasswordLink.code, 'newPassword':'newPassword'}).then(<%-AUTH_MODEL%> => {\n                  expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n                  expect(<%-AUTH_MODEL%>.body.status).toBe('SUCCESS');\n                  expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n                });\n            })\n        });\n  });\n});\n\ndescribe('PUT /reset-password -> if request body is empty or code/newPassword is not given', () => {\n  test('should return insufficient parameter', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM%>/auth/reset-password')\n      .send({});\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('BAD_REQUEST');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(400);\n  });\n});\n\ndescribe('PUT /reset-password -> if code is invalid', () => {\n  test('should return invalid code', async () => {\n    let <%-AUTH_MODEL%> = await request(app)\n      .put('/<%-PLATFORM%>/auth/reset-password')\n      .send({\n        'code': '123',\n        'newPassword': 'testPassword'\n      });\n\n    expect(<%-AUTH_MODEL%>.headers['content-type']).toEqual('application/json; charset=utf-8');\n    expect(<%-AUTH_MODEL%>.body.status).toBe('FAILURE');\n    expect(<%-AUTH_MODEL%>.body.message).toBe('Invalid Code');\n    expect(<%-AUTH_MODEL%>.statusCode).toBe(200);\n  });\n});\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/app.js.ejs",
    "content": "/**\n * app.js\n * Use `app.js` to run your app.\n * To start the server, run: `node app.js`.\n */\n\nconst express = require('express');\nconst cors = require('cors');\nconst path = require('path');\nconst dotenv = require('dotenv');\ndotenv.config();\nglobal.__basedir = __dirname;\n<%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\nconst listEndpoints = require('express-list-endpoints')\n<%_}_%>\n<%_ if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){ _%>\nconst passport = require(\"passport\");\nconst seeder = require('./seeders');\n<%_ } _%>\n\n<%_ if(SHOULD_ADD_ROLE_PERMISSION || (typeof SEEDER !== \"undefined\" && SEEDER)) { _%>\nconst models = require(\"./model\");\n<%_ } _%>\n<% Object.keys(modules).sort().forEach(function (variable) { -%>\nlet <%- variable %> = require('<%- modules[variable] %>');\n<% }); -%>\n<% Object.keys(localModules).sort().forEach(function (variable) { -%>\nconst <%- variable %> = require('<%- localModules[variable] %>');\n<% }); -%>\n\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\nconst {<%-platform.toLowerCase()%>PassportStrategy} = require(\"./config/<%-platform%>PassportStrategy\");\n<%_ } _%>\n<%_ } _%>\n\nconst app = express();\nconst corsOptions = {\n    origin: process.env.ALLOW_ORIGIN,\n}\napp.use(cors(corsOptions));\n\n//template engine\napp.set('view engine', 'ejs'); \napp.set('views', path.join(__dirname, 'views'));\napp.use(require('./utils/response/responseHandler'));\n\n<% uses.forEach(function (use) { -%>\napp.use(<%- use %>);\n<% }); -%>\n<%_ if(typeof PLATFORM !== \"undefined\" && PLATFORM){ _%>\n<%_ for(const platform of PLATFORM){ _%>\n<%-platform.toLowerCase()%>PassportStrategy(passport);\n<%_ } _%>\n<%_ } _%>\n\n<% mounts.forEach(function (mount) { -%>\napp.use(<%= mount.path %>, <%- mount.code %>);\n<% }); -%>\n\napp.get('/', (req, res) => {\n  res.render('index');\n})\n\nif (process.env.NODE_ENV !== 'test' ) {\n    <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    models.sequelize.sync({alter:true}).then(()=>{\n        <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes \n        const routes =  require(\"./routes\");\n        app.use(routes)\n        <%_ } _%>\n        const allRegisterRoutes = listEndpoints(app);\n        seeder(allRegisterRoutes).then(()=>{console.log(\"Seeding done.\")});\n    })\n    <%_}else if(typeof SEEDER !== \"undefined\" && SEEDER){_%>\n    models.sequelize.sync({}).then(()=>{\n        <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes \n        const routes =  require(\"./routes\");\n        app.use(routes)\n        <%_ } _%>\n        seeder().then(()=>{console.log(\"Seeding done.\")});\n    });\n    <%_} else {_%>\n    <%_ if(!NO_PLATFORM && typeof IS_ROUTE!==\"undefined\" && IS_ROUTE) { _%>\n        //all routes \n        const routes =  require(\"./routes\");\n        models.sequelize.sync({}).then(()=>{\n            app.use(routes)\n        });\n    <%_ } _%>\n    <%_}_%>\n    app.listen(process.env.PORT,()=>{\n        console.log(`your application is running on ${process.env.PORT}`)\n    });\n}else{\n    module.exports = app\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/config/constant.js.ejs",
    "content": "/**\n * authConstant.js\n * @description :: constants used in authentication\n */\n\nconst JWT={\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>_SECRET:\"myjwt<%- plt.toLowerCase() %>secret\",\n<%_ }); _%>\n    EXPIRES_IN: <%-TOKEN_EXPIRE_TIME%>\n}\n\nconst USER_ROLE ={   \n    <%_ USER_ROLE.forEach(function (role,index) { _%>\n        <%- role %>:<%- index+=1 %>,\n    <%_ }); _%>\n}\n\nconst PLATFORM = {\n<%_ PLATFORM.forEach(function (plt,index) { _%>\n    <%- plt.toUpperCase() %>:<%- index+1 %>,\n<%_ }); _%>\n}\n\nlet LOGIN_ACCESS ={\n<% Object.keys(LOGIN_ACCESS).map(function (key,index) { -%>\n    [USER_ROLE.<%- key %>]:<%_ let Arr=[]; LOGIN_ACCESS[key].forEach(function(plt,index){ _%>\n    <%_Arr.push(`PLATFORM.${plt.toUpperCase()}`);_%>\n<%_ }) _%><%-JSON.stringify(Arr).toString().replace(/\"/g, \"\");%>,        \n<% }); -%>\n}\n\nconst DEFAULT_ROLE= 1\n\n<%_if(LOGIN_RETRY_LIMIT){_%>\nconst MAX_LOGIN_RETRY_LIMIT = <%=LOGIN_RETRY_LIMIT.max%>;\nconst LOGIN_REACTIVE_TIME = <%=LOGIN_RETRY_LIMIT.reActiveTime%>;   \n<%_}_%>    \n\n<%_if(RESET_PASSWORD){_%>\nconst FORGOT_PASSWORD_WITH = <%-RESET_PASSWORD%>\n<%_}_%>\n<%_if(DEVICE_ALLOWED_REQUIRED){_%>\nconst NO_OF_DEVICE_ALLOWED = <%-NO_OF_DEVICE%>\n<%_}_%>\n<%_ let customRoutes=[]_%>\n<%_if(CUSTOM_ROUTES){_%>\n<%_ for(let platform in CUSTOM_ROUTES){ \n    customRoutes.push(`${platform.toUpperCase()}_CUSTOM_ROUTES`)\n_%>\nconst <%-platform.toUpperCase()%>_CUSTOM_ROUTES = <%=CUSTOM_ROUTES[platform]%>   \n<%_ } _%>\n<%_}_%>\n\nmodule.exports = {\n    JWT,\n    USER_ROLE,\n    DEFAULT_ROLE,\n    PLATFORM,\n    <%_if(LOGIN_RETRY_LIMIT){_%>\n    MAX_LOGIN_RETRY_LIMIT,\n    LOGIN_REACTIVE_TIME,\n    <%_}_%>\n    <%_if(RESET_PASSWORD){_%>\n    FORGOT_PASSWORD_WITH,\n    <%_}_%>\n    <%_if(DEVICE_ALLOWED_REQUIRED){_%>\n    NO_OF_DEVICE_ALLOWED,\n    <%_}_%>\n    LOGIN_ACCESS,\n    <%_ if(CUSTOM_ROUTES){ _%>\n        <%-customRoutes.join()%>\n    <%_ } _%>\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/config/db.js.ejs",
    "content": "/**\n * db.js\n * @description :: exports values used to make connection with SQL database\n */\n\nif(process.env.NODE_ENV !== 'test'){\n    module.exports = {\n        HOST: process.env.HOST,\n        USER: process.env.DATABASE_USERNAME,\n        PASSWORD: process.env.DATABASE_PASSWORD,\n        DB: process.env.DATABASE_NAME,\n        dialect: <%=ADAPTER%>,\n        port: process.env.DB_PORT,\n    }\n}else{\n    module.exports = {\n        HOST: process.env.TEST_HOST,\n        USER: process.env.TEST_DATABASE_USERNAME,\n        PASSWORD: process.env.TEST_DATABASE_PASSWORD,\n        DB: process.env.TEST_DATABASE_NAME,\n        dialect: <%=ADAPTER%>,\n        port: process.env.TEST_DB_PORT,\n    }\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/config/dbConnection.js.ejs",
    "content": "/**\n * dbConnection.js\n * @description :: database connection using sequelize\n */\nconst { Sequelize, DataTypes } = require('sequelize');\nconst dbConfig = require('./db');\n\nconst sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {\n  host: dbConfig.HOST,\n  dialect: dbConfig.dialect,\n  port: dbConfig.port,\n});\nmodule.exports = sequelize;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/config/passport.js.ejs",
    "content": "/**\n * <%- STRATEGY %>PassportStrategy.js\n */\n\nconst { Strategy, ExtractJwt } = require(\"passport-jwt\")\nconst { JWT } = require(\"../constants/authConstant\")\nconst model = require(\"../model/index\");\nconst dbService = require('../utils/dbService');\n\n/**\n * @description : exports authentication strategy for <%-STRATEGY.toLowerCase()%> using passport.js\n * @params {object} passport : passport object for authentication\n * @return {callback} : returns callback to be used in middleware\n */\nmodule.exports = {\n    <%- STRATEGY.toLowerCase() %>PassportStrategy: passport => {\n        const options = {};\n        options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();\n        options.secretOrKey = JWT.<%- STRATEGY.toUpperCase() %>_SECRET;\n        passport.use('<%- STRATEGY.toLowerCase() %>-rule',\n            new Strategy(options, (payload, done) => {\n                dbService.findOne(model.<%-MODEL%>,{id: payload.id}).then((user)=>{\n                    if (user) {\n                      return done(null, { ...user.toJSON() });\n                    }\n                    return done('No User Found', {});\n                  }).catch(err => done(err, false))\n            })\n        );\n    }\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/config/requestConstant.js.ejs",
    "content": "/**\n * <%-FILE_NAME%>.js\n */\n\nmodule.exports=<%=JSON.parse(CONSTANTS)%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/controllers/authController.js.ejs",
    "content": "/**\n * authController.js\n * @description :: exports authentication methods\n*/\n\nconst authService =  require(\"../../services/auth\")\nconst model = require(\"../../model/index\");\nconst dbService = require(\"../../utils/dbService\");\nconst dayjs = require(\"dayjs\");\nconst <%-USER_MODEL %>SchemaKey = require(\"../../utils/validation/<%-USER_MODEL%>Validation\");\nconst validation = require(\"../../utils/validateRequest\");\nconst authConstant = require('../../constants/authConstant');\nconst {Op} = require('sequelize');\n<%_if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\nconst emailService = require(\"../../services/email/emailService\")\n<%_}else if(NOTIFICATION_TYPE===\"SMS\"){_%>\nconst sendSMS = require(\"../../services/sms/smsService\");\nconst ejs = require(\"ejs\")\n<%_}_%>\nconst { uniqueValidation } = require('../../utils/common');\n\n/**\n* @description : user registration \n* @param {object} req : request for register\n* @param {object} res : response for register\n* @return {object} : response for register {status, message, data}\n*/\nconst register = async(req, res) => {\n    try {\n        let validateRequest = validation.validateParamsWithJoi(\n            req.body,\n            <%-USER_MODEL %>SchemaKey.schemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message :  `Invalid values in parameters, ${validateRequest.message}`});\n        }\n        let unique = await uniqueValidation(model.<%-USER_MODEL%>,req.body);   \n        if (!unique){ \n            return res.validationError({message:'User Registration Failed, Duplicate Data found'});\n        }     \n        const result = await dbService.createOne(model.<%-USER_MODEL%>,{...req.body});\n        <%_if(NOTIFICATION_TYPE===\"SMS\"){_%>\n        // send sms to user for successfully registered.\n        let renderData = {\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n            <%_}_%>\n            <%_}else{_%>\n            ...result\n            <%_}_%>\n        }\n        const msg = await ejs.renderFile(`${__basedir}/views/<%-REGISTER_TEMPLATE_NAME%>/html.ejs`, renderData);\n        let smsObj = {\n            to:result.<%-MOBILE_FIELD%>,\n            message:msg\n        }\n        await sendSMS(smsObj);\n        <%_}else if(NOTIFICATION_TYPE===\"EMAIL\"){_%>\n        // send email to user for successfully registered.\n        let mailObj = {\n            subject: \"Register User\",\n            to: result.<%-EMAIL_FIELD%>,\n            <%_if(typeof REGISTER_TEMPLATE_ATTRIBUTE === \"object\"){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:{\n                <%_for(let i in REGISTER_TEMPLATE_ATTRIBUTE){_%>\n                <%-i%>:result.<%-REGISTER_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                <%_}_%>\n            }\n            <%_}else if(!REGISTER_TEMPLATE_ATTRIBUTE){_%>\n            template: \"/views/<%-REGISTER_TEMPLATE_NAME%>\",\n            data:result\n            <%_}_%>\n        };\n        await emailService.sendEmail(mailObj);\n        <%_}_%>\n        return res.success({data:result});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }  \n}\n\n/**\n * @description : send email or sms to user with OTP on forgot password\n * @param {object} req : request for forgotPassword\n * @param {object} res : response for forgotPassword\n * @return {object} : response for forgotPassword {status, message, data}\n */\nconst forgotPassword = async (req, res) => {\n    const params = req.body;\n    try {\n        if (!params.email) {\n            return res.badRequest();\n        }\n        let where = {<%-EMAIL_FIELD%>: params.email};\n        params.email = params.email.toString().toLowerCase();\n        let isUser = await dbService.findOne(model.<%-USER_MODEL%>,where);\n        if (isUser) {\n            let {resultOfEmail,resultOfSMS} = await authService.sendResetPasswordNotification(isUser);\n            if(resultOfEmail && resultOfSMS){\n                return res.success({message:\"otp successfully send.\"});\n            }else if(resultOfEmail && !resultOfSMS) {\n                return res.success({message:\"otp successfully send to your email.\"});\n            } else if (!resultOfEmail && resultOfSMS) { \n                return res.success({message:\"otp successfully send to your mobile number.\"});\n            }else{\n                return res.success({message:\"otp can not be sent due to some issue try again later\"});\n            }\n        } else {\n            return res.recordNotFound();\n        }\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n\n/**\n * @description : validate OTP\n * @param {object} req : request for validateResetPasswordOtp\n * @param {object} res : response for validateResetPasswordOtp\n * @return {object} : response for validateResetPasswordOtp  {status, message, data}\n */ \nconst validateResetPasswordOtp = async (req, res) => {\n    const params = req.body;\n    try {\n        if (!params || !params.otp) {\n            return res.badRequest();\n        }\n        let isUser = await dbService.findOne(model.userAuthSettings, { resetPasswordCode: params.otp });\n        if (!isUser || !isUser.resetPasswordCode) {\n            return res.failure({message:\"Invalid OTP\"});\n        }\n        // link expire\n        if (dayjs(new Date()).isAfter(dayjs(isUser.expiredTimeOfResetPasswordCode))) {\n            return res.failure({message:\"Your reset password link is expired or invalid\"});\n        }\n        return res.success({message:'Otp verified'});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n\n/**\n * @description : reset password with code and new password\n * @param {object} req : request for resetPassword\n * @param {object} res : response for resetPassword\n * @return {object} : response for resetPassword {status, message, data}\n */\nconst resetPassword = async (req, res) => {\n    const params = req.body;\n    try {\n        if (!params.code || !params.newPassword) {\n            return res.badRequest();\n        }\n        let userAuth = await dbService.findOne(model.userAuthSettings, { resetPasswordCode: params.code });\n        if (userAuth && userAuth.expiredTimeOfResetPasswordCode) {\n            if (dayjs(new Date()).isAfter(dayjs(userAuth.expiredTimeOfResetPasswordCode))) {// link expire\n                return res.failure({message:\"Your reset password link is expired or invalid\"});\n            }\n        } else {\n            // invalid code\n            return res.failure({message:\"Invalid Code\"});\n        }\n        let response = await authService.resetPassword(userAuth.userId, params.newPassword);\n        if(response && !response.flag){\n            return res.success({message:response.data});\n        }\n        return res.failure({message:response.data});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n\n/**\n * @description : login with username and password\n * @param {object} req : request for login \n * @param {object} res : response for login\n * @return {object} : response for login {status, message, data}\n */\nconst login = async(req,res)=>{\n    try {\n        let {username,password} = req.body;\n        if(!username || !password){\n            return res.badRequest();\n        }\n        <%_if(ROLE_PERMISSION){_%>\n        let roleAccess = false;\n        if (req.body.includeRoleAccess){\n            roleAccess = req.body.includeRoleAccess;\n        }\n        let result = await authService.loginUser(username, password, authConstant.PLATFORM.<%-PLATFORM.toUpperCase()%>, roleAccess);\n        <%_} else {_%>\n        let result = await authService.loginUser(username,password,authConstant.PLATFORM.<%-PLATFORM.toUpperCase()%>); \n        <%_}_%>\n        if(!result.flag){\n            return res.success({data:result.data,message:result.message});\n        }\n        return res.badRequest({message:result.data});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n\n/**\n * @description : logout user\n * @param {object} req : request for logout\n * @param {object} res : response for logout\n * @return {object} : response for logout {status, message, data}\n */\nconst logout = async (req, res) => {\n    try {\n        let userTokens = await dbService.findOne(model.userTokens, { token: (req.headers.authorization).replace('Bearer ', ''),userId:req.user.id });\n        userTokens.isTokenExpired = true;\n        let id = userTokens.id;\n        delete userTokens.id;\n        await dbService.updateByPk(model.userTokens,id, userTokens.toJSON());\n        return res.success({message:'Logged Out Successfully'});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n\nmodule.exports = {\n    register,\n    forgotPassword,\n    validateResetPasswordOtp,\n    resetPassword,\n    login,\n    logout\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/controllers/controller.js.ejs",
    "content": "/**\n* <%-DB_MODEL%>Controller.js\n* @description :: exports action methods for <%-DB_MODEL%>.\n*/\n\nconst {Op} = require('sequelize')\nconst <%- DB_MODEL_FC %> = require(\"../../model/<%-DB_MODEL%>\")\nconst <%-DB_MODEL %>SchemaKey = require(\"../../utils/validation/<%-DB_MODEL%>Validation\");\nconst validation = require(\"../../utils/validateRequest\");\nconst dbService = require(\"../../utils/dbService\");\n<%_ if(IS_AUTH){ _%>\nconst auth = require(\"../../services/auth\");\n<%_ } _%>\nconst models = require(\"../../model\");\n<%_ if(DELETE_DEPENDENT_MODEL){ _%>\nconst deleteDependentService = require(\"../../utils/deleteDependent\");\n<%_ } _%>\n<%_ var methods = [] _%>\n<%_\nif(typeof(UNIQ_TASK_MODELS)!== 'undefined'){\nlet models = UNIQ_TASK_MODELS\nfor(let model of models){\n    if(model!==DB_MODEL){\n        model = model.charAt(0).toUpperCase() + model.slice(1);\n_%>\nconst <%-model%> = require(\"../../model/<%-model%>\")\n<%_ } } } _%>\n<%_if(IS_CQ){_%>\nconst customQueryService = require(\"../../services/customQueryService\")\n<%_}_%>\n<%_for(let i=0;i< SUPPORT_API.length;i++){ _%>\n<%_ if(SUPPORT_API[i].method==\"create\") {_%>\n    <%_ methods.push('add'+DB_MODEL_FC) _%> \n/**\n* @description : create record of <%-DB_MODEL_FC%> in SQL table.\n* @param {object} req : request including body for creating record.\n* @param {object} res : response of created record.\n* @return {object} : created <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst add<%-DB_MODEL_FC%> = async(req, res) => {\n    try {\n        let dataToCreate = {...req.body || {} };\n        delete dataToCreate[\"addedBy\"]\n        delete dataToCreate[\"updatedBy\"]\n        let validateRequest = validation.validateParamsWithJoi(\n            dataToCreate,\n            <%-DB_MODEL %>SchemaKey.schemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message : `Invalid values in parameters, ${validateRequest.message}`});\n        }   \n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        dataToCreate.<%-SUPPORT_API[i].addedBy%> = req.user.id.toString();\n        <%_ } _%>\n        let result = await dbService.createOne(<%-DB_MODEL_FC %>,dataToCreate);\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n    <%_ methods.push('bulkInsert'+DB_MODEL_FC) _%>\n/**\n* @description : create multiple records of <%-DB_MODEL_FC%> in SQL table.\n* @param {object} req : request including body for creating records.\n* @param {object} res : response of created records.\n* @return {object} : created <%-DB_MODEL_FC%>s. {status, message, data}\n*/\nconst bulkInsert<%-DB_MODEL_FC %> = async(req, res)=>{\n    try{\n        let dataToCreate = req.body && req.body.data ? [...req.body.data] : [];\n        dataToCreate = dataToCreate.map(item=>{\n            delete item.addedBy\n            delete item.updatedBy\n        <%_if(SUPPORT_API[i].isLogin){_%>\n            item.<%-SUPPORT_API[i].addedBy%> = req.user.id\n        <%_}_%>\n            return item;\n        });        \n        let result =await dbService.createMany(<%-DB_MODEL_FC %>,dataToCreate);\n        return res.success({ data:result });  \n    }catch(error){\n        return res.internalServerError({ message : error.message });\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"update\") {_%>\n    <%_methods.push('update'+DB_MODEL_FC) _%>\n/**\n* @description : update record of <%-DB_MODEL_FC%> with data by id.\n* @param {object} req : request including id in request params and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>.\n* @return {object} : updated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst update<%-DB_MODEL_FC%> = async(req, res) => {\n    try {\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let dataToUpdate = { ...req.body || {} };\n        let query = { id: req.params.id};\n        delete dataToUpdate.addedBy\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        dataToUpdate.updatedBy=req.user.id\n        <%_ } _%>\n        let validateRequest = validation.validateParamsWithJoi(\n            dataToUpdate,\n            <%-DB_MODEL%>SchemaKey.updateSchemaKeys\n        );\n        if (!validateRequest.isValid) {\n            return res.validationError({message :  `Invalid values in parameters, ${validateRequest.message}`});\n        }\n        <%_ \n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){\n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n            for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>   \n                query = { ...query,...<%=JSON.parse(element.filter)%>                   \n            <%_}}\n        }}\n        _%> \n        let result = await dbService.updateMany(<%-DB_MODEL_FC%>,query,dataToUpdate);\n        if(!result){\n            return res.recordNotFound();\n        }\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message});\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"bulkUpdate\") {_%>\n    <%_methods.push('bulkUpdate'+DB_MODEL_FC) _%>\n/**\n* @description : update multiple records of <%-DB_MODEL_FC%> with data by id.\n* @param {object} req : request including id in request params and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>s.\n* @return {object} : updated <%-DB_MODEL_FC%>s. {status, message, data}\n*/\nconst bulkUpdate<%-DB_MODEL_FC%>=async(req, res)=>{\n    try {\n        let query = { ...req.body.filter || {} };\n        let dataToUpdate = { ...req.body.data || {} };\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        delete dataToUpdate.addedBy;\n        dataToUpdate.updatedBy=req.user.id;\n        <%_ } _%>\n        <%_ \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>   \n                    query = { ...query ,...<%=JSON.parse(element.filter)%> }; \n                <%_}}\n            }}\n        _%> \n        let result = await dbService.updateMany(<%-DB_MODEL_FC%>,query,dataToUpdate);\n        if(!result){\n            return res.recordNotFound()\n        }\n        return res.success({data:result});\n    } catch(error){\n        return res.internalServerError({ message : error.message }); \n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"partialUpdate\") {_%>\n    <%_methods.push('partialUpdate'+DB_MODEL_FC) _%>\n/**\n* @description : partially update record of <%-DB_MODEL_FC%> with data by id;\n* @param {object} req : request including id in request params and data in request body.\n* @param {object} res : response of updated <%-DB_MODEL_FC%>.\n* @return {object} : updated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst partialUpdate<%-DB_MODEL_FC%> = async (req, res) => {\n    try {\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let dataToUpdate = { ...req.body || {} };\n        let query = { id: req.params.id};\n        delete dataToUpdate.addedBy\n        <%_ if(SUPPORT_API[i].isLogin){ _%>\n        dataToUpdate.updatedBy=req.user.id\n        <%_ } _%>\n        <%_ \n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){\n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n            for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>   \n                query = { ...query,...<%=JSON.parse(element.filter)%>                   \n            <%_}}\n        }}\n        _%> \n        let result = await dbService.updateMany(<%-DB_MODEL_FC%>,query,dataToUpdate);\n        if(!result){\n            return res.recordNotFound();\n        }\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        result = (({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}) => ({<%_SUPPORT_API[i].fields.forEach((item,index)=>{_%><%-item%><%_if(SUPPORT_API[i].fields.length-1 !== index){_%>,<%_}_%><%_})_%>}))(result);\n        <%_}_%>\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message});\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\") {_%>\n    <%_methods.push('findAll'+DB_MODEL_FC) _%>\n/**\n* @description : find all records of <%-DB_MODEL_FC%> from table based on query and options.\n* @param {object} req : request including option and query. {query, options : {page, limit, includes}, isCountOnly}\n* @param {object} res : response contains data found from table.\n* @return {object} : found <%-DB_MODEL_FC%>(s). {status, message, data}\n*/\nconst findAll<%-DB_MODEL_FC%> = async(req, res) => {\n    try {\n        let query = req.body && req.body.query ? {...req.body.query} : {};\n        let options= req.body && req.body.options ? {...req.body.options} : {};\n        query = dbService.queryBuilderParser(query);\n        if(req.body && req.body.isCountOnly){\n            <%_         \n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){\n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){ \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        query = { ...query,...<%=JSON.parse(element.filter)%> }\n                    <%_}}\n                }                \n            }\n            _%>\n            let totalRecords = await dbService.count(<%-DB_MODEL_FC%>, query);\n            return res.success({data : { totalRecords }});\n        }\n        else {\n            <%_if(SUPPORT_API[i].fieldSelection){_%>\n                if(options.select && options.select.length){\n                    options.attributes = <%=SUPPORT_API[i].fields%>.filter(Set.prototype.has, new Set(options.select));\n                }else{\n                    options.attributes=<%=SUPPORT_API[i].fields%>\n                }\n            <%_} else {_%>\n            if (options && options.select && options.select.length){\n                options.attributes = options.select;\n            }\n            <%_}_%>\n            if (options && options.include && options.include.length){\n                let include = [];\n                options.include.forEach(i => {\n                i.model = models[i.model];\n                if (i.query) {\n                    i.where = dbService.queryBuilderParser(i.query);\n                }\n                include.push(i);\n                });\n                options.include = include;\n            }\n            if (options && options.sort){\n                options.order = dbService.sortParser(options.sort);\n                delete options.sort;\n            }\n            let result = await dbService.findMany( <%-DB_MODEL_FC%>,query,options);\n            if(!result){\n                return res.recordNotFound();\n            }\n            return res.success({data:result});   \n        }\n    }\n    catch(error){\n        return res.internalServerError({ message:error.message });\n    }\n}\n\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC) _%>\n/**\n* @description : find record of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains record retrieved from table.\n* @return {object} : found <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst get<%-DB_MODEL_FC%> = async(req, res) => {\n    try {\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let options = {};\n        <%_if(SUPPORT_API[i].fieldSelection){_%>\n        let select = <%=SUPPORT_API[i].fields%>\n        options.attributes = select;\n        <%_}_%> \n        let id = req.params.id\n        let result = await dbService.findByPk(<%-DB_MODEL_FC%>,id,options);\n        if(result){    \n            return res.success({data:result});\n        }\n        return res.recordNotFound();\n    }\n    catch(error){\n        return res.internalServerError({ message : error.message })\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"count\") {_%>\n    <%_methods.push('get'+DB_MODEL_FC+'Count') _%>\n/**\n* @description : returns total number of records of <%-DB_MODEL_FC%>.\n* @param {object} req : request including where object to apply filters in request body \n* @param {object} res : response that returns total number of records.\n* @return {object} : number of records. {status, message, data}\n*/\nconst get<%-DB_MODEL_FC%>Count = async(req, res) => {\n    try {\n        let where = {...req.body.where || {} };\n        <%_\n            nestedCalls={}\n            if(SUPPORT_API[i].IS_NESTED_CALL){  \n            nestedCalls = SUPPORT_API[i].NESTED_CALLS\n            if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                    for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                        where = {...where, ...<%=JSON.parse(element.filter)%> }\n                    <%_}}\n                }\n            }\n        _%>\n        let totalRecords = await dbService.count(<%-DB_MODEL_FC%>,where);\n        return res.success({data: { totalRecords } });\n    }\n    catch(error){\n        return res.internalServerError({ message:error.message });\n    }\n}\n<%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"delete\") {_%>\n    <%_methods.push('delete'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : delete record of <%-DB_MODEL_FC%> from table.\n* @param {object} req : request including id as request param.\n* @param {object} res : response contains deleted record.\n* @return {object} : deleted <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst delete<%-DB_MODEL_FC%> =async(req, res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = { id : req.params.id };\n        <%_\n                nestedCalls={}\n                if(SUPPORT_API[i].IS_NESTED_CALL){  \n                nestedCalls = SUPPORT_API[i].NESTED_CALLS\n                if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n                        for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                            query = { ...query,...<%=JSON.parse(element.filter)%>};\n                        <%_}}\n                    }\n                }\n        _%>\n        let result;\n        if (req.body.isWarning) {\n            result = await deleteDependentService.count<%-DB_MODEL_FC%>(query);\n        } else {\n            result = await deleteDependentService.delete<%-DB_MODEL_FC%>(query); \n        }\n        return res.success({data : result});\n    } catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_} else {_%>\n/**\n* @description : delete record of <%-DB_MODEL_FC%> from table.\n* @param {object} req : request including id as request param.\n* @param {object} res : response contains deleted record.\n* @return {object} : deleted <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst delete<%-DB_MODEL_FC%> = async (req, res) => {\n    try {\n        const result = await dbService.deleteByPk(<%-DB_MODEL_FC%>,req.params.id);\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({ message:error.message });\n    }\n}\n<%_}_%>\n<%_ } _%>\n\n<%_ if(SUPPORT_API[i].method==\"deleteMany\") {_%>\n    <%_methods.push('deleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : delete records of <%-DB_MODEL_FC%> in table by using ids.\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains no of records deleted.\n* @return {object} : no of records deleted. {status, message, data}\n*/\nconst deleteMany<%-DB_MODEL_FC%> =async(req, res) => {\n    try{\n        if(!req.body || !req.body.ids){\n            return res.badRequest();\n        }\n        let ids = req.body.ids;\n        let query = {id: { [Op.in] : ids }}\n        let data = req.body;\n        let result;\n        if(data.isWarning){\n            result = await deleteDependentService.count<%-DB_MODEL_FC%>(query);\n        } else{\n            result = await deleteDependentService.delete<%-DB_MODEL_FC%>(query);\n        }\n        return res.success({data:result});\n    }\n    catch(error){\n        return res.internalServerError({message:error.message}); \n    }\n}\n<%_} else {_%>\n/**\n* @description : delete records of <%-DB_MODEL_FC%> in table by using ids.\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains no of records deleted.\n* @return {object} : no of records deleted. {status, message, data}\n*/\nconst deleteMany<%-DB_MODEL_FC%> =async(req, res) => {\n    try{\n        let ids = req.body.ids; \n        if(!ids || !Array.isArray(ids) || ids.length < 1){\n            return res.badRequest();\n        }\n        let query = {id:{[Op.in]:ids}};\n        let result = await dbService.deleteMany(<%-DB_MODEL_FC%>,query);\n        return res.success({data:result});\n    } catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_ } _%>\n<%_ } _%>\n\n<%_ if(SUPPORT_API[i].method==\"softDelete\") {_%>\n    <%_methods.push('softDelete'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : deactivate record of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains updated record of <%-DB_MODEL_FC%>.\n* @return {object} : deactivated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDelete<%-DB_MODEL_FC%> = async (req, res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = { id :req.params.id }\n        <%_\n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){  \n        nestedCalls = SUPPORT_API[i].NESTED_CALLS\n        if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n            for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n                query = { ...query,...<%=JSON.parse(element.filter)%> };\n            <%_}}\n            }\n        }\n        _%>\n        let result = await deleteDependentService.softDelete<%-DB_MODEL_FC%>(query);\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_} else {_%>\n/**\n* @description : deactivate record of <%-DB_MODEL_FC%> from table by id;\n* @param {object} req : request including id in request params.\n* @param {object} res : response contains updated record of <%-DB_MODEL_FC%>.\n* @return {object} : deactivated <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDelete<%-DB_MODEL_FC%> = async (req, res) => {\n    try{\n        if(!req.params.id){\n            return res.badRequest();\n        }\n        let query = {id:req.params.id}\n        <%_\n        nestedCalls={}\n        if(SUPPORT_API[i].IS_NESTED_CALL){  \n        nestedCalls = SUPPORT_API[i].NESTED_CALLS\n        if(nestedCalls && nestedCalls.pre && nestedCalls.pre.length>0){             \n            for(const element of nestedCalls.pre){ if(element.existingVariable && element.filter!==undefined){_%>\n               query = { ...query,...<%=JSON.parse(element.filter)%> } \n            <%_}}\n            }\n        }\n        _%>\n        let options={};\n        let result = await dbService.softDeleteMany(<%-DB_MODEL_FC%>, query,options);\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_}_%>\n<%_ } _%>\n\n<%_ if(SUPPORT_API[i].method==\"softDeleteMany\") {_%>\n    <%_methods.push('softDeleteMany'+DB_MODEL_FC) _%>\n    <%_ if(DELETE_DEPENDENT_MODEL){_%>\n/**\n* @description : deactivate multiple records of <%-DB_MODEL_FC%> from table by ids;\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains updated records of <%-DB_MODEL_FC%>.\n* @return {object} : number of deactivated documents of <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDeleteMany<%-DB_MODEL_FC%> = async (req, res) => {\n    try{\n        let ids = req.body.ids;\n        if(!ids || !Array.isArray(ids) || ids.length < 1){\n            return res.badRequest();\n        }\n        let query = {id:{[Op.in]:ids}}\n        let result = await deleteDependentService.softDelete<%-DB_MODEL_FC%>(query);\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_} else {_%>\n /**\n* @description : deactivate multiple records of <%-DB_MODEL_FC%> from table by ids;\n* @param {object} req : request including array of ids in request body.\n* @param {object} res : response contains updated records of <%-DB_MODEL_FC%>.\n* @return {object} : number of deactivated documents of <%-DB_MODEL_FC%>. {status, message, data}\n*/\nconst softDeleteMany<%-DB_MODEL_FC%> = async (req, res) => {\n    try{\n        let ids = req.body.ids;\n        if(!ids || !Array.isArray(ids) || ids.length < 1){\n            return res.badRequest();\n        }\n        let query = {id:{[Op.in]:ids}};\n        let result = await dbService.softDeleteMany(<%-DB_MODEL_FC%>,query,options);\n        return res.success({data:result});\n    }catch(error){\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_}_%>\n<%_ } _%>\n\n<%_ } _%>\n\n<%_if(typeof USER_MODEL !== \"undefined\" && USER_MODEL){\n    methods.push('changePassword');\n    methods.push('updateProfile');\n    methods.push('getLoggedInUserInfo');\n    _%> \n    /**\n    * @description : change password\n    * @param {object} req : request including user credentials.\n    * @param {object} res : response contains updated user record.\n    * @return {object} : updated user record {status, message, data}\n    */\n    const changePassword = async (req, res) => {\n        try {\n            let params = req.body;\n            if (!params.newPassword || !params.oldPassword) {\n                return res.validationError();\n            }\n            let result = await auth.changePassword({...params,userId:req.user.id});\n            if(result.flag){\n                return res.failure({message:result.data});\n            }\n            return res.success({message:result.data});\n        } catch (error) {\n            return res.internalServerError({ message:error.message }); \n        }\n    }\n    /**\n    * @description : update user profile.\n    * @param {object} req : request including user profile details to update in request body.\n    * @param {object} res : updated user record.\n    * @return {object} : updated user record. {status, message, data}\n    */\n    const updateProfile = async (req, res) => {\n        try {\n            let dataToUpdate = {...req.body || {} };\n            let validateRequest = validation.validateParamsWithJoi(\n                dataToUpdate,\n                <%-DB_MODEL %>SchemaKey.updateSchemaKeys\n            );\n            if (!validateRequest.isValid) {\n                return res.validationError({message : `Invalid values in parameters, ${validateRequest.message}`});\n            }   \n            delete dataToUpdate.password;\n            delete dataToUpdate.createdAt;\n            delete dataToUpdate.updatedAt;\n            delete dataToUpdate.id;\n            let result = await dbService.updateByPk(<%-DB_MODEL_FC%>, req.user.id ,dataToUpdate);         \n            return res.success({data:result});\n        }\n        catch (error){\n            return res.internalServerError({message:error.message});\n        }\n    };\n\n    /**\n    * @description : get information of logged-in User.\n    * @param {obj} req : authentication token is required\n    * @param {obj} res : Logged-in user information\n    * @return {obj} : Logged-in user information {status, message, data}\n    */\n    const getLoggedInUserInfo = async (req, res) => {\n        try {\n            if (!req.user && !req.user.id) {\n                return res.badRequest();\n            }\n            const query = {\n                id : req.user.id,\n                isDeleted : false,\n                isActive : true\n            };\n            let result = await dbService.findOne(<%-DB_MODEL_FC%>,query);\n            if (!result) {\n                return res.recordNotFound();\n            }\n            return res.success({ data: result });\n        } catch (error){\n            return res.internalServerError({ data: error.message });\n        }\n    };\n<%_}_%>\n\n<%_if(CUSTOM_ROUTES){_%>\n<%_CUSTOM_ROUTES.forEach((v,i)=>{ \n    methods.push(v.functionName)\n_%>\n/**\n    * @description : <%-v.functionName%> \n    * @param {object} req : request\n    * @param {object} res : response \n    * @return {object} : response of <%-v.functionName%> {status, message, data}\n*/\nconst <%-v.functionName%>=async (req, res)=>{\n    try {\n        <%_if(typeof(v.queryBuilder) !== \"undefined\" && v.queryBuilder.length > 0){_%>\n        let combinedOutput={};\n        <%_ for(let i=0;i< v.queryBuilder.length;i++){_%>\n        <%_ if(v.queryBuilder[i].queryMode === \"find\"){ _%>\n            <%_ if(v.queryBuilder[i].filter){ \n                v.queryBuilder[i].model = v.queryBuilder[i].model.charAt(0).toUpperCase() + v.queryBuilder[i].model.slice(1);_%>\n            combinedOutput.<%-v.queryBuilder[i].outputVariable%> =  await customQueryService.find(<%-v.queryBuilder[i].model%>,{filter:<%-v.queryBuilder[i].filter%>});\n            <%_}_%>\n        <%_}_%>   \n        <%_}_%>\n        return res.success({data:combinedOutput});\n        <%_}_%>\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }  \n}   \n<%_ })_%>\n<%_}_%>\n\nmodule.exports = {\n    <%-methods.join()%>\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/controllers/fileUploadController.js.ejs",
    "content": "/**\n  * fileUploadController.js\n  * @description :: exports all method related file upload\n  */\n\n<%_if(S3_UPLOAD){_%>\nconst fs = require('fs');\nconst path = require('path');\nconst formidable = require('formidable');\nconst AWS = require('aws-sdk');\n<%_if(S3_UPLOAD_PRIVATE){_%>\nconst AmazonS3URI = require('amazon-s3-uri');\n<%_}_%>\n\nlet allowedFileTypes = <%=VALIDATION_TYPES%>;<%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\nlet maxFileSize = <%=max_size%>; //In Megabyte\n/**\n  * @description : uploads file using formidable.\n  * @param {object} req : request of file upload API\n  * @param {object} res : response of file upload API.\n  * @return {object} : response of file upload. {status, message, data}\n  */\nconst upload = async (req,res) =>{\n  try {\n\n    // Setting up formidable options.\n    const form = new formidable.IncomingForm();\n    form.multiples = true;\n    form.maxFileSize = 300 * 1024 * 1024; //300 MB\n    form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n    const uploadFileRes = await new Promise(async (resolve, reject) => {\n      form.parse(req, async function (err, fields, files) {\n        \n        if (err) {\n          reject(err);\n        }\n\n        let uploadSuccess = [];\n        let uploadFailed = [];\n        let fileCount = 1;\n\n        let fileArr = [];\n        if (!files['file[]'] || files['file[]'].size == 0) {\n          reject({\n            'message': 'Select at least one file to upload.',\n            'name': 'validationError'\n          });\n        }\n        if (!Array.isArray(files['file[]'])) {\n          fileArr.push(files['file[]']);\n          files['file[]'] = fileArr;\n        }\n\n        for (let file of files['file[]']) {\n          let response = await uploadFiles(file,fields,fileCount++);\n          if (response.status == false) {\n            uploadFailed.push({\n              'name': file.name,\n              'error': response.message,\n              'status': false\n            });\n          } else {\n            uploadSuccess.push({\n              'name': file.name,\n              'path': response.data,\n              'status': true\n            });\n          }\n        }\n\n        resolve({\n          uploadSuccess,\n          uploadFailed\n        });\n      });\n    });\n    \n    if (uploadFileRes.uploadSuccess.length > 0) {\n      let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n      return res.success({\n        message: message,\n        data: uploadFileRes\n      });\n    } else {\n      let message = 'Failed to upload files.';\n      return res.failure({\n        message: message,\n        data: uploadFileRes\n      });\n    }\n  } catch (error){\n    if (error.name && error.name == 'validationError') {\n      return res.validationError({ message: error.message });\n    } else {\n      return res.internalServerError({ message:error.message }); \n    }\n  }\n};\n\n<%_if(S3_UPLOAD_PRIVATE){_%>\n/**\n  * @description : generate pre signed url for file\n  * @param {string} uri : url of file\n  * @return {object} : response for generate pre signed url\n  */\nconst generatePreSignedURL = async (req, res) => {\n    try {\n        if (req.body && req.body.uri){\n          let uri = req.body.uri;\n          let S3Config = {\n              AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n              AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n              AWS_S3_REGION: process.env.AWS_S3_REGION,\n              AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n          };\n\n          const s3 = new AWS.S3({\n              region: S3Config.AWS_S3_REGION,\n              accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n              secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n          });\n\n          try {\n            const {\n              region, bucket, key\n            } = AmazonS3URI(uri);\n\n            let options = {\n              Bucket: bucket,\n              Key: key,\n              Expires: Number(process.env.AWS_URL_EXPIRATION) || 15 * 60 //in seconds,\n            };\n\n            await s3.getSignedUrl('getObject', options, (err, url) => {\n              if (err) {\n                  return res.failure({ message: err });\n              } else {\n                  return res.success({data: url})\n              }\n            });\n\n          } catch (err) {\n            return res.failure({ message: `${uri} is not a valid S3 uri` });\n          }\n        } else {\n            return res.badRequest();\n        }\n    } catch (error) {\n        return res.internalServerError({ message:error.message }); \n    }\n}\n<%_}_%>\n/**\n  * @description : upload files\n  * @param {object} file : file to upload\n  * @param {object} fields : fields for file\n  * @param {number} fileCount : total number of files to upload\n  * @return {object} : response for file upload\n  */\nasync function uploadFiles (file,fields,fileCount){\n\n  let extension = path.extname(file.name);\n  extension = extension.split('.').pop();\n\n  fileType = file.type;\n\n  if (allowedFileTypes.length) {\n    //Check allowed extension;\n    if (!allowedFileTypes.includes(extension)) {\n      return {\n        status: false,\n        message: 'Filetype not allowed.'\n      };\n    }\n  }\n\n  // Check File Size\n  const fileSize = ((file.size / 1024) / 1024);\n  if (maxFileSize < fileSize) {\n    return {\n      status: false,\n      message: `Allow file size upto ${maxFileSize} MB.`\n    };\n  }\n\n  let fileName = file.name;\n  //Create Requested Directory,if given in request parameter.\n  if (fields && fields.folderName) {\n    fileName = fields.folderName + '/' + fileName;\n  }\n  else if (fields && fields.fileName) {\n    fileName = fields.fileName + '-' + fileCount + path.extname(file.name);\n  }\n\n  const response = await new Promise(async (resolve, reject) => {\n    resolve(await uploadToS3(file,fileName));\n  });\n\n  return response;\n\n}\n/**\n  * @description : upload file to AWS s3\n  * @param {object} file : file to upload\n  * @param {string} fileName : name of file\n  * @return {object} : response for file upload to AWS s3\n  */\nasync function uploadToS3 (file, fileName){\n  let S3Config = {\n    AWS_S3_ACCESS_KEY_ID: process.env.AWS_S3_ACCESS_KEY_ID,\n    AWS_S3_SECRET_ACCESS_KEY: process.env.AWS_S3_SECRET_ACCESS_KEY,\n    AWS_S3_REGION: process.env.AWS_S3_REGION,\n    AWS_S3_BUCKET_NAME: process.env.AWS_S3_BUCKET_NAME,\n  };\n\n  const s3 = new AWS.S3({\n    region: S3Config.AWS_S3_REGION,\n    accessKeyId: S3Config.AWS_S3_ACCESS_KEY_ID,\n    secretAccessKey: S3Config.AWS_S3_SECRET_ACCESS_KEY\n  });\n\n  let params = {\n    Bucket: S3Config.AWS_S3_BUCKET_NAME,\n    Body: fs.createReadStream(file.path),\n    Key: fileName,\n  };\n\n  const response = await new Promise(async (resolve, reject) => {\n    s3.putObject(params, function (err, data) {\n      if (err) {\n        resolve({\n          status: false,\n          message: err.message\n        });\n      } else {\n        resolve({\n          status: true,\n          data: 'https://' + process.env.AWS_S3_BUCKET_NAME + '.s3.' + S3Config.AWS_S3_REGION + '.amazonaws.com/' + fileName\n        });\n      }\n    });\n  });\n\n  return response;\n}\nmodule.exports = { upload<%_if(S3_UPLOAD_PRIVATE){_%>,generatePreSignedURL<%_}_%> };\n\n<%_} else { _%>\nconst fs = require('fs');\nconst path = require('path');\nconst formidable = require('formidable');\nconst validUrl = require('valid-url');\n\nlet defaultDirectory = 'public/assets';\nlet allowedFileTypes = <%=VALIDATION_TYPES%>;<%_var max_size = MAX_SIZE ? MAX_SIZE : 5%>\nlet maxFileSize = <%=max_size%>; //In Megabyte\n\n/**\n  * @description : uploads file using formidable.\n  * @param {object} req : request of file upload API\n  * @param {object} res : response of file upload API.\n  * @return {object} : response of file upload. {status, message, data}\n  */\nconst upload = async (req, res) => {\n  try {\n    // Create Directory if not exist.\n    await makeDirectory(defaultDirectory);\n\n    // Setting up formidable options.\n    const form = new formidable.IncomingForm();\n    form.multiples = true;\n    form.maxFileSize = 300 * 1024 * 1024; //300 MB\n    form.maxFieldsSize = 100 * 1024 * 1024; //50 MB\n\n    //Upload File one by one\n    const uploadFileRes = await new Promise(async (resolve, reject) => {\n\n      form.parse(req, async function (err, fields, files) {\n\n        if (err) {\n          reject(err);\n        }\n\n        let uploadSuccess = [];\n        let uploadFailed = [];\n        let fileCount = 1;\n\n        let fileArr = [];\n        if (!files['file[]'] || files['file[]'].size == 0) {\n          reject({\n            'message': 'Select at least one file to upload.',\n            'name': 'validationError'\n          });\n        }\n        if (!Array.isArray(files['file[]'])) {\n          fileArr.push(files['file[]']);\n          files['file[]'] = fileArr;\n        }\n\n        for (let file of files['file[]']) {\n\n          let response = await uploadFiles(file, fields, fileCount++);\n\n          if (response.status == false) {\n            uploadFailed.push({\n              'name': file.name,\n              'error': response.message,\n              'status': false\n            });\n          } else {\n            let url = response.data;\n            if (!validUrl.isUri(response.data)) {\n              response.data = response.data.replace('/public', '');\n              url = `${response.data}`;\n            }\n            uploadSuccess.push({\n              'name': file.name,\n              'path': url,\n              'status': true\n            });\n          }\n        }\n        resolve({\n          uploadSuccess,\n          uploadFailed\n        });\n      });\n    });\n    \n    if (uploadFileRes.uploadSuccess.length > 0) {\n      let message = `${uploadFileRes.uploadSuccess.length} File uploaded successfully out of ${uploadFileRes.uploadSuccess.length + uploadFileRes.uploadFailed.length}`;\n      return res.success({\n        message: message,\n        data: uploadFileRes\n      });\n    } else {\n      let message = 'Failed to upload files.';\n      return res.failure({\n        message: message,\n        data: uploadFileRes\n      });\n    }\n  } catch (error) {\n    if (error.name && error.name == 'validationError') {\n      return res.validationError({ message: error.message });\n    } else {\n      return res.internalServerError({ message:error.message }); \n    }\n  }\n};\n\n/**\n * @description : create directory to specified path\n * @param {string} directoryPath : location where directory will be created\n * @return {boolean} : returns true if directory is created or false\n */\nconst makeDirectory = async (directoryPath) => {\n\n  if (!fs.existsSync(directoryPath)) {\n    fs.promises.mkdir(directoryPath, { recursive: true }, (err) => {\n      if (err) {\n        return false;\n      };\n      return true;\n    });\n  }\n  return true;\n};\n\n/**\n * @description : upload files\n * @param {object} file : file to upload\n * @param {object} fields : fields for file\n * @param {number} fileCount : total number of files to upload\n * @return {object} : response for file upload\n */\nasync function uploadFiles (file, fields, fileCount) {\n\n  let tempPath = file.path;\n  let unlink;\n  let fileName = file.name;\n\n  let extension = path.extname(file.name);\n  extension = extension.split('.').pop();\n\n  fileType = file.type;\n\n  if (allowedFileTypes.length) {\n    //Check allowed extension;\n    if (!allowedFileTypes.includes(extension)) {\n      return {\n        status: false,\n        message: 'Filetype not allowed.'\n      };\n    }\n  }\n\n  // Check File Size\n  const fileSize = ((file.size / 1024) / 1024);\n  if (maxFileSize < fileSize) {\n    return {\n      status: false,\n      message: `Allow file size upto ${maxFileSize} MB.`\n    };\n  }\n\n  //Create New path\n  let newPath = defaultDirectory + '/' + new Date().getTime() + path.extname(file.name);\n\n  //Create Requested Directory,if given in request parameter.\n  if (fields && fields.folderName) {\n    let newDir = defaultDirectory + '/' + fields.folderName;\n    const createDir = await makeDirectory(newDir);\n    if (createDir) {\n      if (fields.fileName) {\n        newPath = newDir + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n        fileName = fields.fileName;\n      }\n    }\n  }\n  else if (fields && fields.fileName) {\n    newPath = defaultDirectory + '/' + fields.fileName + '-' + fileCount + path.extname(file.name);\n    fileName = fields.fileName;\n  }\n  \n  const response = await new Promise(async (resolve, reject) => {\n    fs.readFile(tempPath, function (err, data) {\n      fs.writeFile(newPath, data, async function (err) {\n  \n        //Remove file from temp\n        unlink = await unlinkFile(tempPath);\n  \n        if (unlink.status == false) {\n          reject(unlink);\n        } else {\n          resolve({\n            status: true,\n            message: 'File upload successfully.',\n            data: '/' + newPath\n          });\n        }\n      });\n    });\n  });\n\n  return response;\n}\n\n/**\n  * @description : unlink(delete) file from specified path\n  * @param {string} path : location of file \n  * @return {object} : return unlink file status {status, message}\n  */\nasync function unlinkFile (path) {\n\n  fs.unlink(path, function (err) {\n    if (err) {\n      return {\n        status: false,\n        message: err.message\n      };\n    }\n  });\n\n  return { status: true };\n}\n\nmodule.exports = { upload };\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/customEnv.ejs",
    "content": "<%_for(const [key,value] of Object.entries(CUSTOM_ENV)) {_%>\n<%-key%>=<%-value%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/controller.js.ejs",
    "content": "/**\n * @description :: exports custom route methods.\n */\n<%_\nif(typeof(UNIQ_TASK_MODELS)!== 'undefined'){\nlet models = UNIQ_TASK_MODELS\nfor(const model of models){\n_%>\nconst <%-model%> = require(\"../../model/<%-model%>\")\n<%_ } }_%>\n<%_if(IS_CQ){_%>\nconst {Op} = require(\"sequelize\")\nconst customQueryService = require(\"../../services/customQueryService\")\n<%_}_%>\n\n<%_ROUTES.forEach((v,i)=>{_%>\n/** \n  * @description : <%-v.descriptions%>\n  * @param {object} req : request for <%-v.functionName%>\n  * @param {object} res : response for <%-v.functionName%>\n  * @return {object} : response for <%-v.functionName%>\n  */\nconst <%-v.functionName%>=async (req,res)=>{\ntry {\n    try {\n        <%_if(typeof(v.queryBuilder) !== \"undefined\" && v.queryBuilder.length > 0){_%>\n        let combinedOutput={};\n        <%_ for(let i=0;i< v.queryBuilder.length;i++){_%>\n        <%_ if(v.queryBuilder[i].queryMode === \"find\"){ _%>\n            <%_ if(v.queryBuilder[i].filter){ \n                v.queryBuilder[i].model = v.queryBuilder[i].model.charAt(0).toUpperCase() + v.queryBuilder[i].model.slice(1);_%>\n            combinedOutput.<%-v.queryBuilder[i].outputVariable%> =  await customQueryService.find(<%-v.queryBuilder[i].model%>,{filter:<%-v.queryBuilder[i].filter%>});\n            <%_}_%>\n        <%_}_%>   \n        <%_}_%>\n        return res.success({data:combinedOutput});\n        <%_}_%>\n    } catch (error) {\n        return res.internalServerError();\n    }\n}    \n<%_ })_%>\n\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}\n<%_\nfunction printSequelizeFilter(filter) {\n  let mainstr = \"\"\n  if (typeof filter === typeof {}) {\n    if (filter.length) {\n      mainstr += '['\n      for (let obj of filter) {\n        if (typeof obj === typeof {}) {\n          mainstr+= printSequelizeFilter(obj)\n        } else {\n          mainstr += `${obj}`\n        }\n      }\n      mainstr += ']'\n    } else {\n      for (key in filter) {\n        mainstr += '{'\n        if (typeof filter[key] === typeof {}) {\n          mainstr += `${key}:`\n          mainstr += printSequelizeFilter(filter[key])\n        } else {\n          if(!isNaN(`${filter[key]}`)){ \n            mainstr += `${key}:${filter[key]}`\n          }else if(filter[key] === true || false){\n            mainstr += `${key}:${filter[key]}`\n          }else{\n            mainstr += `${key}:\"${filter[key]}\"`\n          }\n        }\n        mainstr += '},'\n      }\n    }\n  } else {\n    mainstr += `${k}:\"${filter[k]}\"`\n  }\n  return mainstr\n}\n\nfunction printSequelizeSort(sortObj){\n  const finalSortArray = []\n  for (const [key, value] of Object.entries(sortObj)) {\n    let finalSort = []\n    finalSort.push(key)\n    finalSort.push(value === 1 ? 'ASC' : 'DESC')\n    finalSortArray.push(finalSort)\n  }\n  return finalSortArray;\n}\n_%>\n    \n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/existIndexRoute.js.ejs",
    "content": "<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v%>/index\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/indexRoutes.js.ejs",
    "content": "/**\n * index.js\n * @description :: API routes\n */\n \n<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.platform.toLowerCase()%>Route\"));\n<%_ }) _%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/platformIndexRoutes.js.ejs",
    "content": "/**\n * index.js\n * @description :: API routes\n */\n\nconst express = require(\"express\")\nconst router =  express.Router()\n\n<%_ CONTROLLERS.forEach((controller)=>{ _%>\nrouter.use(\"/\",require(\"./<%-controller.toLowerCase()%>Routes\"));\n<%_ }) _%>\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/route.js.ejs",
    "content": "/**\n * index.js\n * @description :: API routes\n */\n\nconst express = require(\"express\");\nconst router = express.Router();\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\nconst <%- SERVICE_NAME%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-SERVICE_NAME%>Controller\");    \n<%_\nif(typeof(CONTROLLER_IMPORTS) !== 'undefined' ){\nObject.keys(CONTROLLER_IMPORTS).forEach(function(key) { _%>\nconst <%-key%> = require(\"<%-CONTROLLER_IMPORTS[key]%>\")\n<%_ }); } _%> \n<%_\nif(POLICIES && POLICIES.length){\n POLICIES.forEach((policy)=>{_%>\nconst <%-policy%> = require(\"../../middleware/<%-policy%>\")\n<%_}) }_%>\n<%_ ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n<%_}else{_%>\n<%-policy%>,<%_}_%>\n<%_})_%>\n<%_}_%><%-v.controller%>Controller.<%-v.functionName%>)\n<%_})_%>\n    \nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/individualRoutes/service.js.ejs",
    "content": "<%_ROUTES.forEach((v,i)=>{_%>\n/* \n* <%-v.descriptions%>\n*/\nconst <%-v.functionName%>=()=>{\n    try {\n        return true;\n    } catch (error) {\n        throw error;\n    }\n}    \n<%_ })_%>\nmodule.exports={\n<%_ROUTES.forEach((v,i)=>{_%>\n    <%- v.functionName %>,\n<%_ })_%>    \n}\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/middleware/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: middleware that checks authentication and authorization of user\n */\n\nconst passport = require('passport');\nconst { LOGIN_ACCESS, USER_TYPES,PLATFORM \n<%_if(CUSTOM_ROUTES){_%><%_ for(let platform in CUSTOM_ROUTES){ _%>\n,<%-platform.toUpperCase()%>_CUSTOM_ROUTES  \n<%_ } _%>\n<%_}_%>\n} = require('../constants/authConstant');\nconst model = require('../model');\nconst dbService = require('../utils/dbService');\n\n/**\n * @description : returns callback that verifies required access\n * @param {obj} req : request of route.\n * @param {callback} resolve : resolve callback for succeeding method.\n * @param {callback} reject : reject callback for error.\n * @param {int} platform : platform.\n */\nconst verifyCallback = (req, resolve, reject, platform) => async (err, user, info) => {\n    if (err || info || !user) {\n        return reject(\"Unauthorized User\");\n    }\n    req.user = user;\n\n    let userToken = await dbService.findOne(model.userTokens,{token:(req.headers.authorization).replace('Bearer ',''),userId:user.id});\n    if (!userToken){\n        return reject('Token not found');\n    }\n    if (userToken.isTokenExpired){\n        return reject('Token is Expired');\n    }\n    if (user.role) {\n        let allowedPlatforms = LOGIN_ACCESS[user.role] ? LOGIN_ACCESS[user.role] : [];\n        if (!allowedPlatforms.includes(platform)) {\n            return reject('Unauthorized user');\n        }\n    }\n    resolve();\n};\n\n/**\n * @description : authentication middleware for request.\n * @param {obj} req : request of route.\n * @param {obj} res : response of route.\n * @param {callback} next : executes the next middleware succeeding the current middleware.\n * @param {int} platform : platform.\n */\nconst auth = (platform) => async (req, res, next) => {\n<% let c = 0; %>\n<%_ PLATFORM.forEach((v)=>{ c++; _%>\n    <%_ if(c===1){ _%>\n    if(platform == PLATFORM.<%- v.toUpperCase() %>){\n        return new Promise((resolve, reject) => {\n            passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(req, resolve, reject, platform))(\n                req,\n                res,\n                next\n            );\n        })\n        .then(() => next())\n        .catch((err) => {\n            return res.unAuthorized();\n        });\n    }\n    <%_ }else{ _%>\n    else if(platform == PLATFORM.<%- v.toUpperCase() %>){\n        return new Promise((resolve, reject) => {\n            passport.authenticate('<%-v.toLowerCase()%>-rule', { session: false }, verifyCallback(req, resolve, reject, platform))(\n                req,\n                res,\n                next\n            );\n        })\n        .then(() => next())\n        .catch((err) => {\n            return res.unAuthorized();\n        });\n    }\n    <%_ } _%> \n<%_ }) _%>\n};\n\nmodule.exports = auth;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/middleware/checkRolePermission.js.ejs",
    "content": "/**\n * checkRolePermission.js\n * @description :: middleware that checks access of APIs for logged-in user\n */\n\nconst { Op } = require('sequelize');\nconst model = require('../model');\nconst dbService = require('../utils/dbService');\nconst { replaceAll } = require('../utils/common');\nconst { role } = require('../model');\n\n/**\n   * @description : middleware for authentication with role and permission.\n   * @param {obj} req : request of route.\n   * @param {obj} res : response of route.\n   * @param {callback} next : executes the next middleware succeeding the current middleware.\n   */\n\n  const checkRolePermission = async (req, res, next) => {\n  if (req.user) {\n    const loggedInUserId = req.user.id;\n    let rolesOfUser = await dbService.findMany(model.userRole, {\n      userId: loggedInUserId,\n      isActive : true,\n      isDeleted: false,\n\n    },\n    { attributes: ['roleId'] });\n    if (rolesOfUser && rolesOfUser.data && rolesOfUser.data.length) {\n      rolesOfUser = [...new Set((rolesOfUser.data).map((item) => item.roleId))];\n      const route = await dbService.findOne(model.projectRoute, {\n        route_name: replaceAll((req.route.path.toLowerCase()).substring(1), '/', '_'),\n        uri: req.route.path.toLowerCase(),\n      });\n      if (route) {\n        const allowedRoute = await dbService.findMany(model.routeRole, {\n\n          [Op.and]: [\n            { routeId: route.id },\n            { roleId: { [Op.in]: rolesOfUser } },\n            { isActive: true },\n            { isDeleted: false },\n          ],\n\n        });\n        if (allowedRoute && allowedRoute.data.length) {\n          next();\n        } else {\n          return res.unAuthorized({message :'You are not having permission to access this route!'});\n        }\n      } else {\n        next();\n      }\n    } else {\n      // return res.unAuthorized({message :'You are not having permission to access this route!'});\n      next();\n    }\n  } else {\n    return res.unAuthorized({message :'Authorization token required!'});\n  }\n  return undefined;\n};\n  \n  \n\nmodule.exports = checkRolePermission;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/middleware/loginUser.js.ejs",
    "content": "/**\n * loginUser.js\n * @description :: middleware that verifies user's JWT token\n */\n\nconst jwt = require(\"jsonwebtoken\");\nconst {PLATFORM} = require(\"../constants/authConstant\");\n<%_ PLATFORM.forEach((v)=>{ _%>\nconst <%-v.toLowerCase()%>Secret = require(\"../constants/authConstant\").JWT.<%-v.toUpperCase()%>_SECRET;\n<%_ }) _%>   \n\n/**\n* @description : middleware for authenticate user with JWT token\n* @param {obj} req : request of route.\n* @param {obj} res : response of route.\n* @param {callback} next : executes the next middleware succeeding the current middleware.\n*/\nconst authenticateJWT = (platform) =>  (req, res, next) => {\n    const authHeader = req.headers.authorization;\n    if (!authHeader) {\n        return res.unAuthorized();\n    }\n    const token = authHeader.split(' ')[1];\n    let secret = '';\n    <%_ let c = 0; PLATFORM.forEach((v)=>{ c++;  _%>\n        <%_ if(c===1){ _%>\n            if(platform == PLATFORM.<%- v.toUpperCase() %>){\n            secret = <%-v.toLowerCase()%>Secret;\n        }\n        <%_ }else{ _%>\n        else  if(platform == PLATFORM.<%- v.toUpperCase() %>){\n            secret = <%-v.toLowerCase()%>Secret;\n        }\n        <%_ } _%> \n    <%_  }) _%>\n    \n    jwt.verify(token,secret, (error, user) => {\n        if (error) {\n            return res.unAuthorized();\n        }\n        req.user = user;\n        next();\n    });\n\n};\nmodule.exports = authenticateJWT\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/middleware/sampleMiddleware.js.ejs",
    "content": "<%_if(POLICY.code){_%>\n<%-POLICY.code%>\n<%_}else{_%>\nconst <%-POLICY.functionName%>=(req,res,next)=>{\n    try {\n        next()\n    } catch (error) {\n        throw error;\n    }\n}\n\nmodule.exports=<%-POLICY.functionName%>\n<%_}_%>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/models/index.js.ejs",
    "content": "/**\n * index.js\n * @description :: exports all the models and its relationships among other models\n */\n\nconst dbConnection=require(\"../config/dbConnection\")\nconst db={};\ndb.sequelize = dbConnection;\n\n<%_ Object.keys(RELATIONSHIPS).map(d => { _%>\ndb.<%- d %> = require('./<%- d %>')\n<%_ }); _%>\n\n<%_ Object.keys(RELATIONSHIPS).map(d => {\nif(Array.isArray(RELATIONSHIPS[d])){\n    RELATIONSHIPS[d].length ? RELATIONSHIPS[d].forEach(m => { \n_%>\n<%_if(m.relType === 'HAS_ONE') {_%>\ndb.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\ndb.<%- d %>.hasOne(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}else if(m.relType === 'HAS_MANY'){_%>\ndb.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\ndb.<%- d %>.hasMany(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}else{_%>\ndb.<%- m.model %>.belongsTo(db.<%- d %>, { foreignKey: \"<%- m.refId %>\", as: \"_<%- m.refId %>\", targetKey: \"<%- m.refAttribute %>\" });\ndb.<%- d %>.hasMany(db.<%- m.model %>, { foreignKey: \"<%- m.refId %>\", sourceKey: \"<%- m.refAttribute %>\" });\n<%_}_%>\n<%_ \n    }) : [] \n}});\n_%>\n<%_\nif(VIRTUAL_RELATION!==undefined){\n(Object.keys(VIRTUAL_RELATION)).forEach(model => {\n    if(Array.isArray(VIRTUAL_RELATION[model])){\n        const vrs = VIRTUAL_RELATION[model];\n        vrs.forEach((vr) => {\n          const data = `db.${model}.hasMany(db.${vr.ref}, { foreignKey: \"${vr.foreignField}\" })`;\n          _%>\n          <%-data%>\n          <%_\n        });\n    }\n})\n}\n_%>\n\nmodule.exports = db;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/models/model.js.ejs",
    "content": "/**\n * <%-DB_MODEL%>.js\n * @description :: sequelize model of database table <%-DB_MODEL%>\n */\n \nconst { DataTypes } = require('sequelize');\nconst sequelize = require('../config/dbConnection')\nconst sequelizePaginate = require('sequelize-paginate');\nconst sequelizeTransforms = require('sequelize-transforms');\n<%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n<%_if(typeof FLAG !== \"undefined\"){_%>    \nconst dayjs = require('dayjs');\n<%_}_%>\n<%_}_%>    \nconst { convertObjectToEnum } = require('../utils/common');\n<%_if(typeof USER !== \"undefined\" && USER){ _%> \nconst bcrypt = require('bcrypt');\n<%_}_%> \n<%_if(MODEL_ENUM!==null && MODEL_ENUM){_%>\n<%_let a=[]_%>    \n<%_for(let i in MODEL_ENUM){_%>\n<%_if(MODEL_ENUM[i].enumFile){_%>\n<%_if(!a.includes(MODEL_ENUM[i].enumFile)){_%>\n<%_a.push(MODEL_ENUM[i].enumFile)_%>\nconst <%-MODEL_ENUM[i].enumFile%>Enum=require(\"../constants/<%-MODEL_ENUM[i].enumFile%>\")\n<%_}_%>        \n<%_}_%>\n<%_}_%>\n<%_}_%>\n<%_ var model = DB_SCHEMA _%>\n<%_ var modelArr = Object.keys(model)_%>\nlet <%-DB_MODEL_FC%> = sequelize.define(\"<%-DB_MODEL%>\",{\n    <%_ for(let v in model){ _%>\n    <%_if(MODEL_ENUM && MODEL_ENUM[v]){_%>\n     <%model[v].values=`convertObjectToEnum(${MODEL_ENUM[v].enumFile}Enum`%>\n     <%model[v].values+=`.${MODEL_ENUM[v].values})`%>\n     <%_if(MODEL_ENUM[v].defaultValue){_%>\n        <%_ if( Array.isArray(MODEL_ENUM[v].defaultValue)){ _%>\n            <% model[v].defaultValue=`${MODEL_ENUM[v].enumFile}Enum` %>\n            <% model[v].defaultValue+=`.${MODEL_ENUM[v].values}` %>\n            <% model[v].defaultValue+=`[${MODEL_ENUM[v].defaultValue[0]}]` %>       \n        <% }else { %>\n                <% model[v].defaultValue=`${MODEL_ENUM[v].enumFile}Enum` %>\n                <% model[v].defaultValue+=`.${MODEL_ENUM[v].values}` %>\n                <% model[v].defaultValue+=`.${MODEL_ENUM[v].defaultValue}` %>\n        <% } %>\n     <%_}_%>\n    <%_}_%>  \n    <%_ let jsonStr = JSON.stringify(model[v]);\n            var finalStr = new String();\n            finalStr = jsonStr.toString().replace(/\"/g, \"\");\n            finalStr = finalStr.replace(/@@/g, '\"').replace('`${',\"\").replace('}`',\"\");\n        _%>\n    <%_ if(modelArr[modelArr.length-1]!==v){ _%>\n        <%-v%>:<%-finalStr%>,\n    <%_}else{_%>\n        <%-v%>:<%-finalStr%>\n    <%_ } _%><%_ } _%>}\n    <%_ if(typeof HOOKS !== \"undefined\") { _%>\n    ,{hooks:{\n    <%_ for(let [key,value] of Object.entries(HOOKS)){_%>\n        <%-key%>: [\n        <%_for(let i=0;i< value.length;i++){_%>\n        async function(<%-DB_MODEL%>,options){\n            <%-value[i].code%>\n        },\n        <%_}_%> \n        ],\n    <%_}_%> \n    }\n    <%_ } _%>\n<%_ if(typeof INDEX !== \"undefined\" && INDEX.length !== 0) { _%>\n    ,indexes:  <%- JSON.stringify(INDEX) %> \n<%_ } _%>\n}\n);\n<%_if(typeof USER!== undefined && USER){ _%>\n<%-DB_MODEL_FC%>.prototype.isPasswordMatch = async function (password) {\n        const user = this;\n        return bcrypt.compare(password, user.<%-PASSWORD%>);\n    }\n<%_ } _%>\n<%-DB_MODEL_FC%>.prototype.toJSON = function () {\n    var values = Object.assign({}, this.get());\n    <%_if(typeof CONCAT_HOOK !== \"undefined\" && CONCAT_HOOK){_%>\n    <%_for(index of CONCAT_HOOK){_%>\n    <%_for(formateIndex in index){_%>\n    <%_if(typeof (index[formateIndex])==='object'){_%>\n    if(values.<%-formateIndex%>){\n        values.<%-formateIndex%>=<%=index[formateIndex].true%>;\n    }else{\n        values.<%-formateIndex%>=<%=index[formateIndex].false%>;\n    }\n    <%_}else{_%>    \n    <%_if(index[formateIndex].includes('concat')){_%>\n    if(values.<%-STRING_ATT[0]%> && values.<%-STRING_ATT[1]%>){\n        values.<%-formateIndex%>=<%-index[formateIndex]%>;\n    }      \n    <%STRING_ATT.shift()%>\n    <%STRING_ATT.shift()%>\n    <%_}else{_%>\n    values.<%-formateIndex%>=<%-index[formateIndex]%>;\n    <%_}_%>        \n    <%_}_%>\n    <%_}_%>   \n    <%_}_%>   \n    <%_}_%>    \n    <%_if(IS_PRIVATE_ATTR !== null && IS_PRIVATE_ATTR === true) {_%>\n        <%_if(PRIVATE_ATTRS !== null && PRIVATE_ATTRS) {_%>\n            <%_Object.keys(PRIVATE_ATTRS).map((t) => {_%>            \n                <%_if(PRIVATE_ATTRS[t]) {_%>            \n                    delete values.<%-t%>\n                <%_}_%>        \n            <%_});_%>        \n        <%_}_%>    \n    <%_}_%>\n    return values;\n}\nsequelizeTransforms(<%-DB_MODEL_FC%>);\nsequelizePaginate.paginate(<%-DB_MODEL_FC%>);\nmodule.exports = <%-DB_MODEL_FC%>\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: express routes of authentication APIs\n */\n\nconst express =  require(\"express\");\nconst routes  =  express.Router();\n<%_if(SOCIAL_PLATFORMS.length){ _%>\nconst session = require('express-session');\n<%_}_%>\nconst authController =  require(\"../../controller/<%-PLATFORM%>/authController\");\nconst auth = require('../../middleware/auth');\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\n\nroutes.route(\"/register\").post(authController.register);\nroutes.post(\"/login\",authController.login);\nroutes.route(\"/forgot-password\").post(authController.forgotPassword);\nroutes.route(\"/validate-otp\").post(authController.validateResetPasswordOtp);\nroutes.route(\"/reset-password\").put(authController.resetPassword);\n<%_if(SOCIAL_PLATFORMS.length) { \n    SOCIAL_PLATFORMS.forEach(s=>{ _%>\nroutes.get(\"/<%-s.toLowerCase()%>\",(req,res)=>{\n    req.session.platform = <%=PLATFORM%>\n    res.redirect(`http://localhost:${process.env.PORT}/auth/<%-s.toLowerCase()%>`);\n})       \n<%_})_%>\n<%_}_%>\nroutes.route('/logout').post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), authController.logout); \n\nmodule.exports = routes;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/commonIndexRoutes.js.ejs",
    "content": "const express =  require(\"express\")\nconst router =  express.Router()\n\n<%_ PLATFORM.forEach((p) =>{ _%>\nrouter.use(require(\"./<%-p%>Routes\"));\n<%_})_%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/index.js.ejs",
    "content": "/**\n * index.js\n * @description :: index route of platforms\n*/\nconst express = require(\"express\")\nconst router =  express.Router()\n<%_ if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimit=require('express-rate-limit');\n<%_ } _%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nconst rateLimiter=rateLimit({\n    windowMs:<%-REACTIVE_TIME%> * 60 * 1000,\n    max:<%-LOGIN_RATE%>,\n    message: \"Too many API calls from this IP, please try again after a <%-REACTIVE_TIME%> minutes\"\n});\n<%_}_%>\n<%_for(let module in PLATFORM){_%>\n<%_if(typeof LOGIN_RATE !== \"undefined\" && LOGIN_RATE){_%>\nrouter.use(rateLimiter,require(\"./<%-module%>/index\"));  \n<%_} else {_%> \nrouter.use(require(\"./<%-module%>/index\"));\n<%_}_%>\n<%_}_%>\n\nmodule.exports =router"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/modelRoutes.js.ejs",
    "content": "/**\n * <%-DB_MODEL%>Routes.js\n * @description :: CRUD API routes for <%-DB_MODEL%>\n */\n \nconst express = require('express');\nconst router = express.Router();\nconst <%-DB_MODEL%>Controller = require(\"../../controller/<%-PLATFORM%>/<%-DB_MODEL%>Controller\")\n<%_ if(IS_AUTH){ _%>\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\nconst auth = require(\"../../middleware/auth\");\n<%_ } _%>\n<%_ if(CUSTOM_POLICY && CUSTOM_POLICY.length){ \n    if(CUSTOM_POLICY.includes('auth')){ let arrayIndex = CUSTOM_POLICY.indexOf('auth'); delete CUSTOM_POLICY[arrayIndex]; CUSTOM_POLICY=CUSTOM_POLICY.filter(Boolean);}\n    _%>\n<%_ for(let i=0;i < CUSTOM_POLICY.length;i++){ _%>\nconst <%-CUSTOM_POLICY[i]-%> = require('../../middleware/<%-CUSTOM_POLICY[i]-%>');\n<%_ } _%>  \n<%_ } _%>  \n<%_ if(CONTROLLERS_TO_IMPORT && CONTROLLERS_TO_IMPORT.length){ _%>\n<%_ for(let i=0;i < CONTROLLERS_TO_IMPORT.length;i++){ \n    if(CONTROLLERS_TO_IMPORT[i] != DB_MODEL){ _%>\nconst <%-CONTROLLERS_TO_IMPORT[i]-%>Controller = require('../../controller/<%-PLATFORM%>/<%-CONTROLLERS_TO_IMPORT[i]-%>Controller');\n<%_ } }_%>  \n<%_ } _%> \n\n<%_ for(let i=0;i < SUPPORT_API.length;i++){ _%>\n<%_ if(SUPPORT_API[i].method==\"create\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/create\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%>\n<%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/create\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.add<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"createBulk\") {_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/addBulk\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/addBulk\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkInsert<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findAll\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/list\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/list\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.findAll<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"findById\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/:id\").get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/:id\").get(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ } _%><%_ } _%>\n<%_ if(SUPPORT_API[i].method==\"count\"){ _%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/count\").post(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/count\").post(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%>\n<%-DB_MODEL%>Controller.get<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>Count);\n<%_ } _%><%_ } _%>\n<%_if(SUPPORT_API[i].method==\"update\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/update/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);    \n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/update/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.update<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);    \n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"bulkUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/updateBulk\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/updateBulk\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.bulkUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"partialUpdate\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/partial-update/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/partial-update/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.partialUpdate<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"delete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/delete/:id\").delete(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/delete/:id\").delete(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.delete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"deleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/deleteMany\").delete(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/deleteMany\").delete(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.deleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDelete\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDelete/:id\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDelete/:id\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDelete<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_if(SUPPORT_API[i].method==\"softDeleteMany\"){_%>\n<%_ if(SUPPORT_API[i].isAuth){ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDeleteMany\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>), <%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_ }else{ _%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/softDeleteMany\").put(<%_ if(SUPPORT_API[i].policy.length) { _%><%_ for(let j=0;j < SUPPORT_API[i].policy.length;j++){ _%><%-SUPPORT_API[i].policy[j]%>,<%_ } _%><%_ } _%><%-DB_MODEL%>Controller.softDeleteMany<%-DB_MODEL.charAt(0).toUpperCase() + DB_MODEL.slice(1);%>);\n<%_}_%><%_}_%>\n<%_}_%>\n<%_ if(USER_MODEL){ _%>\n<%_ if(typeof IS_AUTH !== \"undefined\" && IS_AUTH){_%>\nrouter.route(\"/<%-ROUTE_PREFIX%>/me\").get(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.getLoggedInUserInfo);\nrouter.route(\"/<%-ROUTE_PREFIX%>/change-password\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.changePassword);\nrouter.route(\"/<%-ROUTE_PREFIX%>/update-profile\").put(auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),<%-DB_MODEL%>Controller.updateProfile); \n<%_ } _%> \n<%_ } _%>\n<%_if(CUSTOM_ROUTES && CUSTOM_ROUTES.length){_%>\n<%_ CUSTOM_ROUTES.forEach((v,i)=> {_%>\nrouter.route(\"<%-v.api%>\").<%-v.method%>(<%_if(v.policies && v.policies.length){_%>\n<%_v.policies.forEach((policy)=>{_%>\n<%_if(policy==='auth'){_%>auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),\n<%_}else{_%>\n<%-policy%>,<%_}_%>\n<%_})_%>\n<%_}_%><%-v.controller%>Controller.<%-v.functionName%>)\n<%_})_%> \n<%_}%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/platformIndexRoutes.js.ejs",
    "content": "/**\n  * index route file of <%-PLATFORM_NAME.toLowerCase()%> platform.\n  * @description: exports all routes of <%-PLATFORM_NAME.toLowerCase()%> platform.\n*/\n\nconst express =  require(\"express\")\nconst router =  express.Router()\n<%_ if(IS_AUTH){ _%>\nrouter.use(\"/<%-PLATFORM_NAME.toLowerCase()%>/auth\",require(\"./auth\"));\n<%_ } _%>\n<%_ for(let i in PLATFORM){ _%>\nrouter.use(require(\"./<%-i%>Routes\"));\n<%_}_%>  \n<%_if(typeof ROUTES!==\"undefined\"){_%>\n<%_ ROUTES.forEach((v,i)=>{ _%>\nrouter.use(\"/\",require(\"./<%-v.controller%>Routes\"));\n<%_})_%>\n<%_}_%>\n\nmodule.exports = router;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/routes/uploadRoutes.js.ejs",
    "content": "/**\n * uploadRoutes.js\n * @description :: upload/download attachment routes\n */\n \nvar express = require('express');\nvar router = express.Router();\nconst fileUploadController = require(\"../../controller/<%-PLATFORM%>/fileUploadController\");\n<%_ if(IS_AUTH){ _%>\nconst { PLATFORM } =  require(\"../../constants/authConstant\");\nconst auth = require(\"../../middleware/auth\");\n<%_ } _%>\n\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/upload\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.upload);\n<%_ }else{ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/upload\",fileUploadController.upload);\n<%_ } _%>\n\n<%_ if(S3_UPLOAD_PRIVATE){_%>\n<%_ if(IS_AUTH){ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\",auth(PLATFORM.<%-PLATFORM.toUpperCase()%>),fileUploadController.generatePreSignedURL);\n<%_ }else{ _%>\nrouter.post(\"/<%-PLATFORM_PREFIX%>/generate-pre-signed-url\",fileUploadController.generatePreSignedURL);\n<%_ } _%>\n<%_ } _%>\n\nmodule.exports = router;"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/seeders/index.js.ejs",
    "content": "/**\n * seeder.js\n * @description :: functions that seeds mock data to run the application\n */\n\nconst model = require('../model')\nconst dbService = require('../utils/dbService');\n<%_if(IS_AUTH){_%>\n  const bcrypt = require('bcrypt')\n  const authConstant=require('../constants/authConstant');\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    const { replaceAll } = require('../utils/common');\n    const { Op } = require('sequelize');\n  <%_}_%>\n<%_}_%>\n\n<%_if(IS_AUTH){_%>\n  /* seeds default users */\n  async function seedUser() {\n    try{\n      let userToBeInserted = {}\n      <%_for(let i in USER_EXIST_CONDITION){_%>\n        userToBeInserted = await dbService.findOne(model.<%-AUTH_MODEL%>,<%-JSON.stringify(USER_EXIST_CONDITION[i])%>);\n        <%_var finalStr = new String();\n          USER[i].role=`@@authConstant.USER_ROLE.${ROLE_NAME[i]}@@`;\n          finalStr = JSON.stringify(USER[i]);\n          finalStr = finalStr.replace(/@@\"/g, \"\").replace(/\"@@/g, \"\");\n        _%>\n        if (!userToBeInserted) {  \n          userToBeInserted = <%-finalStr%>\n          await dbService.createOne(model.<%-AUTH_MODEL%>,userToBeInserted);\n        }else{\n          userToBeInserted = <%-finalStr%>\n          userToBeInserted.password = await bcrypt.hash(userToBeInserted.password, 8)\n          await dbService.updateMany(model.<%-AUTH_MODEL%>, <%-JSON.stringify(USER_EXIST_CONDITION[i])%>, userToBeInserted);\n        }\n      <%_}_%>\n      console.info('User model seeded 🍺');\n    }catch(error){\n      console.log('User seeder failed due to ', error.message)\n    }\n  }\n  \n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    /* seeds roles */\n    async function seedRole() {\n      try {\n        const roles = <%=ROLES%>;\n        const insertedRoles = await dbService.findAllRecords(model.role, { code: { [Op.in]: roles.map(role => role.toUpperCase()) } });\n        const rolesToInsert = [];\n        roles.forEach(role => {\n          if (!insertedRoles.find(insertedRole => insertedRole.code === role.toUpperCase())) {\n            rolesToInsert.push({\n              name: role,\n              code: role.toUpperCase(),\n              weight: 1\n            });\n          }\n        });\n        if (rolesToInsert.length) {\n          const result = await dbService.createMany(model.role, rolesToInsert);\n          if (result) console.log('Role seeded 🍺');\n          else console.log('Role seeder failed!');\n        } else {\n          console.log('Role is upto date 🍺');\n        }\n      } catch (error) {\n        console.log('Role seeder failed due to ', error.message);\n      }\n    }\n\n    /* seeds routes of project */\n    async function seedProjectRoutes(routes) {\n      try {\n        if (routes) {\n          let routeName = '';\n          const dbRoutes = await dbService.findAllRecords(model.projectRoute, {});\n          let routeArr = [];\n          let routeObj = {};\n          routes.forEach(route => {\n            routeName = `${replaceAll((route.path).toLowerCase(), '/', '_')}`;\n            route.methods.forEach(method => {\n              routeObj = dbRoutes.find(dbRoute => dbRoute.route_name === routeName && dbRoute.method === method);\n              if (!routeObj) {\n                routeArr.push({\n                  'uri': route.path.toLowerCase(),\n                  'method': method,\n                  'route_name': routeName,\n                });\n              }\n            });\n          });\n          if (routeArr.length) {\n            const result = await dbService.createMany(model.projectRoute, routeArr);\n            if (result) console.info('ProjectRoute model seeded 🍺');\n            else console.info('ProjectRoute seeder failed.');\n          } else {\n            console.info('ProjectRoute is upto date 🍺');\n          }\n        }\n      } catch (error) {\n        console.log('ProjectRoute seeder failed due to ', error.message);\n      }\n    }\n\n    /* seeds role for routes */\n    async function seedRouteRole() {\n      try{\n        const routeRoles =[ \n          <%_for(let i=0;i < ROUTE_ROLE_ARRAY.length;i++){_%>\n          <%=ROUTE_ROLE_ARRAY[i]%>,\n          <%_}_%>\n\n        ];\n        if (routeRoles && routeRoles.length) {\n          const routes = [...new Set(routeRoles.map(routeRole => routeRole.route.toLowerCase()))];\n          const routeMethods = [...new Set(routeRoles.map(routeRole => routeRole.method))];\n          const roles = <%=ROLES%>;\n          const insertedProjectRoute = await dbService.findAllRecords(model.projectRoute, {\n            uri: { [Op.in]: routes },\n            method: { [Op.in]: routeMethods },\n            'isActive': true,\n            'isDeleted': false\n          });\n          const insertedRoles = await dbService.findAllRecords(model.role, {\n            code: { [Op.in]: roles.map(role => role.toUpperCase()) },\n            'isActive': true,\n            'isDeleted': false\n          });\n          let projectRouteId = '';\n          let roleId = '';\n          let createRouteRoles = routeRoles.map(routeRole => {\n            projectRouteId = insertedProjectRoute.find(pr => pr.uri === routeRole.route.toLowerCase() && pr.method === routeRole.method);\n            roleId = insertedRoles.find(r => r.code === routeRole.role.toUpperCase());\n            if (projectRouteId && roleId) {\n              return {\n                roleId: roleId.id,\n                routeId: projectRouteId.id\n              };\n            }\n          });\n          createRouteRoles = createRouteRoles.filter(Boolean);\n          const routeRolesToBeInserted = [];\n          let routeRoleObj = {};\n    \n          await Promise.all(\n            createRouteRoles.map(async routeRole => {\n              routeRoleObj = await dbService.findOne(model.routeRole, {\n                routeId: routeRole.routeId,\n                roleId: routeRole.roleId,\n              });\n              if (!routeRoleObj) {\n                routeRolesToBeInserted.push({\n                  routeId: routeRole.routeId,\n                  roleId: routeRole.roleId,\n                });\n              }\n            })\n          );\n          if (routeRolesToBeInserted.length) {\n            const result = await dbService.createMany(model.routeRole, routeRolesToBeInserted);\n            if (result) console.log('RouteRole seeded 🍺');\n            else console.log('RouteRole seeder failed!');\n          } else {\n            console.log('RouteRole is upto date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('RouteRole seeder failed due to ', error.message)\n      }\n    }\n\n    /* seeds roles for users */\n    async function seedUserRole (){\n      try{\n        const userRoles = <%-JSON.stringify(USER_ROLE_ARRAY)%>;\n        const defaultRole = await dbService.findOne(model.role, { code: <%=DEFAULT_ROLE%> });\n        const insertedUsers = await dbService.findAllRecords(model.<%-AUTH_MODEL%>, { username: { [Op.in]: userRoles.map(userRole => userRole.username) } });\n        let user = {};\n        const userRolesArr = [];\n        userRoles.map(userRole => {\n          user = insertedUsers.find(user => user.username === userRole.username && user.isPasswordMatch(userRole.password) && user.isActive && !user.isDeleted);\n          if (user) {\n            userRolesArr.push({\n              userId: user.id,\n              roleId: defaultRole.id\n            });\n          }\n        });\n        let userRoleObj = {};\n        const userRolesToBeInserted = [];\n        if (userRolesArr.length) {\n          await Promise.all(\n            userRolesArr.map(async userRole => {\n              userRoleObj = await dbService.findOne(model.userRole, {\n                userId: userRole.userId,\n                roleId: userRole.roleId\n              });\n              if (!userRoleObj) {\n                userRolesToBeInserted.push({\n                  userId: userRole.userId,\n                  roleId: userRole.roleId\n                });\n              }\n            })\n          );\n          if (userRolesToBeInserted.length) {\n            const result = await dbService.createMany(model.userRole, userRolesToBeInserted);\n            if (result) console.log('UserRole seeded 🍺');\n            else console.log('UserRole seeder failed');\n          } else {\n            console.log('UserRole is upto date 🍺');\n          }\n        }\n      }catch(error){\n        console.log('UserRole seeder failed due to ', error.message)\n      }\n    }\n  <%_}_%>\n<%_}_%>\n\n/* calls of functions to seed mock data into multiple collections */\nasync function seedData(<%_if(IS_AUTH && SHOULD_ADD_ROLE_PERMISSION){_%>allRegisterRoutes<%_}_%>){\n<%_if(IS_AUTH){_%>\n  await seedUser();\n  <%_if(SHOULD_ADD_ROLE_PERMISSION){_%>\n    await seedRole();\n    await seedProjectRoutes(allRegisterRoutes);\n    await seedRouteRole();\n    await seedUserRole();\n  <%_}_%>\n<%_}_%>\n};\nmodule.exports = seedData;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/services/auth.js.ejs",
    "content": "/**\n * auth.js\n * @description :: service functions used in authentication\n */\nconst model = require(\"../model\")\nconst dbService = require(\"../utils/dbService\");\nconst { JWT,LOGIN_ACCESS,\n    PLATFORM<%_if(LOGIN_RETRY_LIMIT){_%>,MAX_LOGIN_RETRY_LIMIT,LOGIN_REACTIVE_TIME<%_}_%>\n    <%_if(RESET_PASSWORD){_%>,FORGOT_PASSWORD_WITH<%_}_%>\n    <%_if(MAX_DEVICE_ALLOWED){_%>,NO_OF_DEVICE_ALLOWED<%_}_%>} = require(\"../constants/authConstant\");\nconst jwt = require(\"jsonwebtoken\");\nconst common = require(\"../utils/common\");\nconst dayjs = require(\"dayjs\");\nconst bcrypt = require(\"bcrypt\");\nconst emailService = require(\"./email/emailService\");\nconst smsService = require(\"./sms/smsService\");\nconst {Op} = require('sequelize')\n<%_if(FORGOT_WITH_LINK){_%>\nconst uuid = require(\"uuid\").v4;\n<%_}_%>\n<%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS'){_%>\nconst ejs = require(\"ejs\");\n<%_}_%>\n\n/**\n* @description : service to generate JWT token for authentication.\n* @param {object} user : user who wants to login.\n* @param {string} secret : secret for JWT.\n* @return {string}  : returns JWT token.\n*/\nasync function generateToken(user,secret){\n    return jwt.sign( {id:user.id,'<%-LOGIN_WITH[0]%>':user.<%-LOGIN_WITH[0]%>}, secret, {\n        expiresIn: JWT.EXPIRES_IN * 60\n    });\n}\n\n/**\n* @description : service of login user.\n* @param {string} username : username of user.\n* @param {string} password : password of user.\n* @param {string} platform : platform of requested route to login, for platform identification.\n<%_if(ROLE_PERMISSION) {_%>\n* @param {boolean} roleAccess: a flag to request role access of user\n<%_}_%>\n* @return {object} : returns authentication status. {flag, data}\n*/\n    const loginUser = async(username,password,platform<%_if(ROLE_PERMISSION){_%>,roleAccess<%_}_%>) => {\n            try {\n                <%_ if(LOGIN_WITH.length>1){ _%>\n                let where = <%-MULTIPLE_LOGIN%>\n                <%_ }else{_%>\n                let where ={'<%-LOGIN_WITH[0]%>':username}\n                <%_}_%>                   \n                const user = await dbService.findOne(model.<%-MODEL%>,where);\n                if (user) {\n                    let userAuth = await dbService.findOne(model.userAuthSettings, { userId: user.id });\n                    <%_if(MAX_DEVICE_ALLOWED){_%>\n                        const userToken = await dbService.count(model.userTokens, { [Op.and]:{ tokenExpiredTime: { [Op.gt]: dayjs().toISOString() }, isTokenExpired: 0,userId:user.id} } );\n                        if(userToken >= NO_OF_DEVICE_ALLOWED){\n                            return {\n                                flag: true,\n                                data: \"You have reached your device limit\"\n                            }\n                        }\n                    <%_}_%>\n                    <%_if(LOGIN_RETRY_LIMIT){_%>\n                    if (userAuth && userAuth.<%-LOGIN_RETRY_LIMIT.key%> >= MAX_LOGIN_RETRY_LIMIT) {\n                        let now = dayjs();\n                        if (userAuth.loginReactiveTime) {\n                            let limitTime = dayjs(userAuth.loginReactiveTime);\n                            if (limitTime > now) {\n                            let expireTime = dayjs().add(LOGIN_REACTIVE_TIME, 'minute');\n                            if (!(limitTime > expireTime)){\n                                return {\n                                    flag:true,\n                                    data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,limitTime)}.`\n                                }; \n                            }  \n                            await dbService.updateMany(model.userAuthSettings, {userId:user.id}, {\n                                loginReactiveTime: expireTime.toISOString(),\n                                <%-LOGIN_RETRY_LIMIT.key%>: userAuth.<%-LOGIN_RETRY_LIMIT.key%> + 1\n                            });\n                            return {\n                                flag: true,\n                                data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                            };\n                            }else{\n                                await dbService.updateMany(model.userAuthSettings, {userId:user.id}, {\n                                    loginReactiveTime: null,\n                                    <%-LOGIN_RETRY_LIMIT.key%>: 0\n                                });\n                                userAuth = await dbService.findOne(model.userAuthSettings, { userId: user.id });\n                            }\n                        } else {\n                            // send error\n                            let expireTime = dayjs().add(LOGIN_REACTIVE_TIME, 'minute');\n                            await dbService.updateMany(model.userAuthSettings, {userId:user.id}, {\n                            loginReactiveTime: expireTime.toISOString(),\n                                <%-LOGIN_RETRY_LIMIT.key%>: userAuth.<%-LOGIN_RETRY_LIMIT.key%> + 1\n                            });\n                            return {\n                                flag: true,\n                                data:`you have exceed the number of limit.you can login after ${common.getDifferenceOfTwoDatesInTime(now,expireTime)}.`\n                            };\n                        }\n                        }\n                    <%_}_%>\n                    const isPasswordMatched = await user.isPasswordMatch(password);\n                    if (isPasswordMatched) {\n                        const {password,...userData}=user.toJSON()\n                        let token;\n                        if(!user.role){\n                            return {flag:true, data:'You have not assigned any role'}\n                        }\n                        <%_for(let i=0; i<PLATFORMS.length; i++){_%>\n                            <%_if(i===0){_%>\n                            if(platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}else{_%>\n                            else if(platform == PLATFORM.<%-PLATFORMS[i].toUpperCase()%>){\n                                if(!LOGIN_ACCESS[user.role].includes(PLATFORM.<%-PLATFORMS[i].toUpperCase()%>)){\n                                    return {flag:true, data:'you are unable to access this platform'}\n                                }\n                                token = await generateToken(userData,JWT.<%-PLATFORMS[i].toUpperCase()%>_SECRET)\n                            }\n                            <%_}_%>\n                        <%_}_%>                        \n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        if(userAuth && userAuth.<%-LOGIN_RETRY_LIMIT.key%>){\n                            await dbService.updateMany(model.userAuthSettings, {userId:user.id}, {\n                                <%-LOGIN_RETRY_LIMIT.key%>: 0,\n                                loginReactiveTime: null\n                            });\n                        }\n                        <%_}_%>\n                        let expire = dayjs().add(JWT.EXPIRES_IN, 'second').toISOString();\n                        await dbService.createOne(model.userTokens, { userId: user.id, token: token,tokenExpiredTime: expire });\n                        let userToReturn = { ...userData, token };\n                        <%_if(ROLE_PERMISSION){_%>\n                            let roleAccessData = {};\n                            if (roleAccess){\n                            roleAccessData = await common.getRoleAccessData(model,user.id);\n                            userToReturn = {\n                                ...userToReturn,\n                                roleAccess: roleAccessData\n                            };\n                            }\n                        <%_}_%>\n                        return {flag:false,data:userToReturn}\n                    } else {\n                        <%_if(LOGIN_RETRY_LIMIT){_%>\n                        await dbService.updateMany(model.userAuthSettings,{userId:user.id},{<%-LOGIN_RETRY_LIMIT.key%>:userAuth.<%-LOGIN_RETRY_LIMIT.key%>+1});\n                        <%_}_%>\n                        return {flag:true,data:'Incorrect Password'}\n                    }\n                } else {\n                    return {flag:true,data:'User not exists'}\n                }\n            } catch (error) {\n                throw new Error(error.message)\n            }\n    };\n\n/**\n* @description : service to change password.\n* @param {object} params : object of new password, old password and user id.\n* @return {object}  : returns status of change password. {flag,data}\n*/\n    const changePassword = async(params)=>{\n        try {\n            let password = params.newPassword;\n            let oldPassword = params.oldPassword;\n            let where = {id:params.userId};\n            let user = await dbService.findOne(model.<%-MODEL%>,where);\n            if (user && user.id) {\n                const isPasswordMatched = await user.isPasswordMatch(oldPassword);\n                if(!isPasswordMatched){\n                    return {flag:true,data:'Incorrect Old Password'};\n                }\n                password = await bcrypt.hash(password, 8);\n                let updatedUser = dbService.updateByPk(model.<%-MODEL%>,user.id,{<%-PASSWORD%>:password});\n                if (updatedUser) {\n                    return {flag:false,data:'Password changed successfully'};                \n                }\n                return {flag:true,data:'password can not changed due to some error.please try again'}\n            }\n            return {flag:true,data:'User not found'}\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    };\n\n/**\n* @description : service to send notification on reset password.\n* @param {object} user : user document\n* @return {}  : returns status where notification is sent or not\n*/\n    const sendResetPasswordNotification = async (user) => {\n        let resultOfEmail=false;\n        let resultOfSMS=false;\n        try {\n            <%_if(FORGOT_WITH_LINK){_%>\n            let token = uuid();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await dbService.updateMany(model.userAuthSettings, {userId:user.id},\n            {\n                resetPasswordCode: token, expiredTimeOfResetPasswordCode: expires\n            });\n            if(FORGOT_PASSWORD_WITH.LINK.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await dbService.findOne(model.<%-MODEL%>,{id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                };\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = { \n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>\",\n                    data:updatedUser\n                };\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = \"Click on the link below to reset your password.\";\n                let mailObj = {\n                    subject: \"Reset Password\",\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: \"/views/resetPassword\",\n                    data: {\n                        link: `http://localhost:${process.env.PORT}` + viewType + token,\n                        linkText: \"Reset Password\",\n                        message:msg\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;\n                }catch(error){\n                    console.log(error);\n                }\n            }\n            if(FORGOT_PASSWORD_WITH.LINK.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE ==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await dbService.findOne(model.<%-MODEL%>,{id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                <%_}else{_%>\n                let viewType = \"/reset-password/\";\n                let msg = `Click on the link to reset your password.\n                http://localhost:${process.env.PORT}${viewType + token}`;\n                let smsObj = {\n                    to:user.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{\n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){\n                    console.log(error)\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            <%_if(FORGOT_WITH_OTP){_%>\n            let otp = common.randomNumber();\n            let expires = dayjs();\n            expires = expires.add(FORGOT_PASSWORD_WITH.EXPIRE_TIME, \"minute\").toISOString();\n            await dbService.updateMany(model.userAuthSettings, {userId:user.id},\n            {\n                resetPasswordCode: token, expiredTimeOfResetPasswordCode: expires\n            });\n            if(FORGOT_PASSWORD_WITH.OTP.email){\n                <%_if(RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%> \n                let updatedUser= await dbService.findOne(model.<%-MODEL%>,{id:user.id});\n                <%_}_%>\n                <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0 && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template: '/views/<%- RESET_PASSWORD_TEMPLATE_NAME _%>',    \n                    data:{\n                        <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                        <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                        <%_}_%>\n                    }\n                }\n                <%_}else if(!RESET_PASSWORD_TEMPLATE_ATTRIBUTE && RESET_PASSWORD_TEMPLATE_NAME && RESET_PASSWORD_NOTIFICATION_TYPE==='EMAIL'){_%>\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>',\n                    data:updatedUser\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let mailObj = {\n                    subject: 'Your OTP',\n                    to: user.<%-EMAIL_FIELD%>,\n                    template:'/views/resetPassword',\n                    data: {\n                        isWidth: true,\n                        name: \"username\",\n                        email: user.<%-EMAIL_FIELD%> || '-',\n                        message: otpMsg,\n                        otp: otp\n                    }\n                };\n                <%_}_%>\n                try{\n                    await emailService.sendMail(mailObj);\n                    resultOfEmail = true;\n                }catch(error){ \n                    console.log(error);\n                } \n            }\n            if(FORGOT_PASSWORD_WITH.OTP.sms){\n                <%_if(RESET_PASSWORD_NOTIFICATION_TYPE==='SMS' && RESET_PASSWORD_TEMPLATE_NAME){_%> \n                let updatedUser= await dbService.findOne(model.<%-MODEL%>,{id:user.id});\n                let renderData = {\n                    <%_if(typeof RESET_PASSWORD_TEMPLATE_ATTRIBUTE === \"object\" && Object.keys(RESET_PASSWORD_TEMPLATE_ATTRIBUTE).length > 0){_%>\n                    <%_for(let i in RESET_PASSWORD_TEMPLATE_ATTRIBUTE){_%>\n                    <%-i%>:updatedUser.<%-RESET_PASSWORD_TEMPLATE_ATTRIBUTE[i].replace(/.*?\\./, \"\");%>,\n                    <%_}_%>\n                    <%_}else{_%>\n                    ...updatedUser\n                    <%_}_%>\n                }\n                const msg = await ejs.renderFile(`${__basedir}/views/<%-RESET_PASSWORD_TEMPLATE_NAME%>/html.ejs`, renderData);\n                let smsObj = {\n                    to:updatedUser.<%-MOBILE_FIELD%>,\n                    message:msg\n                }\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}else{_%>\n                let message = `OTP code for Reset password`;\n                let otpMsg = `${message}: ${otp}`;\n                let smsObj = {\n                    message: otpMsg,\n                    to: user.<%-MOBILE_FIELD%>,\n                };\n                try{ \n                    await smsService.sendSMS(smsObj);\n                    resultOfSMS = true;\n                }catch(error){ \n                    console.log(error);\n                }\n                <%_}_%>\n            }\n            <%_}_%>\n            return {resultOfEmail,resultOfSMS};\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    };\n    \n/**\n* @description : service to reset password.\n* @param {object} userId : user id\n* @param {string} newPassword : new password to be set.\n* @return {}  : returns status whether new password is set or not. {flag, data}\n*/\n    const resetPassword = async (userId, newPassword) => {\n        try {\n            let where = { id: userId };  \n            const dbUser = await dbService.findOne(model.<%-MODEL%>,where);\n            if (!dbUser) {\n                return {\n                    flag: true,\n                    data: \"User not found\",\n                };\n            }\n            newPassword = await bcrypt.hash(newPassword, 8);\n            let updatedUser = await dbService.updateByPk(model.<%-MODEL%>, userId, {\n                <%-PASSWORD%>: newPassword\n            });\n            if (!updatedUser) {\n                return {\n                  flag: true,\n                  data: 'Password is not reset successfully',\n                };\n              }\n            await dbService.updateMany(model.userAuthSettings, {userId:userId}, { resetPasswordCode: '', expiredTimeOfResetPasswordCode: null, <%-LOGIN_RETRY_LIMIT.key%>: 0 })\n            let mailObj = {\n                subject: 'Reset Password',\n                to: dbUser.<%-EMAIL_FIELD%>,\n                template: '/views/successfullyResetPassword',\n                data: {\n                    isWidth: true,\n                    email: dbUser.<%-EMAIL_FIELD%> || '-',\n                    message: \"Password Successfully Reset\"\n                }\n            };\n            await emailService.sendMail(mailObj);\n            return {\n                flag: false,\n                data: \"Password reset successfully\",\n            };\n        } catch (error) {\n            throw new Error(error.message)\n        }\n    };\n\nmodule.exports = {\n    loginUser,\n    changePassword,\n    sendResetPasswordNotification,\n    resetPassword\n}"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/services/customQueryService.js.ejs",
    "content": "/** \n * customQueryService.js\n * @description :: exports functions used in manipulating data from database\n */\n\nconst find = async (model,{\n    filter = {}, attributes=[], order=[] \n}) => {\n    const result = await model.findAll({\n      where: filter\n    },\n    {attributes: attributes},\n    {order: order})\n    return result;\n};\n\nmodule.exports = {\n    find,\n}\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/services/emailService.js.ejs",
    "content": "/** \n * emailService.js\n * @description :: exports function used in sending mails using mailgun provider\n */\n \nconst nodemailer = require('nodemailer');\nconst ejs = require(\"ejs\")\nmodule.exports = {\n    sendMail: async (obj) => {\n        let transporter = nodemailer.createTransport({\n            service: 'Mailgun',\n            auth: {\n                user: '',\n                pass: ''\n            }\n        });\n        if (!Array.isArray(obj.to)) {\n            obj.to = [obj.to];\n        }\n        const htmlText = await ejs.renderFile(`${__basedir}${obj.template}/html.ejs`, obj.data);\n\n        return await Promise.all(obj.to.map((emailId) => {\n            var mailOpts = {\n                from: obj.from || \"noreply@yoyo.co\",\n                to: emailId,\n                subject: obj.subject,\n                html: htmlText\n            };\n            transporter.sendMail(mailOpts, function (err, response) {\n                if (err) {\n                    //ret.message = \"Mail error.\";\n                } else {\n                    //ret.message = \"Mail send.\";\n                }\n            });\n        }));\n    }\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/services/smsService.js.ejs",
    "content": "/** \n * smsService.js\n * @description :: exports function used in sending sms using gupshup provider\n */\n\nconst axios = require('axios')\nconst sendSMS = async (obj) => {\n    console.log('SMS---', obj);\n    if (obj.to) {\n        obj.mobiles = obj.to;\n    }\n    let mobiles;\n    if (Array.isArray(obj.mobiles)) {\n        obj.mobiles = obj.mobiles.map((m) => {\n            let tmpNo = m.split('+');\n            return tmpNo[1] ? tmpNo[1] : tmpNo[0];\n        });\n        mobiles = obj.mobiles.join(',');\n    }\n    else {\n        let tmpNo = obj.mobiles.split('+');\n        mobiles = tmpNo[1] ? tmpNo[1] : tmpNo[0];\n    }\n    const message = obj.message\n    const userid = \"\"\n    const password = escape(\"You Password\")\n    const v = 1.1\n    const method = \"sendMessage\"\n    const msg_type = \"text\"\n    const send_to = mobiles\n    return await new Promise((resolve, reject) => {\n        axios(\n            {\n                url: `http://enterprise.smsgupshup.com/GatewayAPI/rest?msg=${message}&v=${v}&userid=${userid}&password=${password}&method=${method}&send_to=${send_to}&msg_type=${msg_type}`,\n                method: 'GET',\n            })\n            .then(function (response) {\n                let response1 = response.data.split('|');\n                console.log(response.data)\n                if (response1.length) {\n                    if (response1[0].trim() === 'error') {\n                        reject(response)\n                    } else {\n                        resolve(response)\n                    }\n                }\n            })\n            .catch(function (error) {\n                reject(error)\n            });\n    });\n}\nmodule.exports = { sendSMS }"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/common.js.ejs",
    "content": "/**\n * common.js\n * @description: exports helper methods for project.\n */\n\n<%_if(IS_AUTH){ _%>\nconst dbService = require('./dbService');\nconst { Op } = require('sequelize');\n<%_}_%>\n\n/**\n * replaceAll: find and replace all occurrence of a string in a searched string\n * @param {string} string  : string to be replace\n * @param {string} search  : string which you want to replace\n * @param {string} replace : string with which you want to replace a string\n * @return {string} : replaced new string\n */\nconst replaceAll = (string, search, replace) => string.split(search).join(replace); ;\n\n  /**\n * convertObjectToEnum : converts object to enum\n * @param {object} obj : object to be converted\n * @return {array} : converted array\n */\nconst convertObjectToEnum = (obj) => {\n    if (Array.isArray(obj)) {\n      return obj;\n    }\n    const enumArr = [];\n    Object.values(obj).map((val) => enumArr.push(String(val)));\n    return enumArr;\n  }\n\n/**\n * randomNumber : generate random numbers for given length\n * @param {number} length : length of random number to be generated (default 4)\n * @return {number} : generated random number\n */\nconst randomNumber = (length = 4) => {\n    const numbers = '12345678901234567890';\n    let result = '';\n    for (let i = length; i > 0; i -= 1) {\n      result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n    }\n    return result;\n  }\n  \n  <%_if(IS_AUTH){ _%>\n/**\n * uniqueValidation: check unique validation while user registration\n * @param {object} model : sequelize model instance of table\n * @param {object} data : data, coming from request\n * @return {boolean} : validation status\n */\nconst uniqueValidation = async (Model,data) =>{\n      <%_if (LOGIN_WITH.length > 1) {_%>\n      let filter = { [Op.or]:[]};\n      <%_for(let i in LOGIN_WITH){_%>\n      if(data && data[\"<%-LOGIN_WITH[i]%>\"]){\n          filter[Op.or].push(\n          <%_for(let j in LOGIN_WITH){_%>\n          {\"<%-LOGIN_WITH[j]%>\":data[\"<%-LOGIN_WITH[i]%>\"]},\n          <%_}_%>\n          )\n      }\n      <%_}_%>\n      <%_} else {_%>\n      let filter = {};\n      if(data && data[\"<%-LOGIN_WITH[0]%>\"]){\n          filter = { \"<%-LOGIN_WITH[0]%>\": data[\"<%-LOGIN_WITH[0]%>\"] }\n      }\n      <%_}_%>\n      let found = await dbService.findOne(Model,filter);\n      if(found){\n          return false;\n      }\n      return true;\n  }\n  <%_}_%>\n\n<%_if(IS_AUTH){_%>\n/**\n * getDifferenceOfTwoDatesInTime : get difference between two dates in time\n * @param {date} currentDate  : current date\n * @param {date} toDate  : future date\n * @return {string} : difference of two date in time\n */\n  const getDifferenceOfTwoDatesInTime = (currentDate,toDate) =>{\n    let hours = toDate.diff(currentDate,'hour');\n    currentDate =  currentDate.add(hours, 'hour');\n    let minutes = toDate.diff(currentDate,'minute');\n    currentDate =  currentDate.add(minutes, 'minute');\n    let seconds = toDate.diff(currentDate,'second');\n    currentDate =  currentDate.add(seconds, 'second');\n    if (hours){\n      return `${hours} hour, ${minutes} minute and ${seconds} second`; \n    }\n    return `${minutes} minute and ${seconds} second`; \n  };\n<%_}_%>\n  <%_if(ROLE_PERMISSION){ _%>\n/** \n * getRoleAccessData : returns role access of User\n * @param {object} model : sequelize model instance of tables\n * @param {int} userId : id of user to find role data\n * @return {object} : role access of user for APIs of model\n */\nconst getRoleAccessData = async (model,userId) =>{\n  let userRoles = await dbService.findAllRecords(model.userRole, { userId: userId });\n  let routeRoles = await dbService.findAllRecords(model.routeRole, { roleId: { [Op.in]: userRoles && userRoles.length ? userRoles.map(u=>u.roleId) : [] } },\n    {\n      include:[{\n        model: model.projectRoute,\n        as:'_routeId'\n      },{\n        model: model.role,\n        as: '_roleId'\n      }] \n    });\n  let models = Object.keys(model);\n  let Roles = routeRoles && routeRoles.length ? routeRoles.map(rr => rr._roleId && rr._roleId.name).filter((value, index, self) => self.indexOf(value) === index) : [];\n  let roleAccess = {};\n  if (Roles.length){\n    Roles.map(role => {\n      roleAccess[role] = {};\n      models.forEach(model => {\n        if (routeRoles && routeRoles.length) {\n          routeRoles.map(rr => {\n            if (rr._routeId && rr._routeId.uri.includes(model.toLowerCase()) && rr._roleId && rr._roleId.name === role) {\n              if (!roleAccess[role][model]) {\n                roleAccess[role][model] = [];\n              }\n              if (rr._routeId.uri.includes('create') && !roleAccess[role][model].includes('C')) {\n                roleAccess[role][model].push('C');\n              }\n              else if (rr._routeId.uri.includes('list') && !roleAccess[role][model].includes('R')) {\n                roleAccess[role][model].push('R');\n              }\n              else if (rr._routeId.uri.includes('update') && !roleAccess[role][model].includes('U')) {\n                roleAccess[role][model].push('U');\n              }\n              else if (rr._routeId.uri.includes('delete') && !roleAccess[role][model].includes('D')) {\n                roleAccess[role][model].push('D');\n              }\n            }\n          });\n        }\n      });\n    });\n  }\n  return roleAccess;\n};\n<%_}_%>\n\n  module.exports = {\n    convertObjectToEnum,\n    randomNumber,\n    replaceAll,\n    <%_if(IS_AUTH){ _%>\n    uniqueValidation,\n    getDifferenceOfTwoDatesInTime,\n    <%_}_%>\n    <%_if(ROLE_PERMISSION){ _%>\n    getRoleAccessData,\n    <%_}_%>\n  };"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/dbService.js",
    "content": "/**\n * dbService.js\n * @description: exports all database related methods\n */\n/* eslint-disable import/no-unresolved */\nconst { Op } = require('sequelize');\n\nconst OPERATORS = ['and', 'or', 'like', 'in', 'eq', 'gt', 'lt', 'gte', 'lte', 'any', 'between'];\n\n/*\n * @description : create any record in database\n * @param  {object} model : sequelize model\n * @param  {object} data : {}\n * @return {object} result : database result\n */\nconst createOne = async (model, data) => {\n  const result = await model.create(data);\n  return result;\n};\n\n/*\n * @description : create many records in database\n * @param  {object} model : sequelize model\n * @param  {object} data : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst createMany = async (model, data) => {\n  if (data && data.length > 0) {\n    const result = await model.bulkCreate(data);\n    return result;\n  }\n  throw new Error('send array as input in create many method');\n};\n\n/*\n * @description : update record in database by id\n * @param  {object} model : sequelize model\n * @param  {*} pk : primary field of table\n * @param {object} data : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst updateByPk = async (model, pk, data) => {\n  let result = await model.update(data, {\n    returning: true,\n    where: { [model.primaryKeyField]: pk },\n  });\n  if (result) {\n    result = await model.findOne({ where: { [model.primaryKeyField]: pk } });\n  }\n  return result;\n};\n\n/*\n * @description : update many records in database by query\n * @param  {object} model : sequelize model\n * @param  {*} pk : primary field of table\n * @param {object} data : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst updateMany = async (model, query, data) => {\n  const result = await model.update(data, {\n    returning: true,\n    where: query,\n  });\n  return result;\n};\n\n/*\n * @description : delete any record in database by primary key\n * @param  {object} model : sequelize model\n * @param  {*} pk : primary field of table\n * @return {object} result : database result\n */\nconst deleteByPk = async (model, pk) => {\n  const result = await model.destroy({ where: { [model.primaryKeyField]: pk } });\n  return result;\n};\n\n/*\n * @description : delete many record in database by query\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @return {object} result : database result\n */\nconst deleteMany = async (model, query) => {\n  const result = await model.destroy({ where: query });\n  return result;\n};\n\n/*\n * @description : find single record from table by query\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst findOne = async (model, query, options = {}) => {\n  const result = await model.findOne({\n    where: query,\n    ...options,\n  });\n  return result;\n};\n\n/*\n * @description : find multiple records from table by query\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst findMany = async (model, query, options = {}) => {\n  options = {\n    where: { ...query },\n    ...options,\n  };\n  const result = await model.paginate(options);\n  const data = {\n    data: result.docs,\n    paginator: {\n      itemCount: result.total,\n      perPage: options.paginate || 25,\n      pageCount: result.pages,\n      currentPage: options.page || 1,\n    },\n  };\n  return data;\n};\n\n/*\n * @description : find all records from table\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst findAllRecords = async (model, query, options = {}) => {\n  options = {\n    where: { ...query },\n    ...options,\n  };\n  const result = await model.findAll(options);\n  return result;\n};\n\n/*\n * @description : deactivate record by primary key\n * @param  {object} model : sequelize model\n * @param  {*} pk : primary key field\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst softDeleteByPk = async (model, pk, options = {}) => {\n  const result = await model.update(\n    { isDeleted: true },\n    {\n      fields: ['isDeleted'],\n      where: { [model.primaryKeyField]: pk },\n      ...options,\n    },\n  );\n  return result;\n};\n\n/*\n * @description : deactivate records by query\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @param  {object} data : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst softDeleteMany = async (model, query, options = {}, loggedInUserId) => {\n  let result;\n  if (loggedInUserId !== undefined) {\n    result = await model.update(\n      {\n        isDeleted: true,\n        updatedBy: loggedInUserId,\n      },\n      {\n        fields: ['isDeleted'],\n        where: query,\n        ...options,\n      },\n    );\n  } else {\n    result = await model.update(\n      { isDeleted: true },\n      {\n        fields: ['isDeleted'],\n        where: query,\n        ...options,\n      },\n    );\n  }\n  return result;\n};\n\n/*\n * @description : count total records from table by query\n * @param  {object} model : sequelize model\n * @param  {object} query : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst count = async (model, query, options = {}) => {\n  const result = await model.count({\n    where: query,\n    ...options,\n  });\n  return result;\n};\n\n/*\n * @description : get record by primary key\n * @param  {object} model : sequelize model\n * @param  {object} param : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst findByPk = async (model, param, options = {}) => {\n  const result = await model.findByPk(param, options);\n  return result;\n};\n\n/*\n * @description : upsert record in database\n * @param  {object} model : sequelize model\n * @param  {object} param : {}\n * @param {object} options : {}\n * @return {object} result : database result\n */\nconst upsert = async (model, data, options = {}) => {\n  const result = await model.upsert(data, options);\n  return result;\n};\n\n/*\n * @description : parser for query builder\n * @param  {object} data : {}\n * @return {object} data : query\n */\nconst queryBuilderParser = (data) => {\n  if (data) {\n    Object.entries(data).forEach(([key]) => {\n      if (typeof data[key] === 'object') {\n        queryBuilderParser(data[key]);\n      }\n      if (OPERATORS.includes(key)) {\n        data[Op[key]] = data[key];\n        delete data[key];\n      } else if (key === 'neq') {\n        data[Op.not] = data[key];\n        delete data[key];\n      } else if (key === 'nin') {\n        data[Op.notIn] = data[key];\n        delete data[key];\n      }\n    });\n  }\n\n  return data;\n};\n\n/*\n * @description : parser for query builder of sort\n * @param  {object} input : {}\n * @return {object} data : query\n */\nconst sortParser = (input) => {\n  const newSortedObject = [];\n  if (input) {\n    Object.entries(input).forEach(([key, value]) => {\n      if (value === 1) {\n        newSortedObject.push([key, 'ASC']);\n      } else if (value === -1) {\n        newSortedObject.push([key, 'DESC']);\n      }\n    });\n  }\n  return newSortedObject;\n};\n\nmodule.exports = {\n  createOne,\n  createMany,\n  updateByPk,\n  updateMany,\n  findOne,\n  findMany,\n  findByPk,\n  deleteByPk,\n  deleteMany,\n  softDeleteByPk,\n  count,\n  softDeleteMany,\n  upsert,\n  queryBuilderParser,\n  sortParser,\n  findAllRecords,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/deleteDependentService1.js.ejs",
    "content": "<%_ \nfunction getRandomInt(max) {\n    return Math.floor(Math.random() * max);\n}\nfunction getRandomInt(length = 4){\n        let numbers = '12345678901234567890';\n        let result = '';\n        for (let i = length; i > 0; --i) {\n            result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n        }\n        return result;\n    }\n_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nlet <%-model_FC%> = require(\"../model/<%-model%>\")\n<%_}_%>\nlet dbService = require(\"./dbService\");\nconst { Op } = require('sequelize');\n\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst delete<%-model_FC%> = async (filter) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.findAll({where:filter,attributes:{include:\"id\"}});\n        if(<%-model.toLowerCase()%> && <%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj.id);\n            <%_(DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}`\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {[Op.in]: <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await delete<%-eModel%>(<%-modelFilter%>);\n            <%_})_%>\n            return await <%-model_FC%>.destroy({where :filter})\n        }else{\n            return \"No <%-model%> found.\"\n        }\n    <%_}else{_%>\n        return await <%-model_FC%>.destroy({where: filter});\n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst count<%-model_FC%> = async (filter) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.findAll({where:filter,attributes:{include:\"id\"}});\n        if(<%-model.toLowerCase()%> && <%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj.id);\n            <%_ let newCntModelName = [];\n            (DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}Cnt`\n                newCntModelName.push(modelNewName)\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {[Op.in]: <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await count<%-eModel%>(<%-modelFilter%>);\n            <%_})_%>\n            const <%-model%>Cnt =  await <%-model_FC%>.count(filter)\n            let response = {<%-model%> : <%-model%>Cnt  }\n            response = {\n                ...response,\n                <%_ newCntModelName.forEach((cntModel)=>{_%>\n                    ...<%-cntModel%>,\n                <%_})_%>\n            }\n            return response;\n        }\n    <%_}else{_%>\n        const <%-model%>Cnt =  await <%-model_FC%>.count(filter);\n        return {<%-model%> : <%-model%>Cnt}\n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n<%_for(var model in DELETE_DEPENDENCY){\n    let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\nconst softDelete<%-model_FC%> = async (filter,loggedInUserId) =>{\n    try{\n    <%_if(DELETE_DEPENDENCY[model] && DELETE_DEPENDENCY[model].length){_%>\n        let <%-model.toLowerCase()%> = await <%-model_FC%>.findAll({where:filter,attributes:{include:\"id\"}});\n        if(<%-model.toLowerCase()%> && <%-model.toLowerCase()%>.length){\n            <%-model.toLowerCase()%> = <%-model.toLowerCase()%>.map((obj) => obj.id);\n            <%_(DELETE_DEPENDENCY[model]).forEach((element) => { \n                const eModel = (element.model).charAt(0).toUpperCase() + (element.model).slice(1);\n                const modelFilter = `${element.model}Filter${getRandomInt(4)}`\n                const modelNewName = `${element.model}${getRandomInt(4)}`\n            _%>\n            const <%-modelFilter%> = {<%=element.refId%>: {[Op.in]: <%-model.toLowerCase()%>}}\n            const <%-modelNewName%> = await softDelete<%-eModel%>(<%-modelFilter%>,loggedInUserId);\n            <%_})_%>\n            if(loggedInUserId){\n                return await <%-model_FC%>.update(\n                    {isDeleted:true, updatedBy:loggedInUserId},{\n                    fields: ['isDeleted','updatedBy'],\n                    where: filter ,\n                    });\n            }else{\n                return await <%-model_FC%>.update(\n                    {isDeleted:true},{\n                    fields: ['isDeleted'],\n                    where: filter ,\n                    });\n            }\n \n        }else{\n            return \"No <%-model%> found.\"\n        }\n    <%_}else{_%>\n        if(loggedInUserId){\n            return await <%-model_FC%>.update(\n                {isDeleted:true,updatedBy:loggedInUserId},{\n                fields: ['isDeleted','updatedBy'],\n                where: filter ,\n                });\n        }else{\n            return await <%-model_FC%>.update(\n                {isDeleted:true},{\n                fields: ['isDeleted'],\n                where: filter,\n                });\n        }\n        \n    <%_}_%>\n    }catch(error){\n        throw new Error(error.message);\n    }\n}\n\n<%_}_%>\n\n\nmodule.exports ={\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    delete<%-model_FC%>,\n    <%_}_%>\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    count<%-model_FC%>,\n    <%_}_%>\n    <%_for(var model in DELETE_DEPENDENCY){\n        let model_FC = (model).charAt(0).toUpperCase() + (model).slice(1); _%>\n    softDelete<%-model_FC%>,\n    <%_}_%>\n}\n\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/response/index.js",
    "content": "const responseStatus = require('./responseStatus');\n\nmodule.exports = {\n  success: (data = {}) => ({\n    status: responseStatus.success,\n    message: data.message || 'Your request is successfully executed',\n    data: data.data || {},\n  }),\n\n  failure: (data = {}) => ({\n    status: responseStatus.failure,\n    message: data.message || 'Some error occurred while performing action.',\n    data: data.data || {},\n  }),\n\n  internalServerError: (data = {}) => ({\n    status: responseStatus.serverError,\n    message: data.message || 'Internal server error.',\n    data: data.data || {},\n  }),\n\n  badRequest: (data = {}) => ({\n    status: responseStatus.badRequest,\n    message: data.message || 'Request parameters are invalid or missing.',\n    data: data.data || {},\n  }),\n\n  recordNotFound: (data = {}) => ({\n    status: responseStatus.recordNotFound,\n    message: data.message || 'Record(s) not found with specified criteria.',\n    data: data.data || {},\n  }),\n\n  validationError: (data = {}) => ({\n    status: responseStatus.validationError,\n    message: data.message || `Invalid Data, Validation Failed.`,\n    data: data.data || {},\n  }),\n\n  unAuthorized: (data = {}) => ({\n    status: responseStatus.unauthorized,\n    message: data.message || 'You are not authorized to access the request',\n    data: data.data || {},\n  }),\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/response/responseCode.js",
    "content": "module.exports = {\n  success: 200,\n  badRequest: 400,\n  internalServerError: 500,\n  unAuthorized: 401,\n  notFound: 404,\n  validationError: 422,\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/response/responseHandler.js",
    "content": "/**\n * responseHandler.js\n * @description :: exports all handlers for response format.\n */\nconst responseBody = require('./index');\nconst responseCode = require('./responseCode');\n\n/**\n *\n * @param {obj} req : request from controller.\n * @param {obj} res : response from controller.\n * @param {*} next : executes the middleware succeeding the current middleware.\n */\nconst responseHandler = (req, res, next) => {\n  res.success = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.success(data));\n  };\n  res.failure = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.failure(data));\n  };\n  res.internalServerError = (data = {}) => {\n    res.status(responseCode.internalServerError).json(responseBody.internalServerError(data));\n  };\n  res.badRequest = (data = {}) => {\n    res.status(responseCode.badRequest).json(responseBody.badRequest(data));\n  };\n  res.recordNotFound = (data = {}) => {\n    res.status(responseCode.success).json(responseBody.recordNotFound(data));\n  };\n  res.validationError = (data = {}) => {\n    res.status(responseCode.validationError).json(responseBody.validationError(data));\n  };\n  res.unAuthorized = (data = {}) => {\n    res.status(responseCode.unAuthorized).json(responseBody.unAuthorized(data));\n  };\n  next();\n};\n\nmodule.exports = responseHandler;\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/response/responseStatus.js",
    "content": "module.exports = {\n  success: 'SUCCESS',\n  failure: 'FAILURE',\n  serverError: 'SERVER_ERROR',\n  badRequest: 'BAD_REQUEST',\n  recordNotFound: 'RECORD_NOT_FOUND',\n  validationError: 'VALIDATION_ERROR',\n  unauthorized: 'UNAUTHORIZED',\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/validateRequest.js",
    "content": "/**\n * @description : validate request body parameter with joi.\n * @param {object} payload : body from request.\n * @param {object} schemaKeys : model wise schema keys. ex. user validation object.\n * @returns : returns validation with message {isValid, message}\n */\n\nexports.validateParamsWithJoi = (payload, schemaKeys) => {\n  const { error } = schemaKeys.validate(payload, { abortEarly: false });\n  if (error) {\n    const message = error.details.map((el) => el.message).join('\\n');\n    return {\n      isValid: false,\n      message,\n    };\n  }\n  return { isValid: true };\n};\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/utils/validation/validateSchema.js.ejs",
    "content": "/**\n * <%-MODEL_NAME%>Validation.js\n * @description :: validate each post and put request as per <%-MODEL_NAME%> model\n */\n\n<%let flag=0%>\nconst joi = require(\"joi\");\n<%_if(typeof IS_AUTH!==\"undefined\" && IS_AUTH){_%>\nconst {USER_ROLE} = require(\"../../constants/authConstant\");\nconst {convertObjectToEnum} = require(\"../common\");  \n<%flag=1%> \n<%_}_%>\n<%_if(ENUM_VALIDATION){_%>\n<%_if(!IS_AUTH){_%>\nconst {convertObjectToEnum} = require(\"../common\");  \n<%_}_%>        \n<%_for(let enumIndex of ENUM_VALIDATION){_%>\nconst <%-enumIndex%>Default=require('../../constants/<%-enumIndex%>');    \n<%_}_%>       \n<%_}_%>    \n<%_ if(typeof VARIABLES !== \"undefined\") {\nfor(let i=0;i< VARIABLES.length; i++) {_%>\n<%-VARIABLES[i]%>\n<%_ } } _%>\n/** validation keys and properties of <%-MODEL_NAME%> */\nexports.schemaKeys = joi.object(<%-VALIDATION_KEY%>).unknown(true);\n\n/** validation keys and properties of <%-MODEL_NAME%> for updation */\nexports.updateSchemaKeys = joi.object(<%-UPDATE_VALIDATION_KEY%>).unknown(true);\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/views/emailTemplate.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <!-- message -->\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear ,</b>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/views/index.ejs",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n  <link href=\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\" rel=\"stylesheet\">\n  <link rel=\"icon\" type=\"image/png\" href=\"https://dxuoui1db8w1y.cloudfront.net/index.png?o=g\">\n  <title>welcome to node.js</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n\n    body {\n      font-family: 'Courier Prime', monospace;\n      height: 100vh;\n      background-color: #181818;\n      display: flex;\n    }\n    .sidebar{\n      height: 100vh;\n    }\n    .main-section{\n      padding: 100px;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n    }\n    h1{\n      color: #ffffff;\n      font-weight: 100;\n      font-size: 4vw;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <img class=\"sidebar\" src=\"https://dxuoui1db8w1y.cloudfront.net/sidebar.jpg?o=g\" alt=\"sidebar\">\n  </div>\n  <div class=\"main-section\">\n    <div>\n      <div style=\"display: flex; justify-content: space-between; margin-bottom: 50px;\">\n        <img src=\"https://dxuoui1db8w1y.cloudfront.net/dhiwise.png?o=g\" alt=\"dhiwise\" style=\"width: 130px;\">\n      </div>\n    <h1><br>Welcome to <span style=\"color: #3E863D;\">Node.Js</span><br>application </h1>\n  </div>\n  </div>\n</body>\n\n</html>"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/views/resetPassword.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        <%-message%>\n                    </div>\n                </div>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/views/resetPasswordLink.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        Reset Password Link\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,<%-message%></b>\n                </p>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    <a href=\"<%-link%>\"><%-linkText%></a>\n                </p>\n            </td>\n        </tr>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/templates/mvcSequelize/views/sendOTP.ejs",
    "content": "<table role=\"presentation\" style=\"padding: 26px;border-collapse:collapse;border-spacing:0px;width: 100%;\"\n    cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n    <tbody>\n        <tr>\n            <td style=\" padding: 10px 10px 20px 10px;\">\n                <div>\n                    <div style=\"font-size:20px;font-weight:bold;line-height:24px;text-align:left;color:#212b35;\">\n                        OTP\n                    </div>\n                </div>\n            </td>\n        </tr>\n        <tr>\n            <td>\n                <p style=\"font-size: 14px;color: #000;\">\n                    <b>Dear User,</b>\n                </p>\n            </td>\n        </tr>\n        <% if(otp) { %>\n        <tr>\n            <td>\n                <p style=\"margin-top: 5px;margin-bottom: 15px;font-size: 14px;line-height: 1.8;color: #000;\">\n                    Your OTP code is <strong> <%- otp %></strong>\n                </p>\n            </td>\n        </tr>\n        <% } %>\n    </tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n</div>\n</td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n\n"
  },
  {
    "path": "packages/server/usecase/application/node-generator/writeOperations/index.js",
    "content": "/* eslint-disable func-names */\n/* eslint-disable no-multi-assign */\n/* eslint-disable no-console */\nconst ejs = require('ejs');\nconst fs = require('fs');\nconst mkdirp = require('mkdirp');\nconst path = require('path');\nconst minimatch = require('minimatch');\n\nconst TEMPLATE_DIR = path.join(`${__dirname}/../`, 'templates');\nconst util = require('util');\n\nconst MODE_0755 = 0o0755;\nconst MODE_0666 = 0o0666;\n\nglobal.MODE_0755 = MODE_0755;\nglobal.MODE_0666 = MODE_0666;\n\nconst writeOperations = module.exports = {};\n\nwriteOperations.copyTemplateMulti = function (fromDir, toDir, nameGlob) {\n  fs.readdirSync(path.join(TEMPLATE_DIR, fromDir))\n    .filter(minimatch.filter(nameGlob, { matchBase: true }))\n    .forEach((name) => {\n      writeOperations.copyTemplate(path.join(fromDir, name), path.join(toDir, name));\n    });\n};\nwriteOperations.copyTemplate = function (from, to) {\n  writeOperations.write(to, fs.readFileSync(path.join(TEMPLATE_DIR, from), 'utf-8'));\n};\nwriteOperations.mkdir = function (base, dir) {\n  const loc = path.join(base, dir);\n  console.log(`   \\x1b[36mcreate\\x1b[0m : ${loc}${path.sep}`);\n  mkdirp.sync(loc, MODE_0755);\n};\nwriteOperations.loadTemplate = function (name) {\n  // console.log(__dirname)\n  const contents = fs.readFileSync(path.join(`${__dirname}/../`, 'templates', (`${name}.ejs`)), 'utf-8');\n  const locals = Object.create(null);\n  function render () {\n    return ejs.render(contents, locals, { escape: util.inspect });\n  }\n  return {\n    locals,\n    render,\n  };\n};\nwriteOperations.write = function (file, str, mode, flag = 'w') {\n  fs.writeFileSync(file, str, {\n    mode: mode || MODE_0666,\n    flag,\n  });\n  console.log(`   \\x1b[36mcreate\\x1b[0m : ${file}`);\n};\n"
  },
  {
    "path": "packages/server/usecase/application/openCode.js",
    "content": "/* global __appRootDir,MESSAGE */\nconst { spawn } = require('child_process');\nconst path = require('path');\n\nconst openCode = () => async (params) => {\n  try {\n    const command = `cd \"${path.join(__appRootDir, 'output', params.generatedId, params.name)}\" && code .`;\n    const response = await new Promise((resolve) => {\n      const child = spawn(command, { shell: true });\n      child.on('close', async () => {\n        resolve(MESSAGE.OK);\n        child.kill(0);\n      });\n    });\n    return response;\n  } catch (error) {\n    return MESSAGE.SERVER_ERROR;\n  }\n};\n\nmodule.exports = openCode;\n"
  },
  {
    "path": "packages/server/usecase/application/paginate.js",
    "content": "/* global MESSAGE, */\n\nconst paginate = (applicationRepo) => async ({\n  params, search, fields,\n}) => {\n  try {\n    /*\n     * if (!params.projectId) {\n     *   return INVALID_REQUEST_PARAMS;\n     * }\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    const filter = { find: params };\n    if (fields) {\n      filter.fields = fields;\n    }\n\n    if (search) {\n      filter.search = search;\n    }\n\n    const response = {\n      list: await applicationRepo.getDetails(filter),\n      count: await applicationRepo.getCount(filter),\n    };\n    return {\n      ...MESSAGE.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/application/structure.js",
    "content": "/* global MESSAGE,_ */\nconst fs = require('fs');\nconst os = require('os');\nconst mongoose = require('mongoose');\n\nconst homedir = os.homedir();\nconst {\n  COMPLETED, FAILED, QUEUE_BUILD_REJECTED,\n} = require('../../models/constants/application').IN_PROCESS_STATUS;\nconst {\n  TXT_FILE_EXTENSION, IMAGE_FILE_EXTENSION, TXT_SECOND_LAST_FILE_EXTENSION, EXTENSION_TYPE,\n} = require('../../constants/common');\nconst viewUsecase = require('./view');\n\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst {\n  BAD_REQUEST, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nfunction getFiles (dir, allFiles = [], parent = '') {\n  const outPut = allFiles || [];\n  const files = fs.readdirSync(dir);\n  /*\n   * Object.keys(files).forEach(function(key) {\n   *   yield put(setCurrentValue(key, currentValues[key]));\n   * })\n   */\n  files.forEach((file) => {\n    const name = `${dir}/${file}`;\n    if (fs.statSync(name).isDirectory()) {\n      if (file !== '.git') {\n        outPut.push({\n          name: file,\n          path: `${parent}/${file}`,\n          type: 2,\n          child: getFiles(name, [], `${parent}/${file}`),\n        });\n      }\n    } else {\n      // check file extension and assign value type wise\n      const lastIndex = file.lastIndexOf('.');\n      const secondLastIndex = file.lastIndexOf('.', file.lastIndexOf('.') - 1);\n      const fileExtension = file.substring(lastIndex + 1);\n      const fileExtensionSecondLast = file.substring(secondLastIndex + 1, lastIndex);\n      let extType = EXTENSION_TYPE.DEFAULT;\n      if (TXT_FILE_EXTENSION.includes(fileExtension.toUpperCase())) {\n        extType = EXTENSION_TYPE.TEXT;\n      } else if (IMAGE_FILE_EXTENSION.includes(fileExtension.toUpperCase())) {\n        extType = EXTENSION_TYPE.IMAGE;\n      } else if (TXT_SECOND_LAST_FILE_EXTENSION.includes(fileExtensionSecondLast.toUpperCase())) {\n        extType = EXTENSION_TYPE.TEXT;\n      }\n\n      outPut.push({\n        name: file,\n        path: `${parent}/${file}`,\n        type: 1,\n        extType,\n      });\n    }\n  });\n  /*\n   * for (const i of files) {\n   *   const name = `${dir}/${files[i]}`;\n   *   if (fs.statSync(name).isDirectory()) {\n   *     outPut.push({\n   *       name: files[i],\n   *  path: `${parent}/${files[i]}`,\n   *  type: 2,\n   * child: getFiles(name, [], `${parent}/${files[i]}`),\n   *     });\n   *   } else {\n   *     outPut.push({ name: files[i], path: `${parent}/${files[i]}`, type: 1 });\n   *   }\n   * }\n   */\n  return outPut;\n}\nconst useCase = (applicationRepo, schemaRepo, generatorRepo, projectRepo) => async (params) => {\n  try {\n    if (!params.applicationId) {\n      return {\n        ...BAD_REQUEST,\n        data: {},\n      };\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return {\n          ...BAD_REQUEST,\n          data: {},\n        };\n      }\n    }\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n    const project = applicationData?.data;\n    let filter = { id: project?.generatedId };\n    let generated = await generatorRepo.getById(filter);\n    const mainGenerated = _.cloneDeep(generated);\n    if (!generated) {\n      filter = {\n        find: {\n          _id: project?.tempGeneratedId,\n          'inProcessStatus.build_app': { $in: [COMPLETED, FAILED, QUEUE_BUILD_REJECTED] },\n        },\n      };\n      generated = await generatorRepo.get(filter);\n      if (!generated) {\n        return {\n          ...BAD_REQUEST,\n          data: {},\n        };\n      }\n    }\n    // tempGeneratedIdData return\n    let tempGenerated;\n    if (project.tempGeneratedId) {\n      const tempFilter = { id: project.tempGeneratedId };\n      tempGenerated = await generatorRepo.getById(tempFilter);\n      if (!tempGenerated) {\n        return {\n          ...BAD_REQUEST,\n          data: {},\n        };\n      }\n    }\n\n    let path = `${homedir}${generated.config.generatorPath}/${generated._id}/${project.name}`;\n    // For getting react final code project file\n    if (params.isReact) {\n      path = `${path}_REACT`;\n    }\n    /*\n     * console.log('path=========================>', path);\n     * console.log('generated=========================>', generated);\n     */\n    if (!fs.existsSync(path)) {\n      return {\n        ...BAD_REQUEST,\n        data: null,\n      };\n    }\n    const fileData = getFiles(path, [], '');\n    let appData = await (viewUsecase(applicationRepo, projectRepo))({ id: params.applicationId });\n    if (appData.data) {\n      appData = appData.data;\n      if (appData.application) {\n        appData.application = appData.application.toObject();\n        appData.application.generatedIdData = _.pick(mainGenerated, ['type', 'status', 'createdAt', 'updatedAt', '_id', 'versionNumber', 'semanticVersionNumber', 'tempGeneratedId']);\n        appData.application.tempGeneratedIdData = _.pick(tempGenerated, ['type', 'status', 'createdAt', 'updatedAt', '_id', 'versionNumber', 'semanticVersionNumber', 'tempGeneratedId']);\n      }\n    } else {\n      appData = {};\n    }\n    return {\n      ...OK,\n      data: {\n        list: fileData,\n        ...appData,\n      },\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/application/update.js",
    "content": "/* global MESSAGE ,_ */\nconst mongoose = require('mongoose');\nconst dayjs = require('dayjs');\nconst { DEFAULT_POLICY_NAME } = require('../../models/constants/application');\nconst {\n  getAdditionalJsonAuthOptions, getAdditionalJsonWithoutAuthOptions, schemaJsonAuthOptions, schemaJsonOptions,\n} = require('../schema/util/staticData');\nconst {\n  INVALID_REQUEST_PARAMS,\n  APPLICATION_UPDATED, SERVER_ERROR, OK,\n} = require('../../constants/message').message;\nconst { VALIDATION_RULES } = require('../../constants/validation');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst { applicationUpdateValidation } = require('../util/validation/applicationUpdate');\n\nconst applicationUpdateFields = ['name', 'description', 'stepInput.packageName', 'stepInput.bundleId', 'configInput'];\n\nconst SchemaDetailsRepository = require('../../repo/schemaDetail');\nconst ProjectRouteRepository = require('../../repo/projectRoute');\nconst ApplicationConfigRepository = require('../../repo/applicationConfig');\n\nconst schemaDetailsRepo = new SchemaDetailsRepository();\nconst projectRouteRepo = new ProjectRouteRepository();\nconst applicationConfigRepo = new ApplicationConfigRepository();\n\nconst RouteDeleteUseCase = require('../projectRoute/deleteDependency');\nconst getPermissionWiseRoute = require('../util/getPermissionWiseRoute');\nconst routeInsertManyUseCase = require('../projectRoute/insertMany');\n\n/**\n * Function used to update schema-details and project-routes.\n * @param  {} {schemaRepo\n * @param  {} applicationRepo\n * @param  {} updatedApp\n * @param  {} }\n */\nasync function updateSchemaDetailsAndRoutes ({\n  schemaRepo, applicationRepo, updatedApp, definitionCode,\n}) {\n  try {\n    if (updatedApp?.configInput?.platform) {\n      const platforms = updatedApp.configInput.platform;\n\n      // Get login-access platform.\n      let uniqPlatform = [];\n      _.each(updatedApp.configInput.loginAccess, (v) => {\n        uniqPlatform = uniqPlatform.concat(v);\n      });\n      uniqPlatform = _.uniq(uniqPlatform);\n\n      // Get all schemas\n      const schemas = await schemaRepo.getDetails({ find: { applicationId: updatedApp._id } });\n      if (schemas && schemas.length > 0) {\n        const schemaIds = _.map(schemas, '_id');\n\n        const schemaDetails = await schemaDetailsRepo.getDetails({ find: { schemaId: schemaIds } });\n\n        if (schemaDetails && schemaDetails.length > 0) {\n          for (let i = 0; i < schemaDetails.length; i += 1) {\n            const schemaDetail = schemaDetails[i];\n\n            const {\n              schemaJson, additionalJson,\n            } = schemaDetail;\n\n            const schemaJsonPlatforms = _.keys(schemaJson);\n            const schemaPlatformDiff = _.difference(schemaJsonPlatforms, platforms);\n\n            // Remove platforms from schemaJson, which are not available in application platforms.\n            if (schemaPlatformDiff && schemaPlatformDiff.length > 0) {\n              _.map(schemaPlatformDiff, (val) => {\n                delete schemaJson[val];\n              });\n            }\n\n            const additionalJsonPlatforms = _.keys(additionalJson.additionalSetting);\n            const additionalJsonPlatformDiff = _.difference(additionalJsonPlatforms, platforms);\n\n            // Remove platforms from additionalJson, which are not available in application platforms.\n            if (additionalJsonPlatformDiff && additionalJsonPlatformDiff.length > 0) {\n              _.map(additionalJsonPlatformDiff, (val) => {\n                delete additionalJson.additionalSetting[val];\n              });\n            }\n\n            for (let p = 0; p < platforms.length; p += 1) {\n              const platform = platforms[p];\n\n              let schemaJsonOpt = {};\n              let additionalSettingOpt = {};\n\n              if (!schemaDetail.schemaJson[platform]) {\n                if (_.includes(uniqPlatform, platform)) {\n                  schemaJsonOpt = schemaJsonAuthOptions();\n                } else {\n                  schemaJsonOpt = schemaJsonOptions();\n                }\n              } else if (schemaDetail.schemaJson[platform]) {\n                schemaJsonOpt = schemaDetail.schemaJson[platform];\n                if (_.includes(uniqPlatform, platform)) {\n                  // `schemaJson` add `isAuth` object.\n                  _.each(schemaJsonOpt, (val) => {\n                    if (val?.isAuth === false || val.policy) {\n                      val.isAuth = true;\n                    }\n                  });\n\n                  const index = _.findIndex(schemaJsonOpt, { isAuth: true });\n                  if (index >= 0) {\n                    // Add `auth` policy\n                    if (schemaJsonOpt[index]?.policy && !_.includes(schemaJsonOpt[index].policy, DEFAULT_POLICY_NAME)) {\n                      schemaJsonOpt[index].policy.push(DEFAULT_POLICY_NAME);\n                    } else if (!schemaJsonOpt[index]?.policy) {\n                      schemaJsonOpt[index].policy = [DEFAULT_POLICY_NAME];\n                    }\n                  } else {\n                    schemaJsonOpt.push({\n                      isAuth: true,\n                      policy: [DEFAULT_POLICY_NAME],\n                    });\n                  }\n                  schemaJsonOpt = _.compact(schemaJsonOpt);\n                } else {\n                  _.each(schemaJsonOpt, (val) => {\n                    if (val?.isAuth === true) {\n                      val.isAuth = false;\n                      if (val?.policy) {\n                        val.policy = val.policy.filter((v) => {\n                          if (v !== DEFAULT_POLICY_NAME) {\n                            return v;\n                          }\n                          return null;\n                        });\n                        val.policy = _.compact(val.policy);\n                      }\n                    }\n                  });\n                }\n              }\n\n              if (!schemaDetail.additionalJson.additionalSetting[platform]) {\n                if (_.includes(uniqPlatform, platform)) {\n                  additionalSettingOpt = getAdditionalJsonAuthOptions();\n                } else {\n                  additionalSettingOpt = getAdditionalJsonWithoutAuthOptions();\n                }\n              } else if (schemaDetail.additionalJson.additionalSetting[platform]) {\n                additionalSettingOpt = schemaDetail.additionalJson.additionalSetting[platform];\n                if (_.includes(uniqPlatform, platform)) {\n                  // `additionalJson` add `isAuth` object.\n                  _.each(additionalSettingOpt, (val) => {\n                    if (!val.isAuth || val.isAuth !== true) {\n                      val.isAuth = true;\n                    }\n                    if (val.policy && !_.includes(val.policy, DEFAULT_POLICY_NAME)) {\n                      val.policy.push(DEFAULT_POLICY_NAME);\n                    } else if (!val.policy) {\n                      val.policy = [DEFAULT_POLICY_NAME];\n                    }\n                  });\n                } else {\n                  _.each(additionalSettingOpt, (val) => {\n                    if (val.isAuth === true) {\n                      val.isAuth = false;\n                    }\n                    if (val.policy && _.includes(val.policy, DEFAULT_POLICY_NAME)) {\n                      val.policy = _.compact(val.policy.filter((v) => {\n                        if (v !== DEFAULT_POLICY_NAME) {\n                          return v;\n                        }\n                        return null;\n                      }));\n                    }\n                  });\n                }\n              }\n\n              if (!_.isEmpty(schemaJsonOpt)) {\n                schemaJson[platform] = schemaJsonOpt;\n              }\n\n              if (!_.isEmpty(additionalSettingOpt)) {\n                additionalJson.additionalSetting[platform] = additionalSettingOpt;\n              }\n            }\n\n            // eslint-disable-next-line no-await-in-loop\n            const updatedSchemaDetails = await schemaDetailsRepo.update(schemaDetail._id, {\n              schemaJson,\n              additionalJson,\n            });\n            const schemaDetailsData = updatedSchemaDetails.toObject();\n\n            // Get schema data.\n            const schemaData = _.find(schemas, { _id: schemaDetailsData.schemaId });\n\n            if (schemaData) {\n              // Delete model related routes.\n              const routeDeleteFilter = {\n                find: {\n                  modelId: schemaData._id.toString(),\n                  platform: { $nin: platforms },\n                },\n              };\n              // eslint-disable-next-line no-await-in-loop\n              await (RouteDeleteUseCase(projectRouteRepo, applicationRepo))(routeDeleteFilter, true);\n              const routeSchemaJson = {};\n              _.map(platforms, (v) => {\n                routeSchemaJson[v] = schemaDetailsData.schemaJson[v];\n              });\n              // create route based on permission\n              // eslint-disable-next-line no-await-in-loop\n              const allRouts = await getPermissionWiseRoute(routeSchemaJson, schemaData, definitionCode);\n              const routeFilter = { find: { modelId: schemaData._id.toString() } };\n              // eslint-disable-next-line no-await-in-loop\n              const updatedRoutes = await projectRouteRepo.getDetails(routeFilter);\n              const newRoutes = [];\n              for (let route = 0; route < allRouts.length; route += 1) {\n                const routeData = allRouts[route];\n                const getRoute = _.find(updatedRoutes, {\n                  modelId: routeData.modelId,\n                  applicationId: routeData.applicationId,\n                  route: routeData.route,\n                  method: routeData.method,\n                });\n                if (!getRoute) {\n                  newRoutes.push(routeData);\n                }\n              }\n              if (newRoutes && newRoutes.length > 0) {\n                // eslint-disable-next-line no-await-in-loop\n                await (routeInsertManyUseCase(projectRouteRepo))({ routes: newRoutes });\n              }\n            }\n          }\n        }\n      }\n    }\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return SERVER_ERROR;\n  }\n}\n\n/**\n * Function used to update `platform` in `applicationConfig`.\n * @param  {} {applicationId\n * @param  {} updatedApp\n * @param  {} }\n */\nasync function updatePlatformInApplicationConfig ({ updatedApp }) {\n  try {\n    if (updatedApp?.configInput?.platform) {\n      const configFilter = { find: { applicationId: updatedApp._id } };\n      const configData = await applicationConfigRepo.get(configFilter);\n      if (configData) {\n        const platforms = updatedApp.configInput.platform;\n\n        const updateData = {};\n\n        // Update `platforms` in `socialPlatform`.\n        if (configData?.socialPlatform) {\n          _.each(configData.socialPlatform, (social) => {\n            if (social?.platform && social.platform.length) {\n              social.platform = _.map(social?.platform, (v) => {\n                if (_.includes(platforms, v)) {\n                  return v;\n                }\n                return null;\n              });\n              social.platform = _.compact(social.platform);\n            }\n          });\n          updateData.socialPlatform = _.cloneDeep(configData.socialPlatform);\n        }\n\n        // Update `platforms` in `fileUpload`.\n        if (configData?.fileUpload?.uploads) {\n          _.each(configData.fileUpload.uploads, (file) => {\n            if (file?.platform && file.platform.length) {\n              file.platform = _.map(file?.platform, (v) => {\n                if (_.includes(platforms, v)) {\n                  return v;\n                }\n                return null;\n              });\n              file.platform = _.compact(file.platform);\n            }\n          });\n          updateData.fileUpload = _.cloneDeep(configData.fileUpload);\n        }\n\n        // Update `platforms` in `2FA`.\n        if (configData?.twoFactorAuthentication) {\n          if (configData?.twoFactorAuthentication?.platform && !_.isEmpty(configData.twoFactorAuthentication.platform)) {\n            const twoFaAuthPlatforms = _.cloneDeep(configData.twoFactorAuthentication.platform);\n            const platformObj = {};\n            _.map(platforms, (v) => {\n              if (twoFaAuthPlatforms[v]) {\n                platformObj[v] = true;\n              }\n            });\n            configData.twoFactorAuthentication.platform = platformObj;\n            updateData.twoFactorAuthentication = _.cloneDeep(configData.twoFactorAuthentication);\n          }\n        }\n\n        if (!_.isEmpty(updateData)) {\n          await applicationConfigRepo.update(configData._id, updateData);\n        }\n      }\n    }\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return SERVER_ERROR;\n  }\n}\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (applicationRepo, schemaRepo) => async (id, params) => {\n  try {\n    // Validate Request\n    params.selfUpdatedAt = dayjs().toISOString();\n    delete params.applicationId;\n    /*\n     * const validationErrors = await validateData(params);\n     * const errors = false\n     */\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.configInput) {\n      const loginAccess = params?.configInput?.loginAccess;\n      if (params.configInput.types && params.configInput.types.length > 0) {\n        const keys = Object.keys(loginAccess);\n        const values = Object.values(loginAccess);\n        let flagVal;\n        let flag;\n        keys.forEach((k) => {\n          flag = params.configInput.types.includes(k);\n        });\n        values.forEach((val) => {\n          flagVal = _.difference(val, params.configInput.platform);\n        });\n        if (!flag || flagVal.length > 0) {\n          return INVALID_REQUEST_PARAMS;\n        }\n      }\n    }\n    let cloneParams = _.cloneDeep(params);\n    if (cloneParams.name) {\n      let nameTemp = cloneParams.name;\n      nameTemp = nameTemp.replace(/-/g, '');\n      nameTemp = nameTemp.replace(/_/g, '');\n      cloneParams.name = nameTemp;\n      delete cloneParams.configInput;\n      if (!(VALIDATION_RULES.APPLICATION.NAME.REGEX.test(nameTemp))) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: 'Start your application name with an alphanumeric with a minimum of 3 alphabets, and (_) are allowed after alphanumeric',\n        };\n      }\n\n      const {\n        value, error,\n      } = applicationUpdateValidation(cloneParams);\n      if (error) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: error,\n        };\n      }\n      cloneParams = value;\n    }\n\n    // Validate Unique Criteria\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: id,\n      isAllFields: true,\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const application = applicationData?.data;\n\n    const {\n      value, error,\n    } = applicationUpdateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const updateData = _.pick(params, applicationUpdateFields);\n\n    if (params?.stepInput) {\n      updateData.stepInput = {\n        ...application?.stepInput,\n        ...params?.stepInput,\n      };\n    }\n\n    const updateResponse = await applicationRepo.update(id, updateData);\n\n    const updatedApp = updateResponse.toObject();\n\n    // Update schema-details and routes based on permissions.\n    const updateSchemaDetails = await updateSchemaDetailsAndRoutes({\n      schemaRepo,\n      applicationRepo,\n      updatedApp,\n    });\n    if (updateSchemaDetails.code !== OK.code) {\n      return updateSchemaDetails;\n    }\n\n    // Update platform in `socialPlatform` & `fileUpload` in `applicationConfig`.\n    const appConfig = await updatePlatformInApplicationConfig({ updatedApp });\n    if (appConfig.code !== OK.code) {\n      return appConfig;\n    }\n\n    projectApplicationUpdate({ params: { projectId: application?.projectId } });\n    return {\n      ...APPLICATION_UPDATED,\n      data: _.pick(updateResponse, applicationUpdateFields),\n    };\n  } catch (err) {\n    // console.log('err', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/application/upsert.js",
    "content": "/* global MESSAGE */\n// const validate = require('validate.js');\nconst mongoose = require('mongoose');\nconst {\n  SERVER_ERROR, APPLICATION_NOT_FOUND, INVALID_REQUEST_PARAMS, APPLICATION_IS_ARCHIVED, APPLICATION_IS_UNARCHIVED,\n} = require('../../constants/message').message;\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst { applicationUpsertValidation } = require('../util/validation/applicationUpsert');\n\n/**\n *\n * Function used for update application-config.\n * @return json\n */\nconst upsert = (applicationRepo, projectRepo) => async ({\n  id,\n  params,\n}) => {\n  try {\n    const {\n      value, error,\n    } = applicationUpsertValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    if (id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const filter = { find: { _id: id } };\n    const applicationData = await applicationRepo.get(filter);\n    if (!applicationData) {\n      return APPLICATION_NOT_FOUND;\n    }\n    if (!params.isArchive) {\n      // Updated project isArchive to false\n      await projectRepo.update(applicationData.projectId, { isArchive: false });\n    }\n    await applicationRepo.update(id, params);\n\n    if (params.isArchive) {\n      projectApplicationUpdate({ params: { projectId: applicationData?.projectId } });\n      return APPLICATION_IS_ARCHIVED;\n    }\n    return APPLICATION_IS_UNARCHIVED;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = upsert;\n"
  },
  {
    "path": "packages/server/usecase/application/view.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst paginate = (applicationRepo, projectRepo) => async (params) => {\n  try {\n    if (!params.id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n\n    const filter = params;\n    const response = {};\n    response.application = await applicationRepo.getById(filter);\n    if (response.application) {\n      response.project = await projectRepo.getById({ id: response.application.projectId });\n    }\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/create.js",
    "content": "/* global _ */\nconst { appConfigCreateValidation } = require('../util/validation/applicationConfig');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, APPLICATION_CONFIG_CREATED, BAD_REQUEST,\n} = require('../../constants/message').message;\n\n/**\n * Function used for create application config.\n * @return json\n */\nconst useCase = (applicationConfigRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = appConfigCreateValidation(params);\n    if (error) {\n      return {\n        ...BAD_REQUEST,\n        message: error,\n      };\n    }\n    params = _.cloneDeep(value);\n\n    const created = await applicationConfigRepo.create(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    return {\n      ...APPLICATION_CONFIG_CREATED,\n      data: created,\n    };\n  } catch (err) {\n    // console.log(err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/delete.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS,\n  SERVER_ERROR,\n} = require('../../constants/message').message;\nconst deleteApplicationConfigUseCase = require('./deleteDependency');\n\nconst deleteById = (applicationConfigRepo, applicationRepo) => async (\n  params,\n) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await deleteApplicationConfigUseCase(\n      applicationConfigRepo,\n      applicationRepo,\n    )(\n      {\n        find: {\n          _id: params.id,\n          isActive: { $in: [true, false] },\n        },\n      },\n      params.isHardDelete,\n    );\n    return response;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, OK,\n} = require('../../constants/message').message;\n\nconst deleteMany = (applicationConfigRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await applicationConfigRepo.getDetails(filter);\n    if (response && response.length) {\n      if (isHardDelete) {\n        await applicationConfigRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await applicationConfigRepo.updateMany(updateData);\n      }\n    }\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/get.js",
    "content": "const mongoose = require('mongoose');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, APPLICATION_CONFIG_NOT_FOUND, OK,\n} = require('../../constants/message').message;\n/**\n *\n * Function used for get user.\n * @return json\n */\nconst get = (applicationConfigRepo) => async (id) => {\n  try {\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    // Validate Unique Criteria\n    const filter = { filter: { find: { _id: id } } };\n    const applicationConfig = await applicationConfigRepo.get(filter);\n\n    if (!applicationConfig) {\n      return APPLICATION_CONFIG_NOT_FOUND;\n    }\n    return {\n      ...OK,\n      data: applicationConfig,\n    };\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/paginate.js",
    "content": "/* global _ */\nconst mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst SchemaRepository = require('../../repo/schema');\n\nconst schemaRepo = new SchemaRepository();\n\nconst paginate = (applicationConfigRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    if (!params.find) {\n      params.find = {};\n    }\n    params.find.applicationId = params.applicationId;\n    const filter = params;\n    const list = await applicationConfigRepo.getDetails(filter);\n\n    let resModelIds = [];\n\n    // Get schema data for responseFormatter.\n    _.map(list, (config) => {\n      if (config?.responseFormatter) {\n        const mIds = _.map(config.responseFormatter, 'modelId');\n        resModelIds.push(mIds);\n      }\n    });\n    resModelIds = _.compact(_.flattenDeep(resModelIds));\n    resModelIds = _.cloneDeep(_.uniq(resModelIds.map(String)));\n\n    if (resModelIds && resModelIds.length > 0) {\n      const schemaData = await schemaRepo.getDetails({\n        find: { _id: resModelIds },\n        fields: ['name'],\n      });\n      if (schemaData && schemaData.length > 0) {\n        _.map(list, (config) => {\n          if (config?.responseFormatter) {\n            _.map(config.responseFormatter, (resFormat) => {\n              if (resFormat?.modelId) {\n                const modelData = _.find(schemaData, { _id: resFormat.modelId });\n                if (modelData) {\n                  resFormat.model = _.cloneDeep(modelData);\n                }\n              }\n            });\n          }\n        });\n      }\n    }\n\n    const response = {\n      list,\n      count: await applicationConfigRepo.getCount(filter),\n    };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/applicationConfig/update.js",
    "content": "/* global  _ */\nconst mongoose = require('mongoose');\nconst faker = require('faker');\nconst { appConfigUpdateValidation } = require('../util/validation/applicationConfig');\nconst {\n  SERVER_ERROR, APPLICATION_CONFIG_NOT_FOUND, APPLICATION_CONFIG_UPDATED, BAD_REQUEST, INVALID_REQUEST_PARAMS, APPLICATION_DETAILS_NOT_FOUND,\n} = require('../../constants/message').message;\n\nconst SchemaRepository = require('../../repo/schema');\n\nconst schemaRepo = new SchemaRepository();\n\n/**\n * Function used to generate `FAKER` data.\n * @param  {} dataType\n * @param  {} keyName\n */\nasync function getFakerData (dataType, keyName) {\n  let fakerData = null;\n  if (keyName) {\n    keyName = keyName.toLowerCase();\n    if (keyName.toLowerCase() === 'username') {\n      fakerData = faker.internet.userName();\n    } else if (keyName === 'password') {\n      fakerData = faker.internet.password();\n    } else if (keyName === 'email') {\n      fakerData = faker.internet.email();\n    } else if (keyName === 'email') {\n      fakerData = faker.internet.email();\n    } else if (keyName === 'firstname') {\n      fakerData = faker.name.firstName();\n    } else if (keyName === 'lastname') {\n      fakerData = faker.name.lastName();\n    } else if (keyName === 'name') {\n      fakerData = faker.internet.userName();\n    } else if (keyName === 'gender') {\n      fakerData = faker.name.gender();\n    }\n    if (fakerData) {\n      return fakerData;\n    }\n  }\n\n  switch (dataType.toLowerCase()) {\n  case 'number':\n    fakerData = faker.datatype.number();\n    break;\n  case 'float':\n    fakerData = faker.datatype.float();\n    break;\n  case 'datetime':\n    fakerData = faker.datatype.datetime();\n    break;\n  case 'string':\n    fakerData = faker.random.alphaNumeric(10);\n    break;\n  case 'uuid':\n    fakerData = faker.datatype.uuid();\n    break;\n  case 'boolean':\n    fakerData = faker.datatype.boolean();\n    break;\n\n  default:\n    fakerData = faker.random.alphaNumeric();\n  }\n\n  return fakerData;\n}\n\n/**\n *\n * Function used for update application-config.\n * @return json\n */\nconst update = (applicationConfig, applicationRepo) => async (id, params) => {\n  try {\n    const {\n      value, error,\n    } = appConfigUpdateValidation(params);\n    if (error) {\n      return {\n        ...BAD_REQUEST,\n        message: error,\n      };\n    }\n    params = _.cloneDeep(value);\n\n    // Validate Unique Criteria\n    const filter = { find: { _id: id } };\n    const applicationConfigData = await applicationConfig.get({ filter });\n\n    if (!applicationConfigData) {\n      return APPLICATION_CONFIG_NOT_FOUND;\n    }\n\n    const applicationDetails = await applicationRepo.get({ find: { _id: params.applicationId } });\n    if (!applicationDetails) {\n      return APPLICATION_DETAILS_NOT_FOUND;\n    }\n\n    if (!params.authModuleId) {\n      params.authModule = null;\n    }\n    if (params.authModuleId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.authModuleId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n\n    // Update `authentication.credentials`.\n    let authData = {};\n    if (applicationConfigData?.authentication) {\n      authData = _.cloneDeep(applicationConfigData?.authentication);\n    }\n    const authModel = await schemaRepo.get({\n      find: {\n        _id: params.authModuleId,\n        applicationId: params.applicationId,\n      },\n    });\n    if (authModel?.schemaJson) {\n      const { schemaJson } = authModel;\n      let keys = [];\n      if (params?.loginWith?.username) {\n        keys.push(params.loginWith.username);\n      }\n      if (params?.loginWith?.password) {\n        keys.push(params.loginWith.password);\n      }\n      keys = _.compact(_.uniq(_.flattenDeep(keys)));\n      if (applicationDetails?.configInput?.types && applicationDetails.configInput.types.length > 0) {\n        const userTypes = _.cloneDeep(applicationDetails.configInput.types);\n\n        if (applicationConfigData?.authentication?.credentials) {\n          const authCred = _.cloneDeep(applicationConfigData.authentication.credentials);\n          const updatedCredentials = [];\n          for (let i = 0; i < userTypes.length; i += 1) {\n            const type = userTypes[i];\n\n            let credData = {};\n            credData = _.find(authCred, { type });\n            if (!credData) {\n              credData = { type };\n            }\n            if (!credData.email) {\n              credData.email = faker.internet.email();\n            }\n            if (!credData.password) {\n              credData.password = faker.internet.password();\n            }\n            // eslint-disable-next-line no-await-in-loop\n            await Promise.all(\n              _.map(keys, async (key) => {\n                if (!credData[key]) {\n                  const fakerData = await getFakerData(schemaJson?.[key]?.type, key);\n                  credData[key] = fakerData;\n                }\n              }),\n            );\n\n            const credKeys = _.keys(credData);\n            const diffKeys = _.difference(credKeys, keys);\n            _.map(diffKeys, (k) => {\n              if (!_.includes(['type', 'email', 'password'], k)) {\n                delete credData[k];\n              }\n            });\n\n            if (!_.isEmpty(credData)) {\n              updatedCredentials.push(credData);\n            }\n          }\n          if (updatedCredentials && updatedCredentials.length > 0) {\n            authData.credentials = updatedCredentials;\n          }\n          params.authentication = authData;\n        } else {\n          const credentials = [];\n          for (let i = 0; i < userTypes.length; i += 1) {\n            const type = userTypes[i];\n            const cred = {};\n            cred.type = type;\n            cred.email = faker.internet.email();\n            cred.password = faker.internet.password();\n\n            if (keys && keys.length > 0) {\n              // eslint-disable-next-line no-await-in-loop\n              await Promise.all(\n                _.map(keys, async (key) => {\n                  if (!cred[key]) {\n                    const fakerData = await getFakerData(schemaJson?.[key]?.type, key);\n                    cred[key] = fakerData;\n                  }\n                }),\n              );\n            }\n            credentials.push(cred);\n          }\n          if (credentials && credentials.length > 0) {\n            authData = {\n              ...authData,\n              credentials,\n            };\n          }\n          params.authentication = _.cloneDeep(authData);\n        }\n      } else {\n        params.authentication = _.cloneDeep({\n          ...authData,\n          credentials: null,\n        });\n      }\n    }\n\n    const updateResponse = await applicationConfig.update(id, params);\n\n    const updateDataObj = _.cloneDeep(updateResponse.toObject());\n\n    // Get schema data for responseFormatter.\n    let modelIds = [];\n    let resModelIds = [];\n\n    if (updateDataObj?.responseFormatter) {\n      modelIds = _.map(updateDataObj.responseFormatter, 'modelId');\n      resModelIds = _.compact(_.flattenDeep(modelIds));\n      resModelIds = _.cloneDeep(_.uniq(resModelIds.map(String)));\n    }\n\n    if (resModelIds && resModelIds.length > 0) {\n      const schemaData = await schemaRepo.getDetails({\n        find: { _id: resModelIds },\n        fields: ['name'],\n      });\n      if (schemaData && schemaData.length > 0) {\n        _.map(updateDataObj.responseFormatter, (resFormat) => {\n          if (resFormat?.modelId) {\n            const modelData = _.find(schemaData, { _id: resFormat.modelId });\n            if (modelData) {\n              resFormat.model = _.cloneDeep(modelData);\n            }\n          }\n        });\n      }\n    }\n\n    return {\n      ...APPLICATION_CONFIG_UPDATED,\n      data: updateDataObj,\n    };\n  } catch (err) {\n    // console.log('err: ', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/common/projectApplicationUpdate.js",
    "content": "/* global MESSAGE */\nconst dayjs = require('dayjs');\n\nconst ApplicationRepository = require('../../repo/application');\nconst ProjectRepository = require('../../repo/project');\n\nconst ApplicationRepo = new ApplicationRepository();\nconst ProjectRepo = new ProjectRepository();\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst projectApplicationUpdate = async ({\n  params, isProjectId,\n}) => {\n  try {\n    const updateData = { updatedAt: dayjs().toISOString() };\n\n    if (params.applicationId) {\n      const application = await ApplicationRepo.update(params.applicationId, updateData);\n\n      if (isProjectId) {\n        params.projectId = application?.projectId;\n      }\n    }\n\n    if (params.projectId) {\n      await ProjectRepo.update(params.projectId, updateData);\n    }\n\n    return MESSAGE.OK;\n  } catch (err) {\n    // console.log('err', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\n\nmodule.exports = projectApplicationUpdate;\n"
  },
  {
    "path": "packages/server/usecase/envVariables/get.js",
    "content": "/* global _ */\nconst { decrypt } = require('../../util-service/crypto');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, ENV_VARIABLE_NOT_FOUND,\n} = require('../../constants/message').message;\n\nconst get = (envVariablesRepo) => async (params) => {\n  try {\n    if (!params || !params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n\n    const envData = await envVariablesRepo.get({ find: { applicationId: params.applicationId } });\n\n    if (!envData) {\n      return ENV_VARIABLE_NOT_FOUND;\n    }\n\n    if (envData && envData.customJson) {\n      // Convert Encrypted values in Decrypted form.\n      _.each(envData.customJson, (val) => {\n        if (val && val.value) {\n          _.each(val.value, async (v, k) => {\n            let isDecrypt = true;\n            if ((val?.dataType) && _.indexOf(['string'], val.dataType.toLowerCase()) < 0) {\n              isDecrypt = false;\n            }\n            if (isDecrypt) {\n              const decryptedValue = await decrypt(v);\n              val.value[k] = decryptedValue;\n            }\n          });\n        }\n      });\n    }\n\n    return {\n      ...OK,\n      data: envData,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/envVariables/upsert.js",
    "content": "/* global  _ */\nconst mongoose = require('mongoose');\nconst {\n  encrypt, decrypt,\n} = require('../../util-service/crypto');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, ENV_DETAILS_UPDATED,\n} = require('../../constants/message').message;\nconst { VALIDATION_RULES } = require('../../constants/validation');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst upsert = (envVariablesRepo) => async (params) => {\n  try {\n    if (!params.applicationId || !params.customJson) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n\n    // check variable name\n    let isValid = true;\n    if (params.environments && params.environments.length) {\n      // eslint-disable-next-line for-direction\n      for (let i = 0; i < params.environments.length; i += 1) {\n        const p = new RegExp(VALIDATION_RULES.APPLICATION_FILE_NAME);\n        if (!p.test(params.environments[i])) {\n          isValid = false;\n          break;\n        }\n      }\n    }\n    if (!isValid) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    // Convert values in Encrypted form.\n    _.each(params.customJson, (val) => {\n      if (val && val.value) {\n        _.each(val.value, async (v, k) => {\n          let isEncrypt = true;\n          if ((val?.dataType) && _.indexOf(['string'], val.dataType.toLowerCase()) < 0) {\n            isEncrypt = false;\n          }\n          if (isEncrypt && v !== '') {\n            const encryptedValue = await encrypt(v);\n            val.value[k] = encryptedValue;\n          }\n        });\n      }\n    });\n\n    // Check record already exists for same `Application`.\n    if (!params.id) {\n      const envData = await envVariablesRepo.get({\n        find: {\n          applicationId: params.applicationId,\n          isActive: { $in: [true, false] },\n        },\n      });\n\n      if (envData) {\n        params.id = envData._id;\n      }\n    }\n\n    let environmentData = {};\n    if (params.id) {\n      const { id } = params;\n      delete params.id;\n      environmentData = await envVariablesRepo.update(id, params);\n    } else {\n      environmentData = await envVariablesRepo.create(params);\n    }\n\n    // Convert Encrypted values in Decrypted form.\n    _.each(environmentData.customJson, (val) => {\n      if (val && val.value) {\n        _.each(val.value, async (v, k) => {\n          let isDecrypt = true;\n          if ((val?.dataType) && _.indexOf(['string'], val.dataType.toLowerCase()) < 0) {\n            isDecrypt = false;\n          }\n          if (isDecrypt) {\n            const decryptedValue = await decrypt(v);\n            val.value[k] = decryptedValue;\n          }\n        });\n      }\n    });\n\n    projectApplicationUpdate({\n      params: { applicationId: params.applicationId },\n      isProjectId: true,\n    });\n    const responseMsg = ENV_DETAILS_UPDATED;\n\n    return {\n      ...responseMsg,\n      data: environmentData,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = upsert;\n"
  },
  {
    "path": "packages/server/usecase/generator/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n// {  find: { schemaId: params.id } }\nconst deleteMany = (generatorRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await generatorRepo.getDetails(filter);\n    if (response && response.length) {\n      if (isHardDelete) {\n        await generatorRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await generatorRepo.updateMany(updateData);\n      }\n    }\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/jsonInput.js",
    "content": "/* global MESSAGE, _ */\nconst {\n  ORM_TYPE, DATABASE_TYPE, GENERATOR_DATABASE_TYPE, GENERATOR_ORM_TYPE,\n} = require('../../models/constants/applicationConfig');\n\nconst { JSON_INPUT } = require('../../constants/jsonInput');\nconst { PARENT_CODES } = require('../../constants/master');\nconst {\n  SERVER_ERROR, OK, APPLICATION_NOT_FOUND,\n} = require('../../constants/message').message;\n\nconst {\n  projectConstants, projectPolicy, schema, projectPackages, projectRoleAccessPermission, projectRoutes, notificationTemplates,\n} = require('./util');\nconst { applicationIdValidation } = require('../util/validation/applicationId');\n\nconst ApplicationRepository = require('../../repo/application');\nconst ApplicationConfigRepository = require('../../repo/applicationConfig');\nconst SchemaRepository = require('../../repo/schema');\nconst MasterRepository = require('../../repo/master');\n\nconst applicationRepo = new ApplicationRepository();\nconst applicationConfigRepo = new ApplicationConfigRepository();\nconst schemaRepo = new SchemaRepository();\nconst masterRepo = new MasterRepository();\n\n/**\n * Function used to get `MASTER` data.\n */\nasync function getMasterData () {\n  const masterCodesData = await masterRepo.getDetailsForInput();\n  if (!masterCodesData || masterCodesData.length <= 0) {\n    return [];\n  }\n\n  return masterCodesData;\n}\n\n/**\n * Function used to update application details.\n * @param  {} params\n */\nasync function updateApplicationDetails (params) {\n  try {\n    const filter = { find: { _id: params.applicationId } };\n    const applicationDetails = await applicationRepo.get(filter);\n\n    if (!applicationDetails) {\n      return APPLICATION_NOT_FOUND;\n    }\n\n    const updateAppFilter = {};\n\n    // Prepare `configInput` object.\n    let configInput = {};\n    if (applicationDetails?.configInput) {\n      configInput = applicationDetails.configInput;\n    }\n    if (params?.authentication?.loginAccess) {\n      configInput.loginAccess = params.authentication.loginAccess;\n    }\n    if (params?.authentication?.isAuthentication) {\n      configInput.isAuthentication = params.authentication.isAuthentication;\n    } else {\n      configInput.isAuthentication = false;\n    }\n    if (params?.authentication?.authModel) {\n      configInput.authModel = params.authentication.authModel;\n    } else {\n      configInput.authModel = JSON_INPUT.AUTH_MODEL;\n    }\n    if (params?.config?.port) {\n      configInput.port = String(params.config.port);\n    } else {\n      configInput.port = '5000';\n    }\n    if (params?.config?.databaseName) {\n      configInput.databaseName = params.config.databaseName;\n    }\n    if (params?.authentication?.platform) {\n      configInput.platform = params.authentication.platform;\n    }\n    if (params?.authentication?.types) {\n      configInput.types = params.authentication.types;\n    }\n    if (params?.authentication?.noPlatform) {\n      configInput.noPlatform = params.authentication.noPlatform;\n    }\n    if (!_.isEmpty(configInput)) {\n      updateAppFilter.configInput = configInput;\n    }\n\n    // Prepare `stepInput` object.\n    let stepInput = {};\n    if (applicationDetails?.stepInput) {\n      stepInput = applicationDetails?.stepInput;\n    }\n    if (params?.directoryStructure) {\n      stepInput.directoryStructure = params.directoryStructure;\n    }\n\n    stepInput.ormType = ORM_TYPE.MONGOOSE;\n    stepInput.databaseType = DATABASE_TYPE.MONGODB;\n    if (params?.ORM) {\n      stepInput.ormType = _.invert(GENERATOR_ORM_TYPE)?.[params.ORM];\n    }\n    if (params?.adapter) {\n      stepInput.databaseType = _.invert(GENERATOR_DATABASE_TYPE)?.[params.adapter];\n    }\n    if (!_.isEmpty(stepInput)) {\n      updateAppFilter.stepInput = stepInput;\n    }\n\n    if (params?.projectType) {\n      updateAppFilter.projectType = params.projectType;\n    } else {\n      updateAppFilter.projectType = JSON_INPUT.PROJECT_TYPE;\n    }\n\n    const updatedApp = await applicationRepo.update(applicationDetails._id, updateAppFilter);\n\n    return {\n      ...OK,\n      data: updatedApp.toObject(),\n    };\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to update `application-config`.\n * @param  {} {params\n * @param  {} applicationDetails\n * @param  {} }\n */\nasync function updateApplicationConfig ({\n  params, applicationId,\n}) {\n  try {\n    const appConfigInput = {};\n\n    if (params?.authentication?.noOfDevice) {\n      appConfigInput.noOfDevice = params.authentication.noOfDevice;\n    }\n    if (params?.authentication?.authModule) {\n      appConfigInput.authModule = params.authentication.authModule;\n      const authSchema = await schemaRepo.get({\n        find: {\n          applicationId,\n          name: params.authentication.authModule,\n        },\n      });\n      if (authSchema) {\n        appConfigInput.authModuleId = authSchema._id;\n      }\n    }\n    if (params?.authentication?.loginWith) {\n      if (params?.authentication?.loginWith?.username) {\n        params.authentication.loginWith.username = _.compact(params.authentication.loginWith.username);\n      }\n      appConfigInput.loginWith = params.authentication.loginWith;\n    }\n    if (params?.authentication?.loginRetryLimit) {\n      appConfigInput.loginRetryLimit = params.authentication.loginRetryLimit;\n    }\n    if (params?.authentication?.loginRateLimit) {\n      appConfigInput.loginRateLimit = params.authentication.loginRateLimit;\n    }\n    if (params?.authentication?.loginNextRetryTime) {\n      appConfigInput.loginNextRetryTime = params.authentication.loginNextRetryTime;\n    }\n    if (params?.authentication?.resetPassword) {\n      if (params?.authentication?.resetPassword?.link) {\n        const rPassLinkObj = _.cloneDeep(params.authentication.resetPassword.link);\n\n        // EMAIL & SMS MasterIds\n        const masterCodesIds = [];\n        if (rPassLinkObj?.email) {\n          const emailData = _.find(params.masterDetails, { code: PARENT_CODES.EMAIL });\n          if (emailData) {\n            masterCodesIds.push(emailData._id.toString());\n          }\n        }\n        if (rPassLinkObj?.sms) {\n          const smsData = _.find(params.masterDetails, { code: PARENT_CODES.SMS });\n          if (smsData) {\n            masterCodesIds.push(smsData._id.toString());\n          }\n        }\n        if (masterCodesIds && masterCodesIds.length > 0) {\n          params.authentication.resetPassword.link.masterIds = _.cloneDeep(masterCodesIds);\n        }\n      }\n      appConfigInput.resetPassword = params.authentication.resetPassword;\n    }\n    if (params?.authentication?.isSocialMediaAuth) {\n      appConfigInput.isSocialMediaAuth = params.authentication.isSocialMediaAuth;\n    }\n    if (params?.authentication?.restrictNoOfDevice) {\n      appConfigInput.restrictNoOfDevice = params.authentication.restrictNoOfDevice;\n    }\n    if (params?.fileUpload) {\n      appConfigInput.fileUpload = _.cloneDeep(params.fileUpload);\n    }\n    if (params?.socket?.selected) {\n      appConfigInput.isSocket = params.socket.selected;\n    }\n    if (params?.authentication?.socialPlatform) {\n      _.map(params.authentication.socialPlatform, (sPlatform) => {\n        const sAuthData = _.find(params.masterDetails, { code: sPlatform.type });\n        if (sAuthData?._id) {\n          sPlatform.typeId = _.cloneDeep(sAuthData._id);\n        }\n        if (sPlatform?.platforms) {\n          sPlatform.platform = _.cloneDeep(sPlatform?.platforms);\n          delete sPlatform?.platforms;\n        }\n      });\n      appConfigInput.socialPlatform = _.cloneDeep(params.authentication.socialPlatform);\n    }\n    if (params?.authentication?.externalServiceProviderData) {\n      const exProvider = params?.authentication?.externalServiceProviderData;\n      _.map(exProvider, (provider) => {\n        if (provider?.type) {\n          const providerData = _.find(params.masterDetails, { code: provider.type });\n          if (providerData?._id) {\n            provider.typeId = providerData._id;\n          }\n        }\n\n        if (provider?.serviceProvide) {\n          const providerSubData = _.find(params.masterDetails, { name: provider.serviceProvide });\n          if (providerSubData?._id) {\n            provider.serviceProviderId = providerSubData._id;\n          }\n        }\n      });\n      appConfigInput.externalServiceProviderData = _.cloneDeep(exProvider);\n    }\n    if (params?.authentication?.tokenExpireTime) {\n      appConfigInput.tokenExpiryTime = params.authentication.tokenExpireTime;\n    }\n\n    if (!_.isEmpty(appConfigInput)) {\n      const appConfigFilter = { find: { applicationId } };\n      const appConfigDetails = await applicationConfigRepo.get(appConfigFilter);\n      if (appConfigDetails) {\n        await applicationConfigRepo.update(appConfigDetails._id, appConfigInput);\n      } else {\n        appConfigInput.applicationId = _.cloneDeep(applicationId);\n        await applicationConfigRepo.create(appConfigInput);\n      }\n    }\n\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\nconst jsonInput = () => async (params) => {\n  try {\n    const {\n      value, error,\n    } = applicationIdValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = _.cloneDeep(value);\n    const errorResponse = [];\n\n    // Get `MASTER` data.\n    const masterDetails = await getMasterData();\n\n    // Update application details.\n    const updateAppRes = await updateApplicationDetails({\n      ...params,\n      masterDetails,\n    });\n    if (updateAppRes.code !== OK.code) {\n      return updateAppRes;\n    }\n\n    const updatedAppDetails = _.cloneDeep(updateAppRes.data);\n\n    // Store `Package` related details.\n    if (params && params.packages && !_.isEmpty(params.packages)) {\n      const response = await projectPackages({\n        params: {\n          data: params.packages,\n          applicationId: params.applicationId,\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Constants` related details.\n    if (params && params.constants && !_.isEmpty(params.constants)) {\n      const response = await projectConstants({\n        params: {\n          data: params.constants,\n          applicationId: params.applicationId,\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Policy` related details.\n    if (params && params.policy && !_.isEmpty(params.policy)) {\n      const response = await projectPolicy({\n        params: {\n          data: params.policy,\n          applicationId: params.applicationId,\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Models` related details.\n    if (params && params.models && !_.isEmpty(params.models)) {\n      const response = await schema({\n        params: {\n          data: {\n            models: params?.models,\n            modelConfig: params?.modelConfig,\n            newModelConfig: params?.newModelConfig,\n            hooks: params?.hooks,\n            modelIndexes: params?.modelIndexes,\n            authModule: params?.authentication?.authModule,\n          },\n          applicationId: params.applicationId,\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Role-Access-Permission` related details.\n    if (params?.rolePermission && !_.isEmpty(params?.rolePermission)) {\n      const response = await projectRoleAccessPermission({\n        params: {\n          data: {\n            rolePermission: params.rolePermission,\n            applicationId: params.applicationId,\n          },\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Routes` related details.\n    if (params?.routes && !_.isEmpty(params.routes) > 0) {\n      const response = await projectRoutes({\n        params: {\n          data: {\n            routes: params.routes,\n            applicationId: params.applicationId,\n            definitionType: params?.definitionDetails?.code,\n          },\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    // Store `Notification-Templates` related details.\n    if (params?.templatesData && !_.isEmpty(params.templatesData) > 0) {\n      const response = await notificationTemplates({\n        params: {\n          data: {\n            templatesData: params.templatesData,\n            applicationId: params.applicationId,\n            masterDetails,\n          },\n        },\n      });\n\n      if (response && response.data && response.data.errors && _.size(response.data.errors) > 0) {\n        _.each(response.data.errors, (v) => {\n          errorResponse.push(v);\n        });\n      }\n    }\n\n    const updateAppConfigParams = {\n      ...params,\n      masterDetails,\n    };\n    // Update application-config.\n    const updateAppConfig = await updateApplicationConfig({\n      params: updateAppConfigParams,\n      applicationId: updatedAppDetails._id,\n    });\n    if (updateAppConfig.code !== OK.code) {\n      return updateAppConfig;\n    }\n\n    return {\n      ...OK,\n      data: { errors: errorResponse },\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = jsonInput;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/index.js",
    "content": "const projectConstants = require('./projectConstant/projectConstant');\nconst projectPolicy = require('./projectPolicy/projectPolicy');\nconst schema = require('./schema/schema');\nconst projectRoleAccessPermission = require('./projectRoleAccessPermission/projectRoleAccessPermission');\nconst projectRoutes = require('./projectRoutes/projectRoutes');\n\nmodule.exports = {\n  projectConstants,\n  projectPolicy,\n  schema,\n  projectRoleAccessPermission,\n  projectRoutes,\n};\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/projectConstant/projectConstant.js",
    "content": "/* global MESSAGE, _ */\n\nconst { CONSTANT_GENERATE_TYPE } = require('../../../../models/constants/project');\n\nconst createUseCase = require('../../../projectConstant/create');\n\nconst ProjectConstantRepository = require('../../../../repo/projectConstant');\nconst ApplicationRepository = require('../../../../repo/application');\n\nconst projectConstantRepo = new ProjectConstantRepository();\nconst applicationRepo = new ApplicationRepository();\n\nconst projectConstants = async ({ params }) => {\n  const input = [];\n  const constantData = params.data;\n\n  // Prepare `request-body` for create useCase.\n  Object.keys(constantData).forEach((val) => {\n    input.push({\n      applicationId: params.applicationId,\n      fileName: val,\n      customJson: constantData[val],\n      type: CONSTANT_GENERATE_TYPE.MANUAL,\n    });\n  });\n\n  const errors = [];\n  await Promise.all(input.map(async (val) => {\n    const response = await createUseCase(projectConstantRepo, applicationRepo)(_.cloneDeep(val));\n    if (response.code !== MESSAGE.OK.code) {\n      errors.push({\n        message: response.message,\n        data: val,\n      });\n    }\n  }));\n  return {\n    ...MESSAGE.OK,\n    data: { errors },\n  };\n};\n\nmodule.exports = projectConstants;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/projectPolicy/projectPolicy.js",
    "content": "/* global MESSAGE, _ */\n\nconst { POLICY_GENERATE_TYPE } = require('../../../../models/constants/project');\n\nconst createUseCase = require('../../../projectPolicy/create');\n\nconst ProjectPolicyRepository = require('../../../../repo/projectPolicy');\nconst ApplicationRepository = require('../../../../repo/application');\n\nconst projectPolicyRepo = new ProjectPolicyRepository();\nconst applicationRepo = new ApplicationRepository();\n\nconst projectPolicy = async ({ params }) => {\n  const input = [];\n  const policyData = params.data;\n\n  // Prepare `request-body` for create useCase.\n  Object.keys(policyData).forEach((val) => {\n    input.push({\n      applicationId: params.applicationId,\n      fileName: val,\n      customJson: policyData[val].code,\n      type: POLICY_GENERATE_TYPE.MANUAL,\n    });\n  });\n\n  const errors = [];\n  await Promise.all(input.map(async (val) => {\n    const response = await createUseCase(projectPolicyRepo, applicationRepo)(_.cloneDeep(val));\n    if (response.code !== MESSAGE.OK.code) {\n      errors.push({\n        message: response.message,\n        data: val,\n      });\n    }\n  }));\n  return {\n    ...MESSAGE.OK,\n    data: { errors },\n  };\n};\n\nmodule.exports = projectPolicy;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/projectRoleAccessPermission/projectRoleAccessPermission.js",
    "content": "/* global  _ */\n\nconst rolePermissionAccessUpsert = require('../../../projectRoleAccessPermissions/upsert');\n\nconst { OK } = require('../../../../constants/message').message;\n\nconst SchemaRepository = require('../../../../repo/schema');\nconst ProjectRoleAccessPermissionsRepository = require('../../../../repo/projectRoleAccessPermissions');\n\nconst schemaRepo = new SchemaRepository();\nconst ProjectRoleAccessPermissionsRepo = new ProjectRoleAccessPermissionsRepository();\n\nconst projectRoleAccessPermission = async ({ params }) => {\n  if (!params?.data?.rolePermission) {\n    return OK;\n  }\n\n  const applicationId = _.cloneDeep(params.data.applicationId);\n  const rolePermissions = _.cloneDeep(params.data.rolePermission);\n\n  const modelNames = _.keys(rolePermissions);\n  const schemaData = await schemaRepo.getDetails({\n    find: {\n      applicationId,\n      name: modelNames,\n    },\n  });\n\n  let types = [];\n  _.each(rolePermissions, (data) => {\n    _.each(data, (val) => {\n      types.push(val);\n    });\n  });\n\n  const rolePermissionsData = [];\n  types = _.compact(_.uniq(_.flattenDeep(types)));\n  if (types && types.length > 0) {\n    _.map(types, (type) => {\n      const permission = {\n        name: type,\n        applicationId,\n      };\n\n      const customJson = [];\n      _.each(rolePermissions, (permissionData, modelName) => {\n        const modelData = _.find(schemaData, { name: modelName });\n        const actions = {};\n        if (modelData) {\n          _.each(permissionData, (val, key) => {\n            if (_.includes(val, type)) {\n              actions[key] = true;\n            } else {\n              actions[key] = false;\n            }\n          });\n          customJson.push({\n            modelId: modelData._id.toString(),\n            actions,\n          });\n        }\n      });\n      permission.customJson = customJson;\n\n      rolePermissionsData.push(permission);\n    });\n  }\n\n  const errorsData = [];\n  for (let i = 0; i < rolePermissionsData.length; i += 1) {\n    const roleData = rolePermissionsData[i];\n    // eslint-disable-next-line no-await-in-loop\n    const rolePermissionRes = await rolePermissionAccessUpsert(ProjectRoleAccessPermissionsRepo)(roleData);\n    if (rolePermissionRes.code !== OK.code) {\n      errorsData.push({\n        message: rolePermissionRes.message,\n        data: roleData,\n      });\n    }\n  }\n\n  return {\n    ...OK,\n    data: { errors: errorsData },\n  };\n};\n\nmodule.exports = projectRoleAccessPermission;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/projectRoutes/projectRoutes.js",
    "content": "/* eslint-disable no-loop-func */\n/* eslint-disable no-undef */\n/* global  _ */\nconst { ROUTE_GENERATE_TYPE } = require('../../../../models/constants/project');\nconst { PROJECT_DEFINITION_CODE } = require('../../../../models/constants/projectDefinition');\n\nconst projectRouteCreateUseCase = require('../../../projectRoute/create');\nconst queryBuilderInsertManyUseCase = require('../../../queryBuilder/insertMany');\n\nconst ProjectRouteRepository = require('../../../../repo/projectRoute');\nconst SchemaRepository = require('../../../../repo/schema');\nconst ApplicationRepository = require('../../../../repo/application');\nconst QueryBuilderRepository = require('../../../../repo/queryBuilder');\n\nconst projectRouteRepo = new ProjectRouteRepository();\nconst schemaRepo = new SchemaRepository();\nconst applicationRepo = new ApplicationRepository();\nconst queryBuilderRepo = new QueryBuilderRepository();\n\nconst { OK } = require('../../../../constants/message').message;\nconst { TYPES } = require('../../../../constants/queryBuilder');\n\nconst projectRoutes = async ({ params }) => {\n  const routesData = _.cloneDeep(params.data.routes);\n  const applicationId = _.cloneDeep(params.data.applicationId);\n  const definitionType = _.cloneDeep(params.data.definitionType);\n\n  const errors = [];\n  if (routesData?.apis && routesData?.apis.length > 0) {\n    const modelNames = _.map(routesData.apis, 'model');\n    const schemaData = await schemaRepo.getDetails({\n      find: {\n        applicationId,\n        name: modelNames,\n      },\n    });\n\n    for (let i = 0; i < routesData.apis.length; i += 1) {\n      const routeDetails = _.cloneDeep(routesData.apis[i]);\n\n      const input = {\n        applicationId,\n        type: ROUTE_GENERATE_TYPE.MANUAL,\n      };\n\n      const modelDetails = _.find(schemaData, { name: routeDetails.model });\n\n      if (modelDetails?._id) {\n        input.modelId = modelDetails._id;\n      }\n      if (routeDetails?.method) {\n        input.method = routeDetails.method;\n      }\n      if (routeDetails?.api) {\n        input.route = routeDetails.api;\n      }\n      if (routeDetails?.controller) {\n        input.controller = routeDetails.controller;\n      }\n      if (routeDetails?.descriptions) {\n        input.description = routeDetails.descriptions;\n      }\n      if (routeDetails?.platform) {\n        input.platform = routeDetails.platform;\n      }\n      if (routeDetails?.functionName) {\n        input.action = routeDetails.functionName;\n      }\n      if (routeDetails?.headers) {\n        input.headers = routeDetails.headers;\n      }\n      if (routeDetails?.policies) {\n        input.policies = routeDetails.policies;\n      }\n      if (definitionType) {\n        input.definitionType = routeDetails.definitionType;\n      } else {\n        input.definitionType = PROJECT_DEFINITION_CODE.NODE_EXPRESS;\n      }\n\n      if (routeDetails?.queryBuilder && routeDetails.queryBuilder.length > 0) {\n        // check fileUplaod query mode exist then store it in file upload operation\n        const fileUploadObj = routeDetails?.queryBuilder.filter((data) => data.queryMode === 'fileUpload');\n        if (fileUploadObj?.length > 0) {\n          delete fileUploadObj.queryMode;\n          input.fileUpload = { uploads: [fileUploadObj] };\n        }\n      }\n\n      // eslint-disable-next-line no-await-in-loop\n      const response = await projectRouteCreateUseCase(projectRouteRepo, applicationRepo)(input);\n\n      if (response?.data?._id && routeDetails?.queryBuilder && routeDetails.queryBuilder.length > 0) {\n        // eslint-disable-next-line no-await-in-loop\n        await Promise.all(_.map(routeDetails.queryBuilder, async (qBuilder) => {\n          const routeId = _.cloneDeep(response.data._id);\n          const queryBuilderInput = [\n            {\n              applicationId,\n              referenceId: routeId,\n              referenceType: TYPES.ROUTES,\n              code: qBuilder.code,\n              queryMode: qBuilder.queryMode,\n            },\n          ];\n          // eslint-disable-next-line no-await-in-loop\n          const qBuilderRes = await queryBuilderInsertManyUseCase(queryBuilderRepo)(queryBuilderInput);\n          if (qBuilderRes.code !== OK.code) {\n            errors.push({\n              message: qBuilderRes.message,\n              data: qBuilderRes,\n            });\n          }\n        }));\n      }\n      if (response.code !== OK.code) {\n        errors.push({\n          message: response.message,\n          data: input,\n        });\n      }\n    }\n  }\n\n  return {\n    ...OK,\n    data: { errors },\n  };\n};\n\nmodule.exports = projectRoutes;\n"
  },
  {
    "path": "packages/server/usecase/jsonInput/util/schema/schema.js",
    "content": "/* global MESSAGE, _ */\nconst { getDefaultFieldsForMongoDB } = require('../../../schema/util/staticData');\nconst createUseCase = require('../../../schema/create');\n\nconst { PROPS } = require('../../../../constants/dataTypes/props');\nconst { DATA_TYPES } = require('../../../../constants/schema');\n\nconst SchemaRepository = require('../../../../repo/schema');\nconst ApplicationRepository = require('../../../../repo/application');\n\nconst SchemaRepo = new SchemaRepository();\nconst applicationRepo = new ApplicationRepository();\n\nconst schema = async ({ params }) => {\n  const input = [];\n  const schemaData = params.data.models;\n\n  let authModuleName = null;\n  if (params?.data?.authModule) {\n    authModuleName = _.cloneDeep(params.data.authModule);\n  }\n\n  let modelConfig = {};\n  if (params?.data?.modelConfig) {\n    modelConfig = params.data.modelConfig;\n  }\n\n  let newModelConfig = {};\n  if (params?.data?.newModelConfig) {\n    newModelConfig = params.data.newModelConfig;\n  }\n\n  let hooks = {};\n  if (params.data.hooks) {\n    hooks = params.data.hooks;\n  }\n\n  let modelIndexes = {};\n  if (params.data.modelIndexes) {\n    modelIndexes = params.data.modelIndexes;\n  }\n\n  // Get default fields.\n  const defaultFields = await getDefaultFieldsForMongoDB();\n\n  // Prepare `request-body` for create useCase.\n  Object.keys(schemaData).forEach((val) => {\n    // Prepare `hooks` data.\n    const prepareHooks = [];\n    if (hooks[val]) {\n      const sHooks = hooks[val];\n      Object.keys(sHooks).forEach((v) => {\n        _.each(sHooks[v], (h) => {\n          prepareHooks.push({\n            code: h.code,\n            type: v,\n            operation: h.operation,\n          });\n        });\n      });\n    }\n\n    let modelIndex = [];\n    if (modelIndexes[val] && !_.isEmpty(modelIndexes[val])) {\n      modelIndex = modelIndexes[val];\n      _.map(modelIndex, (mInd) => {\n        let indexName = 'index';\n        Object.keys(mInd.indexFields).forEach((field) => {\n          indexName = `${indexName}_${field}`;\n        });\n        mInd.name = _.cloneDeep(indexName);\n      });\n    }\n\n    // Add default fields.\n    const schemaJson = _.cloneDeep(schemaData[val]);\n    const lowerSchemaJsonKeys = Object.keys(schemaJson).map((key) => key.toLowerCase());\n    Object.keys(defaultFields).forEach((field) => {\n      const lowerField = field.toLowerCase();\n\n      if (!_.includes(lowerSchemaJsonKeys, lowerField)) {\n        schemaJson[field] = defaultFields[field];\n      }\n      if (lowerField && (lowerField === 'addedby' || lowerField === 'updatedby')) {\n        schemaJson[field].type = DATA_TYPES.OBJECTID.value;\n        schemaJson[field][PROPS.REF] = authModuleName;\n      }\n    });\n    schemaData[val] = _.cloneDeep(schemaJson);\n\n    input.push({\n      applicationId: params.applicationId,\n      name: val,\n      schemaJson: schemaData[val],\n      hooks: prepareHooks ?? [],\n      jsonInputModelConfig: modelConfig[val] ?? {},\n      jsonInputNewModelConfig: newModelConfig[val] ?? {},\n      modelIndexes: modelIndex,\n    });\n  });\n\n  const errors = [];\n  await Promise.all(input.map(async (val) => {\n    const response = await createUseCase(SchemaRepo, applicationRepo)(_.cloneDeep(val));\n    if (response.code !== MESSAGE.OK.code) {\n      errors.push({\n        message: response.message,\n        data: val,\n      });\n    }\n  }));\n  return {\n    ...MESSAGE.OK,\n    data: { errors },\n  };\n};\n\nmodule.exports = schema;\n"
  },
  {
    "path": "packages/server/usecase/master/create.js",
    "content": "/* global MESSAGE,_ */\nconst { message } = require('../../constants/message');\nconst { masterCreateValidation } = require('../util/validation/masterValidation');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (masterRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = masterCreateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    const existsFilter = {\n      code: params.code,\n      isActive: [true, false],\n    };\n    if (params && params.parentCode) {\n      existsFilter.parentCode = params.parentCode;\n    }\n\n    const filter = { find: existsFilter };\n    const alreadyExists = await masterRepo.getDetails(filter);\n    if (alreadyExists && _.size(alreadyExists) > 0) {\n      return {\n        code: message.ALREADY_EXISTS.code,\n        message: message.ALREADY_EXISTS.message,\n      };\n    }\n\n    const created = await masterRepo.create(params);\n\n    if (!created) {\n      return message.SERVER_ERROR;\n    }\n    return {\n      data: created,\n      code: message.OK.code,\n    };\n  } catch (err) {\n    // console.log(err);\n    return {\n      data: err,\n      code: message.SERVER_ERROR.code,\n    };\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/master/getByCode.js",
    "content": "/* global _,MESSAGE */\nconst { message } = require('../../constants/message');\nconst { masterCodeValidation } = require('../util/validation/masterValidation');\n\n/**\n * Function used to prepare data tree wise.\n * @param  {} listData\n */\nfunction prepareMasterSubMaster (listData) {\n  const masterSubMaster = [];\n  const mappedArr = {};\n  let arrElem;\n  let mappedElem;\n\n  for (let i = 0, len = listData.length; i < len; i += 1) {\n    arrElem = listData[i];\n    mappedArr[arrElem._id] = arrElem;\n    mappedArr[arrElem._id].subMaster = [];\n  }\n\n  _.each(mappedArr, (value, id) => {\n    // eslint-disable-next-line no-prototype-builtins\n    if (mappedArr.hasOwnProperty(id)) {\n      mappedElem = mappedArr[id];\n      if (mappedElem.parentId) {\n        if (mappedArr[mappedElem.parentId]) {\n          mappedArr[mappedElem.parentId].subMaster.push(mappedElem);\n        } else {\n          masterSubMaster.push(mappedElem);\n        }\n      } else {\n        masterSubMaster.push(mappedElem);\n      }\n    }\n  });\n  return masterSubMaster;\n}\n\n/**\n * Function used to get Child records\n * @param  {} data\n * @param  {} arr=[]\n * @param  {} level=1\n */\nasync function getChildRecord (data, arr = [], level = 1) {\n  let newArr = [];\n  const {\n    masterRepo, params, masterListData,\n  } = data;\n  if (params && params.isSub && params.isSub === true) {\n    const ids = _.map(masterListData, '_id');\n\n    const filter = ids;\n    const masterData = await masterRepo.getChildDetails(filter);\n    if (masterData && _.size(masterData) > 0) {\n      newArr = _.compact([...arr, ...masterData]);\n\n      if (params && params.level >= 0) {\n        if (params.level >= level) {\n          level += 1;\n          const childData = await getChildRecord({\n            masterRepo,\n            params,\n            masterListData: masterData,\n          }, newArr, level);\n          return childData;\n        }\n      } else {\n        const childData = await getChildRecord({\n          masterRepo,\n          params,\n          masterListData: masterData,\n        }, newArr);\n        return childData;\n      }\n    }\n  }\n  return arr;\n}\n\nconst getByCode = (masterRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = masterCodeValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    const filterParams = _.cloneDeep(params);\n    delete filterParams.isSub;\n    delete filterParams.level;\n\n    let listData = await masterRepo.getMasterByCode(params);\n\n    if (params.isSub || params.level) {\n      listData = await getChildRecord({\n        masterRepo,\n        params,\n        masterListData: listData,\n      }, listData);\n    }\n\n    listData = await prepareMasterSubMaster(_.cloneDeep(listData));\n\n    const response = {\n      list: listData,\n      count: listData.length,\n    };\n\n    return {\n      ...message.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return {\n      data: err,\n      code: message.SERVER_ERROR.code,\n    };\n  }\n};\nmodule.exports = getByCode;\n"
  },
  {
    "path": "packages/server/usecase/master/paginate.js",
    "content": "/* global MESSAGE, */\nconst { message } = require('../../constants/message');\nconst { masterCodeValidation } = require('../util/validation/masterValidation');\n\nconst paginate = (masterRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = masterCodeValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const filter = { find: params };\n\n    const response = {\n      list: await masterRepo.getDetails(filter),\n      count: await masterRepo.getCount(filter),\n    };\n\n    return {\n      ...message.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return {\n      data: err,\n      code: message.SERVER_ERROR.code,\n    };\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/nestedQueryBuilder/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteDependencyUseCase = require('./deleteDependency');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (nestedQueryBuilderRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteDependencyUseCase(nestedQueryBuilderRepo, applicationRepo))({ find: { _id: params.id } }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/nestedQueryBuilder/deleteDependency.js",
    "content": "/* global _ */\n\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteMany = (nestedQueryBuilderRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await nestedQueryBuilderRepo.getDetails(filter);\n    if (response && _.size(response) > 0) {\n      if (response && response.length) {\n        if (isHardDelete) {\n          await nestedQueryBuilderRepo.deleteMany(filter);\n        } else {\n          const updateData = {\n            filter,\n            data: { isDeleted: true },\n          };\n          await nestedQueryBuilderRepo.updateMany(updateData);\n        }\n      }\n    }\n    return {\n      ...OK,\n      data: null,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/nestedQueryBuilder/insertMany.js",
    "content": "/* global  _ */\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (nestedQueryBuilderRepo) => async (params) => {\n  try {\n    params = _.cloneDeep(_.map(params, (val) => val));\n    const created = await nestedQueryBuilderRepo.insertMany(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    return {\n      ...OK,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/project/archive.js",
    "content": "const {\n  SERVER_ERROR, PROJECT_NOT_FOUND, PROJECT_IS_ARCHIVED, PROJECT_IS_IN_ARCHIVE,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for update project-config.\n * @return json\n */\nconst archiveProject = (projectRepo, applicationRepo) => async (id) => {\n  try {\n    // Validate Unique Criteria\n    const filter = { find: { _id: id } };\n    const projectData = await projectRepo.get(filter);\n\n    if (!projectData) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    if (projectData?.isArchive === true) {\n      return PROJECT_IS_IN_ARCHIVE;\n    }\n\n    const updateResponse = await projectRepo.update(id, { isArchive: true });\n    const updateData = {\n      filter: { find: { projectId: updateResponse._id } },\n      data: { isArchive: true },\n    };\n\n    await applicationRepo.updateMany(updateData);\n\n    return PROJECT_IS_ARCHIVED;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = archiveProject;\n"
  },
  {
    "path": "packages/server/usecase/project/archivedProjects.js",
    "content": "const {\n  OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst paginate = (projectRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n    const filter = params;\n    const response = {\n      list: await projectRepo.getDetails(filter),\n      count: await projectRepo.getCount(filter),\n    };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/project/create.js",
    "content": "/* global MESSAGE, _ */\nconst {\n  PROJECT_FAILED_CREATE, SERVER_ERROR, NEW_PROJECT_CREATED,\n} = require('../../constants/message').message;\nconst { projectCreationValidation } = require('../util/validation/projectCreate');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectRepo) => async (params) => {\n  try {\n    // Validate Request\n    const actualName = params.name;\n    if (params.name) {\n      let nameTemp = params.name;\n      nameTemp = nameTemp.replace(/-/g, '');\n      nameTemp = nameTemp.replace(/_/g, '');\n      params.name = nameTemp;\n      const {\n        value, error,\n      } = projectCreationValidation(params);\n      if (error) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: error,\n        };\n      }\n      params = value;\n    }\n    params.name = actualName;\n    /*\n     * const existingValidation = await projectRepo.get({ find: { name: params.name } });\n     * if (existingValidation) {\n     *   return { ...BAD_REQUEST, message: 'Project exists with same name.' };\n     * }\n     */\n\n    const created = await projectRepo.create(params);\n\n    if (!created) {\n      return PROJECT_FAILED_CREATE;\n    }\n\n    return {\n      ...NEW_PROJECT_CREATED,\n      data: _.pick(created, ['_id']),\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/project/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteProjectUseCase = require('./deleteDependency');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (projectRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteProjectUseCase(projectRepo))({ find: { _id: params.id } }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/project/deleteDependency.js",
    "content": "/* global MESSAGE,_ */\nconst dayjs = require('dayjs');\nconst ApplicationRepo = require('../../repo/application');\n\nconst applicationRepo = new ApplicationRepo();\n\nconst deleteApplicationUseCase = require('../application/deleteDependency')(applicationRepo);\n\nconst {\n  INVALID_REQUEST_PARAMS, PROJECT_DELETED,\n} = require('../../constants/message').message;\n\nconst deleteMany = (projectRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await projectRepo.getDetails(filter);\n    if (response && response.length) {\n      if (isHardDelete) {\n        await projectRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: {\n            isDeleted: true,\n            selfUpdatedAt: dayjs().toISOString(),\n          },\n        };\n        await projectRepo.updateMany(updateData);\n      }\n      await deleteApplicationUseCase({ find: { projectId: _.map(response, '_id') } }, isHardDelete);\n    }\n    return PROJECT_DELETED;\n  } catch (err) {\n    // console.log('error', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/project/explorePublicPaginate.js",
    "content": "/* global MESSAGE, _ , COMMON_CONSTANTS */\nconst CommonQueryRepository = require('../../models/Repo');\n\nconst applicationUseCase = require('../application/paginate');\n\nconst { APPLICATION_FIELDS } = require('../util/fieldsList');\n\nconst explorePublicPaginate = (projectRepo, applicationRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n    const filter = params;\n    if (!filter.find) {\n      filter.find = {};\n    }\n\n    filter.find.isPublic = true;\n\n    if (!filter.fields) {\n      filter.fields = ['_id', 'image', 'name', 'updatedAt',\n        'description', 'isArchive', 'createdAt'];\n    }\n    const search = params?.search;\n    const isArchive = !!filter.find?.isArchive;\n    delete filter.find?.isArchive;\n\n    // const companyAssociation = await\n    const companyAssociationFilter = {};\n    if (param.isGlobalSearch && filter.search) {\n      delete filter.isGlobalSearch;\n      const searchApplications = await applicationRepo.getDetails({\n        search: {\n          ...filter.search,\n          ...companyAssociationFilter?.applicationId,\n        },\n      });\n\n      if (searchApplications && searchApplications.length) {\n        filter.or = [{ _id: _.compact(_.uniq(_.map(searchApplications, (i) => i.projectId.toString()))) }];\n      }\n    }\n\n    // combine app in list\n    let appFilter = {\n      definitionId: params?.projectDefinitionId,\n      isPublic: true,\n      isDefaultPublic: { $ne: true },\n      ...companyAssociationFilter?.applicationId,\n    };\n    if (isArchive) {\n      appFilter = {\n        ...appFilter,\n        isArchive: true,\n      };\n    }\n\n    /*\n     * else {\n     *   appFilter = { ...appFilter, $or: [{ isArchive: false }, { isArchive: { $exists: false } }] };\n     * }\n     */\n    let applications = await (applicationUseCase(applicationRepo))({\n      params: appFilter,\n      search,\n      fields: [...APPLICATION_FIELDS, 'tags'],\n    });\n    if (applications.code !== MESSAGE.OK.code) {\n      return applications;\n    }\n    applications = applications.data.list;\n\n    const generatedIds = _.compact(_.uniq(applications.map((i) => i.generatedId)));\n\n    // get generate setting\n    const generateFilter = {\n      find: { _id: generatedIds },\n      fields: ['type', 'status', 'createdAt', 'updatedAt', '_id'],\n    };\n\n    const CommonQueryRepo = new CommonQueryRepository(COMMON_CONSTANTS.MODULE.GENERATOR);\n    const generatedData = await CommonQueryRepo.getDetails(generateFilter);\n\n    // Application map data\n    applications = _.map(applications, (app) => {\n      // Project generate setting assign\n      if (generatedData && app.generatedId) {\n        app.generatedIdData = _.find(generatedData, { _id: app.generatedId });\n      }\n\n      return app;\n    });\n\n    const response = {\n      list: applications,\n      count: applications.length,\n    };\n    return {\n      ...MESSAGE.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\nmodule.exports = explorePublicPaginate;\n"
  },
  {
    "path": "packages/server/usecase/project/get.js",
    "content": "/* global MESSAGE, */\nconst mongoose = require('mongoose');\n\nconst {\n  INVALID_REQUEST_PARAMS, PROJECT_NOT_FOUND,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for get user.\n * @return json\n */\nconst get = (projectRepo) => async (id) => {\n  try {\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n\n    // Validate Unique Criteria\n    const filter = {\n      filter: { find: { _id: id } },\n      fields: ['name', 'description', 'isArchive'],\n    };\n    const project = await projectRepo.get(filter);\n\n    if (!project) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    return {\n      ...MESSAGE.OK,\n      data: project,\n    };\n  } catch (err) {\n    return MESSAGE.SERVER_ERROR;\n  }\n};\n\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/project/noOfProjectAndApplication.js",
    "content": "/* global MESSAGE */\n\nconst resourceCount = ({\n  projectRepo, applicationRepo,\n}) => async () => {\n  try {\n    const filter = {};\n    const response = {\n      noOfProject: await projectRepo.getCount(filter),\n      noOfApplication: await applicationRepo.getCount(filter),\n    };\n    return {\n      ...MESSAGE.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return MESSAGE.SERVER_ERROR;\n  }\n};\nmodule.exports = resourceCount;\n"
  },
  {
    "path": "packages/server/usecase/project/paginate.js",
    "content": "/* eslint-disable consistent-return */\n/* eslint-disable array-callback-return */\n/* global MESSAGE, _ , COMMON_CONSTANTS */\nconst CommonQueryRepository = require('../../models/Repo');\nconst applicationUseCase = require('../application/paginate');\n\nconst {\n  APPLICATION_FIELDS, PROJECT_FIELDS,\n} = require('../util/fieldsList');\n\nconst paginate = (projectRepo, applicationRepo) => async (param) => {\n  try {\n    let applicationFilter = {};\n    if (param?.applicationFilter) {\n      applicationFilter = _.cloneDeep(param?.applicationFilter);\n      delete param.applicationFilter;\n    }\n\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n    const filter = params;\n    if (!filter.find) {\n      filter.find = {};\n      // filter.find.isArchive = false;\n    }\n\n    if (!filter.fields) {\n      filter.fields = PROJECT_FIELDS;\n    }\n\n    let [sortKey, sortValue] = ['updatedAt', -1];\n    if (params?.sortBy) {\n      [sortKey, sortValue] = Object.entries(params?.sortBy)?.[0];\n    }\n\n    /*\n     * const isArchive = !!filter.find?.isArchive;\n     * delete filter.find?.isArchive;\n     */\n\n    // const companyAssociation = await\n    const companyAssociationFilter = {};\n\n    if (param.isGlobalSearch && filter.search) {\n      delete filter.isGlobalSearch;\n      const searchApplications = await applicationRepo.getDetails({\n        search: {\n          ...filter.search,\n          ...companyAssociationFilter?.applicationId,\n        },\n      });\n\n      if (searchApplications && searchApplications.length) {\n        filter.or = [{ _id: _.compact(_.uniq(_.map(searchApplications, (i) => i.projectId.toString()))) }];\n      }\n    }\n\n    let list = await projectRepo.getDetails(filter);\n    const projectIds = _.map(list, '_id');\n    if (list.length) {\n      // combine app in list\n      const appFilter = {\n        projectId: { $in: projectIds },\n        ...companyAssociationFilter?.applicationId,\n        ...applicationFilter,\n      };\n      /*\n       * if (isArchive) {\n       *   appFilter = { ...appFilter, isArchive: true };\n       * } else {\n       *   appFilter = { ...appFilter, $or: [{ isArchive: false }, { isArchive: { $exists: false } }] };\n       * }\n       */\n      APPLICATION_FIELDS.push('output');\n      let applications = await (applicationUseCase(applicationRepo))({\n        params: appFilter,\n        fields: APPLICATION_FIELDS,\n      });\n      if (applications.code !== MESSAGE.OK.code) {\n        return applications;\n      }\n      applications = applications.data.list;\n\n      /*\n       * const archivedApplications = _.filter(applications, 'isArchive');\n       * if (params?.isArchive === true && archivedApplications.length === 0) {\n       *   list = [];\n       * }\n       */\n\n      const generatedIds = _.compact(_.uniq(applications.map((i) => {\n        if (i.generatedId) {\n          return i.generatedId;\n        }\n      })));\n\n      // tempGeneratedIds data get in response\n      const tempGeneratedIds = _.compact(_.uniq(applications.map((i) => {\n        if (i.tempGeneratedId) {\n          return i.tempGeneratedId;\n        }\n      })));\n\n      // get generate setting\n      const generateFilter = {\n        find: { _id: generatedIds },\n        fields: ['type', 'status', 'createdAt', 'updatedAt', '_id', 'semanticVersionNumber', 'versionNumber'],\n      };\n\n      // get tempGenerate setting\n      const tempGenerateFilter = {\n        find: { _id: tempGeneratedIds },\n        fields: ['type', 'status', 'createdAt', 'updatedAt', '_id', 'semanticVersionNumber', 'versionNumber'],\n      };\n\n      const CommonQueryRepo = new CommonQueryRepository(COMMON_CONSTANTS.MODULE.GENERATOR);\n      const generatedData = await CommonQueryRepo.getDetails(generateFilter);\n      const tempGeneratedData = await CommonQueryRepo.getDetails(tempGenerateFilter);\n\n      // Group by application\n      const acceessPermissionsGroupBy = _.groupBy({}, 'applicationId');\n\n      // Application map data\n      applications = _.map(applications, (app) => {\n        const applicationPermission = acceessPermissionsGroupBy[app._id.toString()];\n        app.assignedUserCount = applicationPermission?.length ?? 0;\n\n        // Project generate setting assign\n        if (generatedData && app.generatedId) {\n          app.generatedIdData = _.find(generatedData, { _id: app.generatedId });\n        }\n\n        // Project tempGenerate setting assign\n        if (tempGeneratedData && app.tempGeneratedId) {\n          app.tempGeneratedIdData = _.find(tempGeneratedData, { _id: app.tempGeneratedId });\n        }\n\n        return app;\n      });\n\n      // Project\n      const listUnarchive = _.orderBy(list?.filter((i) => !i.isArchive), [sortKey], [sortValue === 1 ? 'asc' : 'desc']);\n      const listArchive = _.orderBy(list?.filter((i) => i.isArchive === true), [sortKey], [sortValue === 1 ? 'asc' : 'desc']);\n      list = [...listUnarchive, ...listArchive];\n\n      // Application\n      const applicationUnarchive = _.orderBy(applications?.filter((i) => !i.isArchive), [sortKey], [sortValue === 1 ? 'asc' : 'desc']);\n      const applicationArchive = _.orderBy(applications?.filter((i) => i.isArchive === true), [sortKey], [sortValue === 1 ? 'asc' : 'desc']);\n\n      applications = [...applicationUnarchive, ...applicationArchive];\n      applications = _.groupBy(applications, 'projectId');\n\n      list = _.filter(list, (l) => {\n        if (applications[l?._id.toString()]) {\n          l.applications = applications[l?._id.toString()];\n        }\n\n        return l;\n      });\n    }\n    const response = {\n      list,\n      count: await projectRepo.getCount(filter),\n      user: null,\n    };\n\n    return {\n      ...MESSAGE.OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return MESSAGE.SERVER_ERROR;\n    // return { ...MESSAGE.SERVER_ERROR, data: err.toString() };\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/project/unArchive.js",
    "content": "const mongoose = require('mongoose');\n\nconst {\n  SERVER_ERROR,\n  PROJECT_NOT_FOUND,\n  PROJECT_IS_UNARCHIVED,\n  PROJECT_NOT_IN_ARCHIVE,\n  INVALID_REQUEST_PARAMS,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for update project-config.\n * @return json\n */\nconst unArchiveProject = (projectRepo, applicationRepo) => async (\n  id,\n) => {\n  try {\n    // Validate Unique Criteria\n    const filter = { find: { _id: id } };\n    if (id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const projectData = await projectRepo.get(filter);\n\n    if (!projectData) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    if (projectData?.isArchive === false) {\n      return PROJECT_NOT_IN_ARCHIVE;\n    }\n\n    const updateResponse = await projectRepo.update(\n      id,\n      { isArchive: false },\n    );\n    const updateData = {\n      filter: { find: { projectId: updateResponse._id } },\n      data: { isArchive: false },\n    };\n\n    await applicationRepo.updateMany(updateData);\n\n    return PROJECT_IS_UNARCHIVED;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = unArchiveProject;\n"
  },
  {
    "path": "packages/server/usecase/project/update.js",
    "content": "/* global MESSAGE,_ */\nconst mongoose = require('mongoose');\n// const validate = require('validate.js');\nconst dayjs = require('dayjs');\nconst {\n  INVALID_REQUEST_PARAMS, PROJECT_NOT_FOUND, SERVER_ERROR, PROJECT_UPDATED,\n} = require('../../constants/message').message;\nconst { projectUpdateValidation } = require('../util/validation/projectUpdate');\n\n// Validation\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (projectRepo) => async (id, params) => {\n  try {\n    /*\n     * Validate Request\n     * const errors = await validateData(params);\n     */\n    const actualName = params.name;\n    if (params.name) {\n      let nameTemp = params.name;\n      nameTemp = nameTemp.replace(/-/g, '');\n      nameTemp = nameTemp.replace(/_/g, '');\n      params.name = nameTemp;\n      const {\n        value, error,\n      } = projectUpdateValidation(params);\n      if (error) {\n        return {\n          data: null,\n          code: MESSAGE.BAD_REQUEST.code,\n          message: error,\n        };\n      }\n      params = value;\n    }\n    params.name = actualName;\n\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    // Validate Unique Criteria\n    const filter = { _id: id };\n    const project = await projectRepo.get({ filter });\n\n    if (!project) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    params.selfUpdatedAt = dayjs().toISOString();\n    const updateResponse = await projectRepo.update(id, _.pick(params, ['name', 'description']));\n    return {\n      ...PROJECT_UPDATED,\n      data: _.pick(updateResponse, ['name', 'description']),\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/project/upsert.js",
    "content": "/* global MESSAGE */\nconst mongoose = require('mongoose');\nconst dayjs = require('dayjs');\nconst {\n  SERVER_ERROR, PROJECT_NOT_FOUND, INVALID_REQUEST_PARAMS,\n  PROJECT_IS_ARCHIVED, PROJECT_IS_UNARCHIVED,\n} = require('../../constants/message').message;\nconst { projectUpsertValidation } = require('../util/validation/projectUpsert');\n\n/**\n *\n * Function used for update project-config.\n * @return json\n */\nconst archiveProject = (projectRepo, applicationRepo) => async (id, params) => {\n  try {\n    if (params.isOver) { params.isPublicConsent = params.isOver; }\n    // const errors = await validateData(params);\n\n    /*\n     * if (errors) {\n     *   return { ...INVALID_REQUEST_PARAMS, data: errors };\n     * }\n     */\n    const {\n      value, error,\n    } = projectUpsertValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    // Validate Unique Criteria\n    const filter = { find: { _id: id } };\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const projectData = await projectRepo.get(filter);\n\n    if (!projectData) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    params.selfUpdatedAt = dayjs().toISOString();\n    const updateResponse = await projectRepo.update(id, params);\n    const updateData = {\n      filter: { find: { projectId: updateResponse._id } },\n      data: {\n        isArchive: params.isArchive,\n        isPublicConsent: params.isPublicConsent,\n      },\n    };\n\n    await applicationRepo.updateMany(updateData);\n\n    if (params.isArchive) {\n      return {\n        ...PROJECT_IS_ARCHIVED,\n        data: updateResponse,\n      };\n    }\n\n    return {\n      ...PROJECT_IS_UNARCHIVED,\n      data: updateResponse,\n    };\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = archiveProject;\n"
  },
  {
    "path": "packages/server/usecase/projectConstant/create.js",
    "content": "/* global MESSAGE, */\nconst mongoose = require('mongoose');\n\nconst {\n  INVALID_REQUEST_PARAMS, RECORD_WITH_SAME_NAME_EXISTS, SERVER_ERROR, CONSTANT_CREATED,\n} = require('../../constants/message').message;\nconst { projectConstantValidation } = require('../util/validation/projectConstant');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectConstantRepo, applicationRepo) => async (params) => {\n  try {\n    // Validate Request\n    const {\n      value, error,\n    } = projectConstantValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    if (params.modelId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.modelId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const filter = {\n      or: [{ fileName: params.fileName }],\n      find: {\n        isActive: { $in: [true, false] },\n        applicationId: params.applicationId,\n      },\n    };\n    const checkProjectConstant = await projectConstantRepo.get({ filter });\n\n    // Validate Unique Criteria\n    if (checkProjectConstant) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    const created = await projectConstantRepo.create(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    projectApplicationUpdate({\n      params: { applicationId: params.applicationId },\n      isProjectId: true,\n    });\n    return {\n      ...CONSTANT_CREATED,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/projectConstant/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteConstantUseCase = require('./deleteDependency');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (projectConstantRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteConstantUseCase(projectConstantRepo, applicationRepo))({\n      find: {\n        _id: params.id,\n        isActive: { $in: [true, false] },\n      },\n    }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/projectConstant/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, CONSTANT_DELETED,\n} = require('../../constants/message').message;\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst deleteMany = (projectConstantRepo, applicationRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await projectConstantRepo.getDetails(filter);\n    if (response && response.length) {\n      const application = await applicationRepo.get({\n        filter: { find: { _id: response?.[0]?.applicationId } },\n        fields: ['isArchive', 'projectId'],\n      });\n\n      if (isHardDelete) {\n        await projectConstantRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await projectConstantRepo.updateMany(updateData);\n      }\n      projectApplicationUpdate({\n        params: {\n          applicationId: response?.[0]?.applicationId,\n          projectId: application?.projectId,\n        },\n      });\n    }\n    return {\n      ...CONSTANT_DELETED,\n      data: null,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/projectConstant/paginate.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst paginate = (projectConstantRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    if (!params.find) {\n      params.find = {};\n    }\n    params.find.applicationId = params.applicationId;\n    const filter = params;\n    const list = await projectConstantRepo.getDetails(filter);\n    const response = {\n      list,\n      count: await projectConstantRepo.getCount(filter),\n    };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/projectConstant/update.js",
    "content": "/* global MESSAGE, */\nconst mongoose = require('mongoose');\nconst {\n  RECORD_WITH_SAME_NAME_EXISTS, PROJECT_NOT_FOUND, SERVER_ERROR, CONSTANT_UPDATED, INVALID_REQUEST_PARAMS,\n} = require('../../constants/message').message;\nconst { projectConstantValidation } = require('../util/validation/projectConstant');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (projectConstantRepo, applicationRepo) => async (id, params) => {\n  try {\n    const {\n      value, error,\n    } = projectConstantValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    params = value;\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const checkFilter = {\n      or: [{ fileName: params.fileName }],\n      ne: [{ _id: id }],\n      find: {\n        isActive: { $in: [true, false] },\n        applicationId: params.applicationId,\n      },\n    };\n    const checkProjectConstant = await projectConstantRepo.get({ filter: checkFilter });\n\n    // Validate Unique Criteria\n    if (checkProjectConstant) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    // Validate Unique Criteria\n    const filter = {\n      find: {\n        _id: id,\n        isActive: [true, false],\n      },\n    };\n    const project = await projectConstantRepo.get({ filter });\n\n    if (!project) {\n      return PROJECT_NOT_FOUND;\n    }\n\n    const updateConstant = await projectConstantRepo.update(id, params);\n    if (!updateConstant) {\n      return SERVER_ERROR;\n    }\n\n    const updatedConstantData = await projectConstantRepo.get({\n      find: {\n        _id: updateConstant._id,\n        isActive: [true, false],\n      },\n    });\n\n    projectApplicationUpdate({\n      params: { applicationId: params.applicationId },\n      isProjectId: true,\n    });\n    return {\n      ...CONSTANT_UPDATED,\n      data: updatedConstantData,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/create.js",
    "content": "/* global MESSAGE, */\nconst mongoose = require('mongoose');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst {\n  INVALID_REQUEST_PARAMS, RECORD_WITH_SAME_NAME_EXISTS, SERVER_ERROR, MIDDLEWARE_CREATED,\n} = require('../../constants/message').message;\nconst { projectPolicyCreateValidation } = require('../util/validation/projectPolicy');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectPolicyRepo, applicationRepo) => async (params) => {\n  try {\n    // Validate Request\n\n    const {\n      value, error,\n    } = projectPolicyCreateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['projectId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const filter = {\n      or: [{ fileName: params.fileName }],\n      find: {\n        isActive: { $in: [true, false] },\n        applicationId: params.applicationId,\n      },\n    };\n    const checkProjectPolicy = await projectPolicyRepo.get({ filter });\n\n    // Validate Unique Criteria\n    if (checkProjectPolicy) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    const created = await projectPolicyRepo.create(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    projectApplicationUpdate({\n      params: {\n        projectId: applicationData?.data?.projectId,\n        applicationId: params.applicationId,\n      },\n    });\n    return {\n      ...MIDDLEWARE_CREATED,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deletePolicyUseCase = require('./deleteDependency');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (projectPolicyRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deletePolicyUseCase(projectPolicyRepo, applicationRepo))({\n      find: {\n        _id: params.id,\n        isActive: { $in: [true, false] },\n      },\n    }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/deleteDependency.js",
    "content": "/* global _ */\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, ALREADY_USED_POLICY, SCHEMA_NOT_FOUND, MIDDLEWARE_DELETED,\n} = require('../../constants/message').message;\n\nconst SchemaDetailRepo = require('../../repo/schemaDetail');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst SchemaRepo = require('../../repo/schema');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\n\nconst schemaDetailRepository = new SchemaDetailRepo();\nconst schemaRepository = new SchemaRepo();\nconst projectRouteRepository = new ProjectRouteRepo();\n\nconst {\n  additionalJsonObj, schemaJsonObj,\n} = require('./util/dependentCond');\n\nconst deleteMany = (projectPolicyRepo, applicationRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await projectPolicyRepo.getDetails(filter);\n    if (response && response.length) {\n      const application = await applicationRepo.get({\n        filter: { find: { _id: response?.[0]?.applicationId } },\n        fields: ['isArchive', 'configInput', 'projectId'],\n      });\n\n      // Get applicationId from `Schema` collection.\n      const getSchema = await schemaRepository.getDetails({\n        find: { applicationId: response[0].applicationId },\n        fields: ['_id'],\n      });\n      if (!getSchema) {\n        return SCHEMA_NOT_FOUND;\n      }\n      const schemaIds = _.compact(_.map(getSchema, '_id'));\n\n      const schemaJsonData = await schemaJsonObj(application, response[0]);\n      const additionalJsonData = await additionalJsonObj(application, response[0]);\n\n      const orCondArr = [...schemaJsonData, ...additionalJsonData];\n\n      const schemaFilter = {\n        find: { schemaId: schemaIds },\n        or: orCondArr,\n      };\n      const schemaDetails = await schemaDetailRepository.getDetails(schemaFilter);\n      if (schemaDetails && _.size(schemaDetails) > 0) {\n        return ALREADY_USED_POLICY;\n      }\n\n      // Check policy dependency in `Project-Routes`.\n      const projectRouteFilter = {\n        find: {\n          applicationId: response[0].applicationId,\n          policies: response[0].fileName,\n        },\n      };\n      const projectRoutes = await projectRouteRepository.getDetails(projectRouteFilter);\n      if (projectRoutes && _.size(projectRoutes) > 0) {\n        return ALREADY_USED_POLICY;\n      }\n\n      if (isHardDelete) {\n        await projectPolicyRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await projectPolicyRepo.updateMany(updateData);\n      }\n      projectApplicationUpdate({\n        params: {\n          projectId: application?.projectId,\n          applicationId: response[0].applicationId,\n        },\n      });\n    }\n    return {\n      ...MIDDLEWARE_DELETED,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/paginate.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst paginate = (projectPolicyRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    if (!params.find) {\n      params.find = {};\n    }\n    params.find.applicationId = params.applicationId;\n    const filter = params;\n    const list = await projectPolicyRepo.getDetails(filter);\n    const response = {\n      list,\n      count: await projectPolicyRepo.getCount(filter),\n    };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/update.js",
    "content": "/* global MESSAGE, _ */\nconst mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, PROJECT_POLICY_NOT_FOUND, RECORD_WITH_SAME_NAME_EXISTS, SERVER_ERROR, ALREADY_USED_POLICY, MIDDLEWARE_UPDATED, OK,\n} = require('../../constants/message').message;\n\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst SchemaDetailRepo = require('../../repo/schemaDetail');\nconst SchemaRepo = require('../../repo/schema');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\n\nconst schemaDetailRepository = new SchemaDetailRepo();\nconst projectRouteRepository = new ProjectRouteRepo();\nconst schemaRepository = new SchemaRepo();\nconst { projectPolicyUpdateValidation } = require('../util/validation/projectPolicy');\nconst {\n  additionalJsonObj, schemaJsonObj,\n} = require('./util/dependentCond');\n// Validation\n\n/**\n *\n * Function used for validate request.\n * @description ::  Find Documentation @ http://validatejs.org/\n * @return mixed :: If error occurred then return array of errors else return undefined | null\n */\n/*\n * async function validateData(data) {\n *   const constraints = {\n *     customJson: {\n *       presence: true,\n *     },\n *     fileName: {\n *       type: 'string',\n *       presence: true,\n *     },\n *     applicationId: {\n *       type: 'string',\n *       presence: true,\n *     },\n *   };\n */\n\n//   const errors = validate(data, constraints);\n\n/*\n *   if (errors) {\n *     return errors;\n *   }\n *   return null;\n * }\n */\n\n/**\n * Function used to update policyName in `Schema-Details` and `Project-Route`.\n * @param  {} {params\n * @param  {} policyData\n * @param  {} }\n */\nasync function udpdatePolicyNameInSchemaDetailsAndRoutes ({\n  params, policyData,\n}) {\n  try {\n    // Update `policy-name` in `project-routes`.\n    const projectRouteFilter = {\n      find: {\n        applicationId: params.applicationId,\n        policies: policyData.fileName,\n      },\n    };\n    const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const routesData = await projectRouteRepository.getDetails(projectRouteFilter);\n    if (routesData && routesData.length) {\n      await Promise.all(routesData.map(async (route) => {\n        let policies = [];\n        if (route?.policies && _.includes(route.policies, policyData.fileName)) {\n          policies = _.pull(route.policies, policyData.fileName);\n          policies.push(params.fileName);\n          policies = _.compact(policies);\n          await projectRouteRepository.update(route._id, { policies });\n        }\n      }));\n    }\n\n    // Update `policy-name` in `schema-details`.\n    const getSchema = await schemaRepository.getDetails({\n      find: { applicationId: policyData.applicationId },\n      fields: ['_id'],\n    });\n\n    const schemaIds = _.compact(_.map(getSchema, '_id'));\n    if (schemaIds && _.size(schemaIds) > 0) {\n      const schemaDetails = await schemaDetailRepository.getDetails({ find: { schemaId: schemaIds } });\n      if (schemaDetails && _.size(schemaDetails) > 0) {\n        await Promise.all(schemaDetails.map(async (scDetail) => {\n          let schemaJsonUpdate = false;\n          let additionalJsonUpdate = false;\n          const updateData = {};\n          _.each(scDetail.schemaJson, (schemaJson) => {\n            _.map(schemaJson, (v) => {\n              if (v?.policy && _.includes(v.policy, policyData.fileName)) {\n                v.policy = _.pull(v.policy, policyData.fileName);\n                v.policy.push(params.fileName);\n                v.policy = _.compact(v.policy);\n                schemaJsonUpdate = true;\n              }\n            });\n          });\n\n          _.each(scDetail.additionalJson.additionalSetting, (addJson) => {\n            _.each(addJson, (v) => {\n              if (v?.policy && _.includes(v.policy, policyData.fileName)) {\n                v.policy = _.pull(v.policy, policyData.fileName);\n                v.policy.push(params.fileName);\n                v.policy = _.compact(v.policy);\n                additionalJsonUpdate = true;\n              }\n            });\n          });\n\n          if (schemaJsonUpdate) {\n            updateData.schemaJson = scDetail.schemaJson;\n          }\n          if (additionalJsonUpdate) {\n            updateData.additionalJson = scDetail.additionalJson;\n          }\n\n          if (!_.isEmpty(updateData)) {\n            await schemaDetailRepository.update(scDetail._id, updateData);\n          }\n        }));\n      }\n    }\n\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return SERVER_ERROR;\n  }\n}\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (projectPolicyRepo, applicationRepo) => async (id, params) => {\n  try {\n    /*\n     * Validate Request\n     * const errors = await validateData(params);\n     */\n\n    /*\n     * if (errors || !id) {\n     *   return { ...INVALID_REQUEST_PARAMS, data: errors };\n     * }\n     */\n    const {\n      value, error,\n    } = projectPolicyUpdateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['configInput', 'projectId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const applicationDetails = _.cloneDeep(applicationData.data);\n\n    const checkFilter = {\n      or: [{ fileName: params.fileName }],\n      ne: [{ _id: id }],\n      in: [{ isActive: [true, false] }],\n      find: { applicationId: params.applicationId },\n    };\n    const checkProjectPolicy = await projectPolicyRepo.get({ filter: checkFilter });\n\n    // Validate Unique Criteria\n    if (checkProjectPolicy) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    const filter = {\n      find: {\n        _id: id,\n        isActive: { $in: [true, false] },\n      },\n    };\n    const policyData = await projectPolicyRepo.get({ filter });\n\n    if (!policyData) {\n      return PROJECT_POLICY_NOT_FOUND;\n    }\n\n    if (params.isActive === false) {\n      // Check policy dependency in `Schem-Details`.\n\n      // Get applicationId from `Schema` collection.\n      const getSchema = await schemaRepository.getDetails({\n        find: { applicationId: policyData.applicationId },\n        fields: ['_id'],\n      });\n\n      const schemaIds = _.compact(_.map(getSchema, '_id'));\n      if (schemaIds && _.size(schemaIds) > 0) {\n        const schemaJsonData = await schemaJsonObj(applicationDetails, policyData);\n        const additionalJsonData = await additionalJsonObj(applicationDetails, policyData);\n\n        const orCondArr = [...schemaJsonData, ...additionalJsonData];\n\n        const schemaFilter = {\n          find: { schemaId: schemaIds },\n          or: orCondArr,\n        };\n        const schemaDetails = await schemaDetailRepository.getDetails(schemaFilter);\n        if (schemaDetails && _.size(schemaDetails) > 0) {\n          return ALREADY_USED_POLICY;\n        }\n      }\n\n      // Check policy dependency in `Project-Routes`.\n      const projectRouteFilter = {\n        find: {\n          applicationId: params.applicationId,\n          policies: policyData.fileName,\n        },\n      };\n      const projectRoutes = await projectRouteRepository.getDetails(projectRouteFilter);\n      if (projectRoutes && _.size(projectRoutes) > 0) {\n        return ALREADY_USED_POLICY;\n      }\n    }\n\n    // Update policyName in `Schema-Details` and `Project-Route`.\n    if (params.fileName !== policyData.fileName) {\n      const updateRes = await udpdatePolicyNameInSchemaDetailsAndRoutes({\n        params,\n        policyData,\n      });\n\n      if (updateRes.code !== OK.code) {\n        return updateRes;\n      }\n    }\n\n    projectApplicationUpdate({\n      params: {\n        projectId: applicationData?.data?.projectId,\n        applicationId: params.applicationId,\n      },\n    });\n    const updateResponse = await projectPolicyRepo.update(id, params);\n    return {\n      ...MIDDLEWARE_UPDATED,\n      data: updateResponse,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/projectPolicy/util/dependentCond.js",
    "content": "/* global _ */\nconst schemaJsonObj = (project, policy) => {\n  let schemaJsonData = [];\n  if (project?.configInput?.platform) {\n    _.map(project.configInput.platform, (val) => {\n      const sjKey = `schemaJson.${val}`;\n      const sObj = {};\n      sObj[sjKey] = { $elemMatch: { policy: policy.fileName } };\n      schemaJsonData.push(sObj);\n    });\n  } else {\n    // Default schemaJson\n    schemaJsonData = [\n      { 'schemaJson.device': { $elemMatch: { policy: policy.fileName } } },\n      { 'schemaJson.desktop': { $elemMatch: { policy: policy.fileName } } },\n      { 'schemaJson.client': { $elemMatch: { policy: policy.fileName } } },\n      { 'schemaJson.admin': { $elemMatch: { policy: policy.fileName } } },\n    ];\n  }\n\n  return schemaJsonData;\n};\n\nconst additionalJsonObj = (project, policy) => {\n  // Check policy in additionalJson.\n  let additionalJsonData = [];\n  const operations = ['C', 'R', 'U', 'D', 'BC', 'BU', 'HD'];\n  if (project?.configInput?.platform) {\n    _.map(project.configInput.platform, (val) => {\n      _.map(operations, (op) => {\n        const ajKey = `additionalJson.additionalSetting.${val}.${op}.policy`;\n        const addObj = {};\n        addObj[ajKey] = policy.fileName;\n        additionalJsonData.push(addObj);\n      });\n    });\n  } else {\n    additionalJsonData = [\n      { 'additionalJson.additionalSetting.admin.C.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.R.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.U.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.D.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.BC.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.BU.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.admin.HD.policy': policy.fileName },\n\n      { 'additionalJson.additionalSetting.device.C.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.R.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.U.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.D.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.BC.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.BU.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.device.HD.policy': policy.fileName },\n\n      { 'additionalJson.additionalSetting.desktop.C.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.R.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.U.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.D.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.BC.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.BU.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.desktop.HD.policy': policy.fileName },\n\n      { 'additionalJson.additionalSetting.client.C.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.R.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.U.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.D.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.BC.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.BU.policy': policy.fileName },\n      { 'additionalJson.additionalSetting.client.HD.policy': policy.fileName },\n    ];\n  }\n\n  return additionalJsonData;\n};\n\nmodule.exports = {\n  schemaJsonObj,\n  additionalJsonObj,\n};\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deletePolicyUseCase = require('./deleteDependency');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (projectRoleAccessPermissionsRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deletePolicyUseCase(projectRoleAccessPermissionsRepo))({\n      find: {\n        _id: params.id,\n        isActive: { $in: [true, false] },\n      },\n    }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, ROLE_PERMISSIONS_DELETED,\n} = require('../../constants/message').message;\n\nconst ApplicationRepository = require('../../repo/application');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst applicationRepo = new ApplicationRepository();\n\nconst deleteMany = (projectRoleAccessPermissionsRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await projectRoleAccessPermissionsRepo.getDetails(filter);\n    if (response && response.length) {\n      const application = await applicationRepo.get({\n        filter: { find: { _id: response[0].applicationId } },\n        fields: ['isArchive', 'projectId'],\n      });\n\n      if (isHardDelete) {\n        await projectRoleAccessPermissionsRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await projectRoleAccessPermissionsRepo.updateMany(updateData);\n      }\n      projectApplicationUpdate({\n        params: {\n          applicationId: response[0].applicationId,\n          projectId: application?.projectId,\n        },\n      });\n    }\n    return {\n      ...ROLE_PERMISSIONS_DELETED,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/paginate.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, ROLE_PERMISSIONS_RETRIEVED,\n} = require('../../constants/message').message;\n\nconst paginate = (projectRoleAccessPermissionsRepo) => async (params) => {\n  try {\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const filter = { find: { applicationId: params.applicationId } };\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const list = await projectRoleAccessPermissionsRepo.getDetails(filter);\n    const response = {\n      list,\n      count: await projectRoleAccessPermissionsRepo.getCount(filter),\n    };\n    return {\n      ...ROLE_PERMISSIONS_RETRIEVED,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/upsert.js",
    "content": "/* global MESSAGE, _ */\nconst mongoose = require('mongoose');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst {\n  RECORD_WITH_SAME_NAME_EXISTS, SERVER_ERROR, ROLE_PERMISSIONS_CREATED, ROLE_PERMISSIONS_UPDATED, INVALID_REQUEST_PARAMS,\n} = require('../../constants/message').message;\n\nconst ApplicationRepository = require('../../repo/application');\nconst { projectRoleAccessPermissionValidation } = require('../util/validation/projectRoleAccessPermission');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst applicationRepo = new ApplicationRepository();\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectRoleAccessPermissionsRepo) => async (params) => {\n  try {\n    // Validate Request\n\n    const {\n      value, error,\n    } = projectRoleAccessPermissionValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    if (params.id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['projectId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    // Check already exists.\n    const filter = {\n      find: {\n        name: params.name,\n        applicationId: params.applicationId,\n      },\n    };\n    if (params?.id) {\n      filter.nin = [{ _id: params.id }];\n    }\n    const checkRolePermissions = await projectRoleAccessPermissionsRepo.get(filter);\n    if (checkRolePermissions) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    let rolePermissionsData = {};\n    if (params?.id) {\n      const { id } = params;\n      const updateFilter = _.cloneDeep(_.omit(params, 'id'));\n      rolePermissionsData = await projectRoleAccessPermissionsRepo.update(id, updateFilter);\n      projectApplicationUpdate({\n        params: {\n          applicationId: params.applicationId,\n          projectId: applicationData?.data?.projectId,\n        },\n      });\n      return {\n        ...ROLE_PERMISSIONS_UPDATED,\n        data: rolePermissionsData,\n      };\n    }\n    rolePermissionsData = await projectRoleAccessPermissionsRepo.create(params);\n    projectApplicationUpdate({\n      params: {\n        applicationId: params.applicationId,\n        projectId: applicationData?.data?.projectId,\n      },\n    });\n    return {\n      ...ROLE_PERMISSIONS_CREATED,\n      data: rolePermissionsData,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/util/RemoveModelDetails.js",
    "content": "/* global  _ */\nconst mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../../constants/message').message;\n\nconst RemoveModelDetails = (projectRoleAccessPermissionsRepo) => async (params) => {\n  try {\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    if (params.modelId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.modelId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const filter = {\n      find: {\n        applicationId: params.applicationId,\n        customJson: { $elemMatch: { modelId: params.modelId } },\n      },\n    };\n\n    const rolePermissions = await projectRoleAccessPermissionsRepo.getDetails(filter);\n    if (rolePermissions && rolePermissions.length > 0) {\n      for (let i = 0; i < rolePermissions.length; i += 1) {\n        const roleAccessPermission = _.cloneDeep(rolePermissions[i]);\n        let { customJson } = roleAccessPermission;\n\n        customJson = _.map(customJson, (v) => {\n          if (v.modelId && v.modelId.toString() !== params.modelId.toString()) {\n            return v;\n          }\n          return {};\n        });\n        customJson = _.reject(customJson, _.isEmpty);\n        // eslint-disable-next-line no-await-in-loop\n        await projectRoleAccessPermissionsRepo.update(roleAccessPermission._id, { customJson });\n      }\n    }\n    return OK;\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = RemoveModelDetails;\n"
  },
  {
    "path": "packages/server/usecase/projectRoleAccessPermissions/util/index.js",
    "content": "const RemoveModelDetails = require('./RemoveModelDetails');\n\nmodule.exports = { RemoveModelDetails };\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/create.js",
    "content": "/* global MESSAGE,_ */\nconst mongoose = require('mongoose');\n\nconst { PROJECT_DEFINITION_CODE } = require('../../models/constants/projectDefinition');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, ROUTE_CREATED, SAME_ROUTES_EXISTS,\n} = require('../../constants/message').message;\n\nconst QueryBuilderRepo = require('../../repo/queryBuilder');\nconst NestedQueryBuilderRepo = require('../../repo/nestedQueryBuilder');\n\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst queryBuilderRepo = new QueryBuilderRepo();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepo();\n\nconst queryBuilderUseCase = require('../queryBuilder/insertMany');\nconst nestedQueryBuilderUseCase = require('../nestedQueryBuilder/insertMany');\nconst { TYPES } = require('../../constants/queryBuilder');\nconst { projectRouteCreateValidation } = require('../util/validation/projectRoute');\n\n/**\n * Function used to retrieve and store query-builder data.\n * @param  {} {params\n * @param  {} routeData\n * @param  {} projectOwner\n * @param  {} }\n */\nasync function getQueryBuilder ({\n  params, routeData,\n}) {\n  // Store query-builder data.\n  if (params && params.queryBuilder && _.size(params.queryBuilder) > 0) {\n    _.each(params.queryBuilder, (val) => {\n      if (val && val.filter) {\n        val.filter = _.cloneDeep(JSON.stringify(val.filter));\n      }\n\n      val.applicationId = params.applicationId;\n      val.referenceId = routeData._id;\n      val.referenceType = TYPES.ROUTES;\n      delete val._id;\n    });\n\n    const queryBuilderData = await queryBuilderUseCase(queryBuilderRepo)(params.queryBuilder);\n    if (!queryBuilderData.code || queryBuilderData.code !== OK.code) {\n      return queryBuilderData;\n    }\n  }\n  if (params.applicationId) {\n    const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n  }\n  // Retrieved query-builder data.\n  let queryBuilderData = [];\n  const qBuilderInput = {\n    find: {\n      applicationId: params.applicationId,\n      referenceId: routeData._id,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let qBuilderData = await queryBuilderRepo.getDetails(qBuilderInput);\n  if (qBuilderData && _.size(qBuilderData) > 0) {\n    qBuilderData = _.map(qBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    queryBuilderData = _.cloneDeep(qBuilderData);\n  }\n\n  return {\n    ...OK,\n    data: queryBuilderData,\n  };\n}\n\n/**\n * Function used to retrieve and store Nested-query-builder data.\n * @param  {} params\n * @param  {} routeData\n * @param  {} }\n */\nasync function getNestedQueryBuilder ({\n  params, routeData,\n}) {\n  let nestedQueryBuilderData = [];\n\n  // Store nested-query-builder data.\n  if (params && params.nestedQueryBuilder && _.size(params.nestedQueryBuilder) > 0) {\n    _.each(params.nestedQueryBuilder, (val) => {\n      if (val && val.filter) {\n        val.filter = _.cloneDeep(JSON.stringify(val.filter));\n      }\n\n      val.applicationId = params.applicationId;\n      val.referenceId = routeData._id;\n      val.referenceType = TYPES.ROUTES;\n      delete val._id;\n    });\n\n    const nqBuilderData = await nestedQueryBuilderUseCase(nestedQueryBuilderRepo)(params.nestedQueryBuilder);\n    if (nqBuilderData.code !== OK.code) {\n      return nqBuilderData;\n    }\n  }\n\n  // Retrieve nested-query-builder data.\n  const qBuilderInput = {\n    find: {\n      applicationId: params.applicationId,\n      referenceId: routeData._id,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let nqBuilderData = await nestedQueryBuilderRepo.getDetails(qBuilderInput);\n  if (nqBuilderData && _.size(nqBuilderData) > 0) {\n    nqBuilderData = _.map(nqBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    nestedQueryBuilderData = _.cloneDeep(nqBuilderData);\n  }\n\n  return {\n    ...OK,\n    data: nestedQueryBuilderData,\n  };\n}\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectRouteRepo, applicationRepo) => async (params) => {\n  try {\n    // Validate Request\n\n    let isNodeApp = false;\n    if (params?.definitionType && params.definitionType === PROJECT_DEFINITION_CODE.NODE_EXPRESS) {\n      isNodeApp = true;\n    }\n\n    const {\n      value, error,\n    } = projectRouteCreateValidation(params, isNodeApp);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    if (params?.controller) {\n      params.controller = _.capitalize(params.controller);\n    }\n\n    const filter = {\n      or: [{ route: params.route }],\n      find: { applicationId: params.applicationId },\n    };\n    if (params?.controller && params?.action) {\n      filter.or.push({\n        action: params.action,\n        controller: params.controller,\n      });\n    }\n    const checkRoute = await projectRouteRepo.get({ filter });\n\n    // Validate Unique Criteria\n    if (checkRoute) {\n      return SAME_ROUTES_EXISTS;\n    }\n\n    if (!params.modelId) {\n      params.groupName = null;\n    }\n\n    const created = await projectRouteRepo.create(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n\n    // Store & Retrieve query-builder-data.\n    const qBuilderData = await getQueryBuilder({\n      params,\n      routeData: created,\n    });\n    if (qBuilderData.code !== OK.code) {\n      return qBuilderData;\n    }\n    const queryBuilderData = _.cloneDeep(qBuilderData.data);\n\n    // Store & Retrieve nested-query-builder-data.\n    const nqBuilderData = await getNestedQueryBuilder({\n      params,\n      routeData: created.toObject(),\n    });\n    if (nqBuilderData.code !== OK.code) {\n      return nqBuilderData;\n    }\n    const nestedQueryBuilder = _.cloneDeep(nqBuilderData.data);\n\n    const response = created.toObject();\n    response.queryBuilder = queryBuilderData;\n    response.nestedQueryBuilder = nestedQueryBuilder;\n    projectApplicationUpdate({\n      params: { applicationId: params.applicationId },\n      isProjectId: true,\n    });\n\n    const responseMsg = ROUTE_CREATED;\n\n    return {\n      ...responseMsg,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteRouteUseCase = require('./deleteDependency');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (projectRouteRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteRouteUseCase(projectRouteRepo, applicationRepo))({ find: { _id: params.id } }, params.isHardDelete, params.definitionType);\n    return response;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, ROUTE_DELETED, OK,\n} = require('../../constants/message').message;\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst { TYPES } = require('../../constants/queryBuilder');\nconst QueryBuilderRepository = require('../../repo/queryBuilder');\nconst NestedQueryBuilderRepository = require('../../repo/nestedQueryBuilder');\n\nconst queryBuilderRepo = new QueryBuilderRepository();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepository();\n\nconst deleteMany = (projectRouteRepo, applicationRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await projectRouteRepo.getDetails(filter);\n    if (response && response.length) {\n      const application = await applicationRepo.get({\n        filter: { find: { _id: response?.[0]?.applicationId } },\n        fields: ['isArchive', 'projectId'],\n      });\n\n      if (isHardDelete) {\n        // Delete query-builder\n        await queryBuilderRepo.deleteMany({\n          find: {\n            referenceId: filter.find._id,\n            referenceType: TYPES.ROUTES,\n          },\n        });\n        await nestedQueryBuilderRepo.deleteMany({\n          find: {\n            referenceId: filter.find._id,\n            referenceType: TYPES.ROUTES,\n          },\n        });\n        await projectRouteRepo.deleteMany(filter);\n      } else {\n        // `Soft-delete` query-builder data.\n        const updateQueryBuilderData = {\n          filter: {\n            find: {\n              referenceId: filter.find._id,\n              referenceType: TYPES.ROUTES,\n            },\n          },\n          data: { isDeleted: true },\n        };\n        await queryBuilderRepo.updateMany(updateQueryBuilderData);\n        // `Soft-delete` nested-query-builder data.\n        const updateNestedQueryBuilderData = {\n          filter: {\n            find: {\n              referenceId: filter.find._id,\n              referenceType: TYPES.ROUTES,\n            },\n          },\n          data: { isDeleted: true },\n        };\n        await nestedQueryBuilderRepo.updateMany(updateNestedQueryBuilderData);\n        // `Soft-delete` project-route.\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await projectRouteRepo.updateMany(updateData);\n      }\n      projectApplicationUpdate({\n        params: {\n          applicationId: response?.[0]?.applicationId,\n          projectId: application?.projectId,\n        },\n      });\n    }\n\n    let responseMsg = OK;\n    responseMsg = ROUTE_DELETED;\n\n    return {\n      ...responseMsg,\n      data: null,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/insertMany.js",
    "content": "/* global MESSAGE, */\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\nconst { projectRouteInsertManyValidation } = require('../util/validation/projectRoute');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectRouteRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = projectRouteInsertManyValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    const created = await projectRouteRepo.insertMany(params.routes);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    return {\n      ...OK,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/paginate.js",
    "content": "/* global  _ */\nconst mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\nconst { TYPES } = require('../../constants/queryBuilder');\nconst QueryBuilderRepository = require('../../repo/queryBuilder');\nconst SchemaDetailRepository = require('../../repo/schemaDetail');\nconst NestedQueryBuilderRepository = require('../../repo/nestedQueryBuilder');\n\nconst QueryBuilderRepo = new QueryBuilderRepository();\nconst schemaDetailRepo = new SchemaDetailRepository();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepository();\n\n/**\n * Function used to get query-builder data.\n * @param  {} {listData\n * @param  {} applicationId\n * @param  {} projectRouteIds\n * @param  {} }\n */\nasync function getQueryBuilderDetails ({\n  listData, applicationId, projectRouteIds,\n}) {\n  const queryInput = {\n    find: {\n      applicationId,\n      referenceId: projectRouteIds,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let queryBuilderData = await QueryBuilderRepo.getDetails(queryInput);\n  if (queryBuilderData && _.size(queryBuilderData) > 0) {\n    queryBuilderData = _.map(queryBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    queryBuilderData = _.cloneDeep(_.groupBy(queryBuilderData, 'referenceId'));\n    _.each(listData, (val) => {\n      val.queryBuilder = queryBuilderData[val._id];\n    });\n  }\n  return listData;\n}\n\n/**\n * Function used to get nested-query-builder-data.\n * @param  {} {listData\n * @param  {} applicationId\n * @param  {} projectRouteIds\n * @param  {} }\n */\nasync function getNestedQueryBuilderDetails ({\n  listData, applicationId, projectRouteIds,\n}) {\n  const queryInput = {\n    find: {\n      applicationId,\n      referenceId: projectRouteIds,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let nqBuilderData = await nestedQueryBuilderRepo.getDetails(queryInput);\n  if (nqBuilderData && _.size(nqBuilderData) > 0) {\n    nqBuilderData = _.map(nqBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    nqBuilderData = _.cloneDeep(_.groupBy(nqBuilderData, 'referenceId'));\n    _.each(listData, (val) => {\n      val.nestedQueryBuilder = nqBuilderData[val._id];\n    });\n  }\n  return listData;\n}\n\nconst paginate = (projectRouteRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    if (!params.find) {\n      params.find = {};\n    }\n    params.find.applicationId = params.applicationId;\n    const filter = params;\n    let list = await projectRouteRepo.getDetails(filter);\n\n    if (list && _.size(list) > 0) {\n      const projectRouteIds = _.map(list, '_id');\n      // Get query-builder details.\n      list = await getQueryBuilderDetails({\n        listData: list,\n        applicationId: params.applicationId,\n        projectRouteIds,\n      });\n\n      // Get nested-query-builder details.\n      list = await getNestedQueryBuilderDetails({\n        listData: list,\n        applicationId: params.applicationId,\n        projectRouteIds,\n      });\n\n      // Get schemaDetails data.\n      const modelsIds = _.map(list, 'modelId');\n      const schemaDetailsData = await schemaDetailRepo.getDetails({ find: { schemaId: modelsIds } });\n      if (schemaDetailsData && schemaDetailsData.length > 0) {\n        _.map(list, (route) => {\n          const scDetails = _.find(schemaDetailsData, { schemaId: route.modelId });\n          if (scDetails) {\n            route.permissionData = _.pick(scDetails, ['_id', 'schemaJson', 'additionalJson']);\n          }\n        });\n      }\n    }\n\n    list = _.cloneDeep(_.orderBy(list, ['createdAt'], ['desc']));\n    const response = {\n      list,\n      count: await projectRouteRepo.getCount(filter),\n    };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/requestApi.js",
    "content": "/* global MESSAGE */\nconst axios = require('axios');\nconst { projectRouteRequestApiValidation } = require('../util/validation/projectRoute');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst requestApi = () => async ({ params }) => {\n  try {\n    // Validate Request\n    const {\n      value, error,\n    } = projectRouteRequestApiValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const {\n      method, url,\n    } = params;\n    const headers = params?.headers;\n    const data = params?.body;\n\n    const options = {\n      method,\n      url,\n      data,\n      headers,\n    };\n    const response = await axios(options);\n\n    return {\n      ...MESSAGE.OK,\n      data: response?.data,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n\n    let message = 'Could not get any response. Ensure that the backend is working properly.';\n    if (err?.code === 'ENOTFOUND') {\n      message = 'Can not send requests to given address. Make sure address is publicly accessible.';\n    } else if (err?.code === 'ECONNABORTED') {\n      message = 'Could not get any response. Ensure that the backend is working properly.';\n    } else if (err?.code === 'ECONNREFUSED') {\n      if (err?.config?.url?.includes('http://localhost', 0) || err?.config?.url?.includes('https://localhost', 0)) {\n        message = 'Unable to access your localhost.';\n      } else if (/(\\b25[0-5]|\\b2[0-4][0-9]|\\b[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/.test(err?.address)) {\n        message = 'Unable to access IP address.';\n      }\n    } else if (err?.config?.url?.includes('http://localhost', 0) || err?.config?.url?.includes('https://localhost', 0)) {\n      message = 'Unable to access your localhost.';\n    } else {\n      return {\n        ...MESSAGE.OK,\n        data: err?.response?.data,\n      };\n    }\n\n    return {\n      ...MESSAGE.BAD_REQUEST,\n      message,\n    };\n  }\n};\n\nmodule.exports = requestApi;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/update.js",
    "content": "/* global MESSAGE,_ */\nconst mongoose = require('mongoose');\nconst { PROJECT_DEFINITION_CODE } = require('../../models/constants/projectDefinition');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, PROJECT_ROUTE_NOT_FOUND, ROUTE_UPDATED, SAME_ROUTES_EXISTS,\n} = require('../../constants/message').message;\n\nconst QueryBuilderRepo = require('../../repo/queryBuilder');\nconst NestedQueryBuilderRepository = require('../../repo/nestedQueryBuilder');\nconst SchemaDetailRepository = require('../../repo/schemaDetail');\n\nconst queryBuilderRepo = new QueryBuilderRepo();\nconst schemaDetailRepo = new SchemaDetailRepository();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepository();\n\nconst queryBuilderUseCase = require('../queryBuilder/insertMany');\nconst queryBuilderDeleteDependencyUseCase = require('../queryBuilder/deleteDependency');\n\nconst nestedQueryBuilderUseCase = require('../nestedQueryBuilder/insertMany');\nconst nestedQueryBuilderDeleteDependencyUseCase = require('../nestedQueryBuilder/deleteDependency');\n\nconst { TYPES } = require('../../constants/queryBuilder');\nconst { projectRouteUpdateValidation } = require('../util/validation/projectRoute');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\n/**\n * Function used to create, delete and retrieve Query-builder.\n * @param  {} {applicationRepo\n * @param  {} params\n * @param  {} routeData\n * @param  {} }\n */\nasync function queryBuilderOperations ({\n  applicationRepo, params, routeData,\n}) {\n  // Delete and create query-builder details.\n  if (params.applicationId) {\n    const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n  }\n  if (params && params.queryBuilder && _.size(params.queryBuilder) > 0) {\n    _.each(params.queryBuilder, (val) => {\n      if (val && val.filter) {\n        val.filter = _.cloneDeep(JSON.stringify(val.filter));\n      }\n\n      val.applicationId = params.applicationId;\n      val.referenceId = routeData._id;\n      val.referenceType = TYPES.ROUTES;\n      delete val._id;\n    });\n\n    // Delete old query-builder data.\n    const deleteInput = {\n      find: {\n        applicationId: params.applicationId,\n        referenceId: routeData._id,\n        referenceType: TYPES.ROUTES,\n      },\n    };\n    const deleteQueryBuilderData = await queryBuilderDeleteDependencyUseCase(queryBuilderRepo, applicationRepo)(deleteInput, true);\n    if (!deleteQueryBuilderData.code || deleteQueryBuilderData.code !== OK.code) {\n      return deleteQueryBuilderData;\n    }\n    // InsertMany query-builder.\n    const queryBuilderData = await queryBuilderUseCase(queryBuilderRepo)(params.queryBuilder);\n    if (!queryBuilderData.code || queryBuilderData.code !== OK.code) {\n      return queryBuilderData;\n    }\n  }\n\n  // Retrieved query-builder data.\n  let queryBuilder = [];\n  const qBuilderInput = {\n    find: {\n      applicationId: params.applicationId,\n      referenceId: routeData._id,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let qBuilderData = await queryBuilderRepo.getDetails(qBuilderInput);\n  if (qBuilderData && _.size(qBuilderData) > 0) {\n    qBuilderData = _.map(qBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    queryBuilder = qBuilderData;\n  }\n\n  return {\n    ...OK,\n    data: queryBuilder,\n  };\n}\n\n/**\n * Function used to delete, create, and retrieved Nested-query-builder.\n * @param  {} {applicationRepo\n * @param  {} params\n * @param  {} routeData\n * @param  {} }\n */\nasync function nestedQueryBuilderOperations ({\n  applicationRepo, params, routeData,\n}) {\n  // Delete and create query-builder details.\n  if (params && params.nestedQueryBuilder && _.size(params.nestedQueryBuilder) > 0) {\n    _.each(params.nestedQueryBuilder, (val) => {\n      if (val && val.filter) {\n        val.filter = _.cloneDeep(JSON.stringify(val.filter));\n      }\n\n      val.applicationId = params.applicationId;\n      val.referenceId = routeData._id;\n      val.referenceType = TYPES.ROUTES;\n      delete val._id;\n    });\n\n    // Delete old query-builder data.\n    const deleteInput = {\n      find: {\n        applicationId: params.applicationId,\n        referenceId: routeData._id,\n        referenceType: TYPES.ROUTES,\n      },\n    };\n    const deleteNqBuilderData = await nestedQueryBuilderDeleteDependencyUseCase(nestedQueryBuilderRepo, applicationRepo)(deleteInput, true);\n    if (deleteNqBuilderData.code !== OK.code) {\n      return deleteNqBuilderData;\n    }\n    // InsertMany query-builder.\n    const nqBuilderData = await nestedQueryBuilderUseCase(nestedQueryBuilderRepo)(params.nestedQueryBuilder);\n    if (nqBuilderData.code !== OK.code) {\n      return nqBuilderData;\n    }\n  }\n\n  // Retrieved query-builder data.\n  let nestedQueryBuilder = [];\n  const qBuilderInput = {\n    find: {\n      applicationId: params.applicationId,\n      referenceId: routeData._id,\n      referenceType: TYPES.ROUTES,\n    },\n  };\n  let qBuilderData = await nestedQueryBuilderRepo.getDetails(qBuilderInput);\n  if (qBuilderData && _.size(qBuilderData) > 0) {\n    qBuilderData = _.map(qBuilderData, (val) => {\n      val = _.omit(val, ['createdAt', 'updatedAt', 'addedBy', 'updatedBy', 'isActive', 'isDeleted']);\n      return val;\n    });\n    nestedQueryBuilder = _.cloneDeep(qBuilderData);\n  }\n  return {\n    ...OK,\n    data: nestedQueryBuilder,\n  };\n}\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (projectRouteRepo, applicationRepo) => async (id, params) => {\n  try {\n    let isNodeApp = false;\n    if (params?.definitionType && params.definitionType === PROJECT_DEFINITION_CODE.NODE_EXPRESS) {\n      isNodeApp = true;\n    }\n\n    const {\n      value, error,\n    } = projectRouteUpdateValidation(params, isNodeApp);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const filter = { find: { _id: id } };\n    const project = await projectRouteRepo.get({ filter });\n\n    if (!project) {\n      return PROJECT_ROUTE_NOT_FOUND;\n    }\n\n    if (params?.controller) {\n      params.controller = _.capitalize(params.controller);\n    }\n\n    const checkFilter = {\n      or: [{ route: params.route }],\n      ne: [{ _id: id }],\n      find: { applicationId: params.applicationId },\n    };\n    if (params?.controller && params?.action) {\n      checkFilter.or.push({\n        action: params.action,\n        controller: params.controller,\n      });\n    }\n    const checkProjectRoute = await projectRouteRepo.get({ filter: checkFilter });\n\n    // Validate Unique Criteria\n    if (checkProjectRoute) {\n      return SAME_ROUTES_EXISTS;\n    }\n\n    if (!params.modelId) {\n      params.groupName = null;\n    }\n\n    const updateResponse = await projectRouteRepo.update(id, params);\n\n    const response = updateResponse.toObject();\n\n    // Update Query-builder data.\n    const qBuilderData = await queryBuilderOperations({\n      applicationRepo,\n      params,\n      routeData: response,\n    });\n    if (qBuilderData.code !== OK.code) {\n      return qBuilderData;\n    }\n    const queryBuilder = _.cloneDeep(qBuilderData.data);\n\n    response.queryBuilder = queryBuilder;\n\n    // Update nested-query-builder.\n    const nqBuilder = await nestedQueryBuilderOperations({\n      applicationRepo,\n      params,\n      routeData: response,\n    });\n    if (nqBuilder.code !== OK.code) {\n      return nqBuilder;\n    }\n    response.nestedQueryBuilder = _.cloneDeep(nqBuilder.data);\n\n    // Update schemaDetails data.\n    if (params?.permissionData?._id) {\n      const schemaDetail = await schemaDetailRepo.get({ find: { _id: params.permissionData._id } });\n      if (schemaDetail) {\n        delete params.permissionData._id;\n        const schemaDetails = await schemaDetailRepo.update(schemaDetail._id, params.permissionData);\n        response.permissionData = _.pick(schemaDetails.toObject(), ['_id', 'schemaJson', 'additionalJson']);\n      }\n    }\n\n    projectApplicationUpdate({\n      params: { applicationId: params.applicationId },\n      isProjectId: true,\n    });\n\n    let responseMsg = OK;\n    responseMsg = ROUTE_UPDATED;\n\n    return {\n      ...responseMsg,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/projectRoute/uploadPostmanFile.js",
    "content": "/* global MESSAGE,_ */\n// const validate = require('validate.js');\nconst formidable = require('formidable');\nconst mongoose = require('mongoose');\nconst path = require('path');\nconst fs = require('fs');\nconst { ROUTE_GENERATE_TYPE } = require('../../models/constants/project');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, INVALID_JSON, EMPTY_JSON_FILE, POSTMAN_UPLOADED,\n} = require('../../constants/message').message;\nconst { applicationIdValidation } = require('../util/validation/applicationId');\n/**\n *\n * Function used for validate request.\n * @description ::  Find Documentation @ http://validatejs.org/\n * @return mixed :: If error occurred then return array of errors else return undefined | null\n */\n/*\n * async function validateData(data) {\n *   const constraints = {\n *     applicationId: {\n *       type: 'string',\n *       presence: true,\n *     },\n *   };\n */\n\n//   const errors = validate(data, constraints);\n\n/*\n *   if (errors) {\n *     return errors;\n *   }\n *   return null;\n * }\n */\n\n/**\n *\n * Function used to check `string` is valid `JSON` or not.\n * @param  {} str\n */\nasync function isJson (str) {\n  try {\n    JSON.parse(str);\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Function used to get request body and fileData.\n * @param  {} req\n */\nasync function getBodyAndFileData (req) {\n  const form = new formidable.IncomingForm();\n  form.multiples = true;\n  const getFilesData = await new Promise((resolve) => {\n    form.parse(req, async (err, fields, files) => {\n      if (err) {\n        const errObj = {\n          code: SERVER_ERROR.code,\n          message: SERVER_ERROR.message,\n          data: err,\n        };\n        resolve(errObj);\n      } else if (_.isEmpty(files)) {\n        const errObj = {\n          code: INVALID_REQUEST_PARAMS.code,\n          message: INVALID_REQUEST_PARAMS.message,\n        };\n        resolve(errObj);\n      } else if (path.extname(files.file.name).split('.')[1] !== 'json' || files.file.type !== 'application/json') {\n        const errObj = {\n          code: INVALID_JSON.code,\n          message: INVALID_JSON.message,\n        };\n        resolve(errObj);\n      } else {\n        // Read file and validate JSON format in file.\n        const rawData = fs.readFileSync(files.file.path);\n        const checkJson = await isJson(rawData.toString());\n        if (!checkJson) {\n          const errObj = {\n            code: INVALID_JSON.code,\n            message: INVALID_JSON.message,\n          };\n          resolve(errObj);\n        } else {\n          const fileDetails = JSON.parse(rawData.toString());\n\n          const succObj = {\n            code: OK.code,\n            message: OK.message,\n            data: {\n              fileData: fileDetails,\n              params: fields,\n            },\n          };\n          resolve(succObj);\n        }\n      }\n    });\n  });\n\n  return getFilesData;\n}\n\n/**\n * Function used to prepared route array.\n *\n * @param  {} postmanData\n * @param  {} rJsonData=[]\n */\nasync function prepareRouteJsonFromPostmanFile (postmanData, rJsonData = []) {\n  if (postmanData.item) {\n    const jData = await Promise.all(postmanData.item.map(async (data) => {\n      if (data.item) {\n        await prepareRouteJsonFromPostmanFile(data, rJsonData);\n      }\n      return data;\n    }));\n    if (jData && _.size(jData)) {\n      _.each(jData, (val) => {\n        if (val && !val.item) {\n          rJsonData.push(val);\n        }\n      });\n    }\n  }\n  return rJsonData;\n}\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (projectRouteRepo, applicationRepo) => async (req) => {\n  try {\n    const postmanFileData = await getBodyAndFileData(req);\n    if (postmanFileData.code !== OK.code) {\n      return postmanFileData;\n    }\n\n    let { params } = postmanFileData.data;\n\n    const { fileData } = postmanFileData.data;\n\n    // Validate Request\n    const {\n      value, error,\n    } = applicationIdValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    params = value;\n    const applicationData = await getApplicationDetail(applicationRepo)({ applicationId: params.applicationId });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    // Prepared single array of routes, from Tree strucutred.\n    const preparedJson = await prepareRouteJsonFromPostmanFile(fileData, []);\n    if (!preparedJson || _.size(preparedJson) <= 0) {\n      return EMPTY_JSON_FILE;\n    }\n    let routeErrors = [];\n\n    let routeSuccess = await Promise.all(preparedJson.map(async (route) => {\n      let routeUrl = '';\n      if (typeof route.request.url === 'string') {\n        routeUrl = _.cloneDeep(route.request.url);\n      } else if (route?.request?.url?.raw) {\n        routeUrl = _.cloneDeep(route.request.url.raw);\n      }\n\n      // Validate Unique Criteria\n      const filter = {\n        find: {\n          route: routeUrl,\n          isActive: { $in: [true, false] },\n          applicationId: params.applicationId,\n        },\n      };\n      const checkRoute = await projectRouteRepo.get({ filter });\n\n      let created = {};\n      if (!checkRoute) {\n        // Prepare `Headers`.\n        const headers = [];\n        if (route?.request?.header) {\n          _.map(route.request.header, (header) => {\n            headers.push({\n              key: header.key,\n              value: header.value,\n            });\n          });\n        }\n\n        // Prepare `Params`.\n        const queryParams = [];\n        if (route?.request?.url?.query) {\n          _.map(route.request.url.query, (q) => {\n            queryParams.push({\n              key: q.key,\n              value: q.value,\n            });\n          });\n        }\n\n        const requestBodyErr = [];\n        if (route?.request?.body?.raw) {\n          if (!await isJson(route.request.body.raw)) {\n            requestBodyErr.push({\n              route: routeUrl,\n              sequence: 1,\n              msg: 'Invalid JSON format of request body.',\n            });\n          }\n        }\n        if (!route?.request?.method) {\n          requestBodyErr.push({\n            route: routeUrl,\n            sequence: 1,\n            msg: 'Method property not found.',\n          });\n        }\n\n        if (requestBodyErr && _.size(requestBodyErr) > 0) {\n          routeErrors = [...routeErrors, ...requestBodyErr];\n        } else {\n          const routeObj = {\n            applicationId: params.applicationId,\n            method: route.request.method.toLowerCase(),\n            route: routeUrl,\n            headers,\n            type: ROUTE_GENERATE_TYPE.MANUAL,\n            params: queryParams,\n          };\n\n          if (route?.request?.body?.raw) {\n            routeObj.request = JSON.parse(route.request.body.raw);\n          }\n\n          created = await projectRouteRepo.create(routeObj);\n        }\n      } else {\n        routeErrors.push({\n          route: routeUrl,\n          sequence: 2,\n          msg: 'API already exists.',\n        });\n      }\n\n      return created;\n    }));\n    routeSuccess = _.cloneDeep(_.reject(routeSuccess, _.isEmpty));\n    routeErrors = _.cloneDeep((_.sortBy(routeErrors, 'sequence')));\n\n    let responseMsg = OK;\n    responseMsg = POSTMAN_UPLOADED;\n\n    return {\n      ...responseMsg,\n      data: {\n        error: routeErrors,\n        success: routeSuccess,\n      },\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/queryBuilder/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteDependencyUseCase = require('./deleteDependency');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (queryBuilderRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteDependencyUseCase(queryBuilderRepo, applicationRepo))({ find: { _id: params.id } }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/queryBuilder/deleteDependency.js",
    "content": "/* global _ */\n\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteMany = (queryBuilderRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await queryBuilderRepo.getDetails(filter);\n    if (response && _.size(response) > 0) {\n      if (response && response.length) {\n        if (isHardDelete) {\n          await queryBuilderRepo.deleteMany(filter);\n        } else {\n          const updateData = {\n            filter,\n            data: { isDeleted: true },\n          };\n          await queryBuilderRepo.updateMany(updateData);\n        }\n      }\n    }\n    return {\n      ...OK,\n      data: null,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/queryBuilder/insertMany.js",
    "content": "/* global  _ */\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (queryBuilderRepo) => async (params) => {\n  try {\n    params = _.cloneDeep(_.map(params, (val) => val));\n    const created = await queryBuilderRepo.insertMany(params);\n\n    if (!created) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    return {\n      ...OK,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/schema/InsertDefaultModels/insertDefaultModels.js",
    "content": "/* global MESSAGE,_ */\nconst { PROJECT_DEFINITION_CODE } = require('../../../models/constants/projectDefinition');\nconst {\n  DATABASE_TYPE, ORM_TYPE,\n} = require('../../../models/constants/applicationConfig');\n\nconst { validateProperties } = require('../util');\nconst { getApplicationDetail } = require('../../util/getApplicationData');\nconst { VALIDATION_MESSAGES } = require('../../../constants/schema');\nconst {\n  mySqlDataTypes, sqlDataTypes, postGreSqlDataTypes,\n} = require('../../../constants/dataTypes/sequelize');\nconst validateSequelizeDataTypes = require('../util/sequelize/validateDataTypes');\n\nconst SchemaDetailRepo = require('../../../repo/schemaDetail');\nconst ProjectRouteRepo = require('../../../repo/projectRoute');\nconst routeInsertManyUseCase = require('../../projectRoute/insertMany');\nconst getPermissionWiseRoute = require('../../util/getPermissionWiseRoute');\nconst {\n  getDefaultFieldsForMongoDB, schemaJsonOptions, getAdditionalJsonWithoutAuthOptions, schemaJsonAuthPlatform,\n  schemaJsonAuthOptions, getAdditionalJsonAuthOptions, getAdditionalJsonAuthPlatform, getDefaultFieldsForSequelize, reOrderSchemaJson,\n} = require('../util/staticData');\n\nconst SchemaDetail = new SchemaDetailRepo();\nconst projectRouteRepo = new ProjectRouteRepo();\n\nconst {\n  SERVER_ERROR, DEFAULT_MODELS_INSERTED,\n} = require('../../../constants/message').message;\nconst { defaultInsertModels } = require('../../util/validation/defaultInsertModels');\n\n/**\n * Function used to add default fields, if not exists.\n * @param  {} jsonSchemaData\n */\nasync function addDefaultFields (jsonSchemaData, ormType) {\n  let defaultFields = {};\n\n  if (ormType === ORM_TYPE.MONGOOSE) {\n    defaultFields = await getDefaultFieldsForMongoDB();\n  } else if (ormType && _.includes([ORM_TYPE.SEQUELIZE, ORM_TYPE.ELOQUENT], ormType)) {\n    defaultFields = await getDefaultFieldsForSequelize({ ormType });\n  }\n  _.each(jsonSchemaData, (json) => {\n    const lowerSchemaJsonKeys = Object.keys(json.schemaJson).map((key) => key.toLowerCase());\n    Object.keys(defaultFields).forEach((field) => {\n      if (!_.includes(lowerSchemaJsonKeys, field.toLowerCase())) {\n        json.schemaJson[field] = defaultFields[field];\n      }\n    });\n  });\n\n  return jsonSchemaData;\n}\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (schemaRepo, applicationRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = defaultInsertModels(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = _.cloneDeep(value);\n\n    // Validate application.\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['name', 'configInput', 'isArchive', 'definitionId', 'stepInput'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n    const applicationDetails = _.cloneDeep(applicationData?.data);\n\n    let ormType = ORM_TYPE.MONGOOSE;\n    let databaseType = DATABASE_TYPE.MONGODB;\n\n    if (applicationDetails?.stepInput?.ormType) {\n      ormType = applicationDetails.stepInput.ormType;\n    }\n\n    if (applicationDetails?.stepInput?.databaseType) {\n      databaseType = applicationDetails.stepInput.databaseType;\n    }\n\n    // Read file and validate JSON format in file.\n    const schemaErrors = [];\n    let modelValidateErrors = [];\n\n    let modelsData = _.cloneDeep(params.models);\n\n    // Add default fields.\n    modelsData = await addDefaultFields(modelsData, ormType);\n\n    if (ormType === ORM_TYPE.MONGOOSE) {\n      modelsData = modelsData.map((json) => {\n        Object.keys(json.schemaJson).forEach((key) => {\n          if (json.schemaJson[key].type && json.schemaJson[key].description && json.schemaJson[key].type.toUpperCase() === 'JSON') {\n            json.schemaJson[key] = _.cloneDeep(json.schemaJson[key].description);\n          } else if (json.schemaJson[key].type && json.schemaJson[key].description && _.isArray(json.schemaJson[key].description) && json.schemaJson[key].type.toUpperCase() === 'ARRAY') {\n            json.schemaJson[key] = [_.cloneDeep(json.schemaJson[key].description[0])];\n          }\n        });\n        return json;\n      });\n\n      const validateProps = await validateProperties(_.cloneDeep(modelsData));\n      if (validateProps && (validateProps.errors && _.size(validateProps.errors) > 0)) {\n        modelValidateErrors = _.cloneDeep(validateProps.errors);\n      }\n\n      if (validateProps?.originJson) {\n        modelsData = _.cloneDeep(validateProps.originJson);\n      }\n    } else if (ormType && _.includes([ORM_TYPE.SEQUELIZE, ORM_TYPE.ELOQUENT], ormType)) {\n      let validDataTypes = {};\n      if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.SQL) {\n        validDataTypes = sqlDataTypes.DATA_TYPES;\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.MYSQL) {\n        validDataTypes = mySqlDataTypes.DATA_TYPES;\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.POSTGRE_SQL) {\n        validDataTypes = postGreSqlDataTypes.DATA_TYPES;\n      }\n\n      for (let i = 0; i < modelsData.length; i += 1) {\n        const model = modelsData[i];\n\n        let propErrors = [];\n        // eslint-disable-next-line no-await-in-loop\n        propErrors = await validateSequelizeDataTypes({\n          model,\n          dataTypes: validDataTypes,\n        });\n        modelValidateErrors = [...modelValidateErrors, ...propErrors.errors];\n      }\n    }\n\n    modelValidateErrors = _.flattenDeep(modelValidateErrors);\n\n    // Check model already exists.\n    const modelNames = _.map(modelsData, 'modelName');\n    const schemaExists = await schemaRepo.getDetails({\n      find: { applicationId: params.applicationId },\n      multipleSearch: {\n        keywords: modelNames,\n        keys: ['name'],\n      },\n    });\n\n    let schemaList = await Promise.all(modelsData.map(async (schema) => {\n      // Check schema already exists of same name.\n      let checkSchemaExists = {};\n      if (schemaExists && _.size(schemaExists) > 0) {\n        checkSchemaExists = _.reject(_.map(schemaExists, (schemaVal) => {\n          if (schemaVal.name.toUpperCase() === schema.modelName.toUpperCase()) {\n            return schemaVal;\n          }\n          return {};\n        }), _.isEmpty);\n\n        if (!_.isEmpty(checkSchemaExists)) {\n          schemaErrors.push({\n            modelName: schema.modelName,\n            isExists: true,\n            schemaId: checkSchemaExists[0]._id,\n            schemaJson: schema.schemaJson,\n            error: [VALIDATION_MESSAGES.SCHEMA_ALREADY_EXISTS],\n          });\n        }\n      }\n\n      // Check model attribute(s) has errors.\n      let modelAttrError = {};\n      if (modelValidateErrors && modelValidateErrors.length > 0) {\n        modelAttrError = _.find(modelValidateErrors, { modelName: schema.modelName });\n      }\n\n      let created = {};\n      if (_.isEmpty(checkSchemaExists) && _.isEmpty(modelAttrError)) {\n        const schemaData = {\n\n          name: schema.modelName,\n          applicationId: params.applicationId,\n          description: schema.description,\n          schemaJson: schema.schemaJson,\n        };\n        if (schema?.modelIndexes) {\n          schemaData.modelIndexes = schema.modelIndexes;\n        }\n        if (schema?.hooks) {\n          schemaData.hooks = schema.hooks;\n        }\n\n        if (schemaData?.schemaJson && !_.isEmpty(schemaData.schemaJson)) {\n          schemaData.schemaJson = await reOrderSchemaJson(_.cloneDeep(schemaData.schemaJson));\n        }\n        created = await schemaRepo.create(schemaData);\n\n        let schemaJson = {};\n        const additionalSetting = {};\n        // add schema detail according to accessible platform.\n        if (applicationDetails?.configInput?.loginAccess && applicationDetails?.configInput?.platform) {\n          const customPlatform = applicationDetails.configInput.platform;\n          let uniqPlatform = [];\n          _.each(applicationDetails.configInput.loginAccess, (v) => {\n            uniqPlatform = uniqPlatform.concat(v);\n          });\n          uniqPlatform = _.uniq(uniqPlatform);\n          if (customPlatform && _.size(customPlatform)) {\n            _.each(customPlatform, (data) => {\n              let schemaJsonOpt = [];\n              let additionalSettingOpt = [];\n\n              if (_.includes(uniqPlatform, data)) {\n                schemaJsonOpt = schemaJsonAuthOptions();\n                additionalSettingOpt = getAdditionalJsonAuthOptions();\n              } else {\n                schemaJsonOpt = schemaJsonOptions();\n                additionalSettingOpt = getAdditionalJsonWithoutAuthOptions();\n              }\n\n              schemaJson[data] = schemaJsonOpt;\n              additionalSetting[data] = additionalSettingOpt;\n            });\n          }\n        }\n\n        if (schemaJson && !_.size(schemaJson)) {\n          schemaJson = schemaJsonAuthPlatform();\n        }\n\n        let additionalJson = {};\n        if (additionalSetting && !_.isEmpty(additionalSetting)) {\n          additionalJson = { additionalSetting };\n        } else if (!additionalSetting || _.isEmpty(additionalSetting)) {\n          additionalJson = getAdditionalJsonAuthPlatform();\n        }\n        const detail = {\n          schemaId: created._id,\n          schemaJson,\n          additionalJson,\n        };\n\n        const schemaDetails = await SchemaDetail.create(detail);\n        const allRouts = getPermissionWiseRoute(schemaDetails.schemaJson, created, PROJECT_DEFINITION_CODE.NODE_EXPRESS);\n        await (routeInsertManyUseCase(projectRouteRepo))({ routes: allRouts });\n      }\n      return created;\n    }));\n    schemaList = _.reject(schemaList, _.isEmpty);\n    return {\n      ...DEFAULT_MODELS_INSERTED,\n      data: {\n        error: modelValidateErrors,\n        success: schemaList,\n        existsModels: _.compact(_.flattenDeep(schemaErrors)),\n      },\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/schema/create.js",
    "content": "/* global MESSAGE,_ */\nconst mongoose = require('mongoose');\n\nconst {\n  ORM_TYPE, DATABASE_TYPE,\n} = require('../../models/constants/applicationConfig');\nconst { PROJECT_DEFINITION_CODE } = require('../../models/constants/projectDefinition');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\nconst { getApplicationDetail } = require('../util/getApplicationData');\n\nconst SchemaDetailRepo = require('../../repo/schemaDetail');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\nconst routeInsertManyUseCase = require('../projectRoute/insertMany');\nconst getPermissionWiseRoute = require('../util/getPermissionWiseRoute');\n\nconst validateSequelizeDataTypes = require('./util/sequelize/validateDataTypes');\nconst {\n  mySqlDataTypes, sqlDataTypes, postGreSqlDataTypes,\n} = require('../../constants/dataTypes/sequelize');\nconst {\n  schemaJsonAuthOptions, getAdditionalJsonAuthOptions,\n  schemaJsonOptions, getAdditionalJsonWithoutAuthOptions, schemaJsonAuthPlatform, schemaJsonWithoutAuthPlatform, getAdditionalJsonAuthPlatform,\n} = require('./util/staticData');\n\nconst SchemaDetail = new SchemaDetailRepo();\nconst projectRouteRepo = new ProjectRouteRepo();\n\nconst {\n  FAILED_TO_CREATE, OK, SERVER_ERROR, INVALID_REQUEST_PARAMS, RECORD_WITH_SAME_NAME_EXISTS, INVALID_SCHEMA_ATTR, MODEL_CREATED,\n} = require('../../constants/message').message;\nconst { schemaCreateValidation } = require('../util/validation/schema');\nconst { validateRegEx } = require('./util');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (schemaRepo, applicationRepo) => async (params) => {\n  try {\n    // Validate Request\n    const {\n      value, error,\n    } = schemaCreateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['configInput', 'definitionId', 'stepInput', 'projectId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const existingProject = applicationData?.data;\n    // Check schema already exists.\n    const schemaData = await schemaRepo.get({\n      find: { applicationId: params.applicationId },\n      search: {\n        keyword: params.name,\n        keys: ['name'],\n      },\n    });\n    if (schemaData && schemaData.name.toUpperCase() === params.name.toUpperCase()) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    let dataTypeValidateErr = [];\n\n    // Validate sequelize dataTypes.\n    if (existingProject?.stepInput?.ormType && existingProject?.stepInput?.databaseType\n      && _.includes([ORM_TYPE.SEQUELIZE, ORM_TYPE.ELOQUENT], existingProject.stepInput.ormType) && params?.schemaJson) {\n      const {\n        databaseType, ormType,\n      } = existingProject.stepInput;\n      if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.SQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: sqlDataTypes.DATA_TYPES,\n        });\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.MYSQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: mySqlDataTypes.DATA_TYPES,\n        });\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.POSTGRE_SQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: postGreSqlDataTypes.DATA_TYPES,\n        });\n      }\n    } else {\n      // Validate `RegExp` pattern.\n      // eslint-disable-next-line no-lonely-if\n      if (params?.schemaJson) {\n        const validateRegExp = await validateRegEx(params.schemaJson);\n        if (validateRegExp.code !== OK.code) {\n          return validateRegExp;\n        }\n      }\n    }\n    if (dataTypeValidateErr.errors && dataTypeValidateErr.errors.length) {\n      return {\n        ...INVALID_SCHEMA_ATTR,\n        data: dataTypeValidateErr.errors,\n      };\n    }\n    if (params?.schemaJson && dataTypeValidateErr?.model?.schemaJson) {\n      params.schemaJson = _.cloneDeep(dataTypeValidateErr.model.schemaJson);\n    }\n\n    const created = await schemaRepo.create(params);\n\n    if (!created) {\n      return FAILED_TO_CREATE;\n    }\n\n    let schemaJson = {};\n    const additionalSetting = {};\n    // add schema detail according to accessible platform\n    if (existingProject?.configInput?.loginAccess && existingProject?.configInput?.platform) {\n      let uniqPlatform = [];\n      _.each(existingProject.configInput.loginAccess, (v) => {\n        uniqPlatform = uniqPlatform.concat(v);\n      });\n      uniqPlatform = _.uniq(uniqPlatform);\n      const customPlatform = existingProject.configInput.platform;\n      if (customPlatform && _.size(customPlatform)) {\n        _.each(customPlatform, (data) => {\n          let schemaJsonOpt = [];\n          let additionalSettingOpt = [];\n          if (_.includes(uniqPlatform, data) && (existingProject?.stepInput?.ormType && existingProject?.stepInput?.ormType !== ORM_TYPE.ELOQUENT)) {\n            schemaJsonOpt = schemaJsonAuthOptions();\n            additionalSettingOpt = getAdditionalJsonAuthOptions();\n          } else {\n            schemaJsonOpt = schemaJsonOptions();\n            additionalSettingOpt = getAdditionalJsonWithoutAuthOptions();\n          }\n          schemaJson[data] = schemaJsonOpt;\n          additionalSetting[data] = additionalSettingOpt;\n        });\n      }\n    }\n\n    // If modelConfig key found in `params`\n    if (existingProject?.configInput?.platform && (!_.isEmpty(params.jsonInputModelConfig) || !_.isEmpty(params.jsonInputNewModelConfig))) {\n      const customPlatform = existingProject.configInput.platform;\n\n      /*\n       * let uniqPlatform = [];\n       * _.each(existingProject.configInput.loginAccess, (v) => {\n       * uniqPlatform = uniqPlatform.concat(v);\n       * });\n       * uniqPlatform = _.uniq(uniqPlatform);\n       */\n      if (customPlatform && _.size(customPlatform)) {\n        _.each(customPlatform, (data) => {\n          if (params.jsonInputModelConfig[data]) {\n            schemaJson[data] = params.jsonInputModelConfig[data];\n          } else {\n            schemaJson[data] = schemaJsonOptions();\n          }\n\n          if (params.jsonInputNewModelConfig[data]) {\n            additionalSetting[data] = params.jsonInputNewModelConfig[data];\n          } else {\n            additionalSetting[data] = getAdditionalJsonWithoutAuthOptions();\n          }\n        });\n      }\n    }\n\n    if (schemaJson && !_.size(schemaJson)) {\n      if ((existingProject?.stepInput?.ormType && existingProject?.stepInput?.ormType !== ORM_TYPE.ELOQUENT)) {\n        schemaJson = schemaJsonAuthPlatform();\n      } else {\n        schemaJson = schemaJsonWithoutAuthPlatform();\n      }\n    }\n\n    let additionalJson = {};\n    if (additionalSetting && !_.isEmpty(additionalSetting)) {\n      additionalJson = { additionalSetting };\n    } else if (!additionalSetting || _.isEmpty(additionalSetting)) {\n      if ((existingProject?.stepInput?.ormType && existingProject?.stepInput?.ormType !== ORM_TYPE.ELOQUENT)) {\n        additionalJson = await getAdditionalJsonAuthPlatform();\n      } else {\n        additionalJson = await getAdditionalJsonWithoutAuthOptions();\n      }\n    }\n\n    const detail = {\n      schemaId: created._id,\n      schemaJson,\n      additionalJson,\n    };\n\n    const schemaDetails = await SchemaDetail.create(detail);\n\n    const allRouts = getPermissionWiseRoute(schemaDetails.schemaJson, created, PROJECT_DEFINITION_CODE.NODE_EXPRESS);\n    await (routeInsertManyUseCase(projectRouteRepo))({ routes: allRouts });\n\n    projectApplicationUpdate({\n      params: {\n        projectId: existingProject?.projectId,\n        applicationId: params.applicationId,\n      },\n    });\n\n    let responseMsg = OK;\n    responseMsg = MODEL_CREATED;\n\n    return {\n      ...responseMsg,\n      data: created,\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/schema/dataTypeSuggestions.js",
    "content": "const {\n  DATA_TYPES_SUGGESTIONS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst dataTypeSuggestions = (dataTypeSuggestionsRepo) => async () => {\n  try {\n    const dataTypes = await dataTypeSuggestionsRepo.get({});\n    return {\n      ...DATA_TYPES_SUGGESTIONS,\n      data: dataTypes,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = dataTypeSuggestions;\n"
  },
  {
    "path": "packages/server/usecase/schema/delete.js",
    "content": "const mongoose = require('mongoose');\nconst deleteSchemaUseCase = require('./deleteDependency');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteById = (schemaRepo, applicationRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteSchemaUseCase(schemaRepo, applicationRepo))(params);\n    return response;\n  } catch (err) {\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/schema/deleteDependency.js",
    "content": "/* global MESSAGE */\nconst {\n  SERVER_ERROR, MODEL_DELETED, OK, APP_CONFIG_MODEL, SCHEMA_DELETE_DEPENDENCY,\n} = require('../../constants/message').message;\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst ApplicationConfigRepo = require('../../repo/applicationConfig');\n\nconst applicationConfigRepo = new ApplicationConfigRepo();\n\nconst {\n  deleteSchemaRefInfo, deleteSchemaReferences,\n} = require('./util');\n\n/**\n *Function used to update application config data.\n * @param  {} data\n */\nasync function getAuthModule (data) {\n  const { schemaId } = data;\n\n  const appConfigUpdateFilter = { find: { authModuleId: schemaId } };\n  const appConfig = await applicationConfigRepo.get(appConfigUpdateFilter);\n  return appConfig;\n}\n\n// { filter: { find: { applicationId: params.id } } }\nconst deleteMany = (schemaRepo, applicationRepo) => async (params) => {\n  try {\n    const {\n      isHardDelete, isDependencyInfo,\n    } = params;\n    const filter = { find: { _id: params.id } };\n\n    const response = await schemaRepo.getDetails(filter);\n    if (response && response.length) {\n      const applicationData = await getApplicationDetail(applicationRepo)({\n        applicationId: response?.[0]?.applicationId,\n        fields: ['projectId'],\n      });\n\n      if (applicationData?.code !== MESSAGE.OK.code) {\n        return applicationData;\n      }\n      const application = applicationData?.data;\n\n      // Check requested model, used in Application-Config.\n      const authModuleRes = await getAuthModule({ schemaId: response[0]._id });\n      if (authModuleRes) {\n        return APP_CONFIG_MODEL;\n      }\n\n      const schemaReferenceInput = {\n        delSchemaDetails: response[0],\n        isInfo: isDependencyInfo,\n      };\n\n      // Update schema dependency.\n      const delRefRes = await deleteSchemaRefInfo(schemaReferenceInput);\n      if (delRefRes?.code && delRefRes.code !== OK.code) {\n        throw new Error(delRefRes.data);\n      }\n      if (isDependencyInfo) {\n        return {\n          ...SCHEMA_DELETE_DEPENDENCY,\n          data: delRefRes.data.schemaErrors,\n        };\n      }\n\n      if (isHardDelete) {\n        await schemaRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await schemaRepo.updateMany(updateData);\n      }\n\n      // Function used to delete `schema` related references.\n      const delRef = await deleteSchemaReferences({\n        schemaData: response[0],\n        isHardDelete,\n      });\n      if (delRef?.code && delRef.code !== OK.code) {\n        return delRef;\n      }\n\n      projectApplicationUpdate({\n        params: {\n          projectId: application?.projectId,\n          applicationId: application._id,\n        },\n      });\n    }\n\n    let responseMsg = OK;\n    responseMsg = MODEL_DELETED;\n\n    return {\n      ...responseMsg,\n      data: null,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/schema/existsSchemaUpdate.js",
    "content": "/* global MESSAGE,_ */\nconst {\n  SERVER_ERROR, MODELS_UPDATED,\n} = require('../../constants/message').message;\n\nconst { validateProperties } = require('./util');\nconst { existingSchemaUpdateValidation } = require('../util/validation/schema');\n\nconst {\n  VALIDATION_MESSAGES, DEFAULT_FIELDS, DEFAULT_TABLE_NAME, DATA_TYPES,\n} = require('../../constants/schema');\nconst {\n  getDefaultFieldsForMongoDB, reOrderSchemaJson,\n} = require('./util/staticData');\nconst { PROPS } = require('../../constants/dataTypes/props');\n/**\n *\n * Function used for validate request.\n * @description ::  Find Documentation @ http://validatejs.org/\n * @return mixed :: If error occurred then return array of errors else return undefined | null\n */\n\n/*\n * async function validateData(data) {\n *   const constraints = {\n */\n\n/*\n *     applicationId: {\n *       presence: true,\n *       type: 'string',\n *     },\n *     models: {\n *       presence: true,\n *       type: 'array',\n *     },\n *   };\n */\n\n//   const errors = validate(data, constraints);\n\n/*\n *   if (errors) {\n *     return errors;\n *   }\n */\n\n/*\n *   return null;\n * }\n */\n\nconst existsSchemaUpdate = (schemaRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = existingSchemaUpdateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n\n    let modelErrors = [];\n    const success = [];\n\n    await Promise.all(params.models.map(async (model) => {\n      if (model.isUploadedFile === true) {\n        const schemaFilter = {\n          find: {\n            applicationId: params.applicationId,\n            _id: model.schemaId,\n          },\n        };\n        const schema = await schemaRepo.get(schemaFilter);\n        if (!schema) {\n          modelErrors.push({\n            modelName: model.modelName,\n            error: VALIDATION_MESSAGES.MODEL_NOT_FOUND,\n          });\n        } else {\n          const validateProps = await validateProperties([\n            {\n              modelName: model.modelName,\n              schemaJson: model.schemaJson,\n            },\n          ]);\n\n          if (validateProps && (validateProps.errors && _.size(validateProps.errors) > 0)) {\n            modelErrors.push(validateProps.errors);\n          }\n\n          if (validateProps?.originJson && _.size(validateProps.originJson) > 0) {\n            model.schemaJson = _.cloneDeep(validateProps.originJson[0].schemaJson);\n          }\n          Object.keys(model.schemaJson).forEach((key) => {\n            if (model.schemaJson[key].type && model.schemaJson[key].description && model.schemaJson[key].type.toUpperCase() === 'JSON') {\n              model.schemaJson[key] = _.cloneDeep(model.schemaJson[key].description);\n            } else if (model.schemaJson[key].type && model.schemaJson[key].description && _.isArray(model.schemaJson[key].description) && model.schemaJson[key].type.toUpperCase() === 'ARRAY') {\n              model.schemaJson[key] = [_.cloneDeep(model.schemaJson[key].description[0])];\n            }\n          });\n\n          const lowerSchemaJsonKeys = Object.keys(model.schemaJson).map((key) => key.toLowerCase());\n          const defaultFields = await getDefaultFieldsForMongoDB();\n\n          Object.keys(defaultFields).forEach((field) => {\n            if (!_.includes(lowerSchemaJsonKeys, field.toLowerCase())) {\n              model.schemaJson[field] = defaultFields[field];\n            }\n          });\n\n          _.map(Object.keys(model.schemaJson), (key) => {\n            if ((key.toLowerCase() === DEFAULT_FIELDS.ADDED_BY || key.toLowerCase() === DEFAULT_FIELDS.UPDATED_BY)) {\n              if (typeof model.schemaJson[key] === 'string' && model.schemaJson[key].toLowerCase() === DATA_TYPES.OBJECTID.value.toLowerCase()) {\n                model.schemaJson[key] = { type: model.schemaJson[key] };\n                model.schemaJson[key][PROPS.REF] = DEFAULT_TABLE_NAME;\n              } else if (model?.schemaJson[key]?.type && model?.schemaJson[key]?.type.toLowerCase() === DATA_TYPES.OBJECTID.value.toLowerCase()) {\n                if (!model.schemaJson[key][PROPS.REF]) {\n                  model.schemaJson[key][PROPS.REF] = DEFAULT_TABLE_NAME;\n                }\n              }\n            }\n          });\n\n          const updateModelInput = { schemaJson: model.schemaJson };\n          if (updateModelInput?.schemaJson && !_.isEmpty(updateModelInput.schemaJson)) {\n            updateModelInput.schemaJson = await reOrderSchemaJson(_.cloneDeep(updateModelInput.schemaJson));\n          }\n          const schemaUpdate = await schemaRepo.update(model.schemaId, updateModelInput);\n          if (schemaUpdate) {\n            success.push(schemaUpdate.toObject());\n          } else {\n            modelErrors.push({\n              modelName: model.modelName,\n              error: VALIDATION_MESSAGES.UPDATE_MODEL_ERROR,\n            });\n          }\n        }\n      }\n    }));\n\n    modelErrors = _.cloneDeep(_.flattenDeep(_.uniq(modelErrors)));\n\n    return {\n      ...MODELS_UPDATED,\n      data: {\n        error: modelErrors,\n        success,\n      },\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = existsSchemaUpdate;\n"
  },
  {
    "path": "packages/server/usecase/schema/get.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, SCHEMA_DETAIL_NOT_FOUND,\n} = require('../../constants/message').message;\n\nconst get = (schemaRepo) => async (id) => {\n  try {\n    if (!id) {\n      return INVALID_REQUEST_PARAMS;\n    }\n\n    const filter = { find: { _id: id } };\n    const schemaDetails = await schemaRepo.get(filter);\n    if (!schemaDetails) {\n      return SCHEMA_DETAIL_NOT_FOUND;\n    }\n\n    return {\n      ...OK,\n      data: schemaDetails,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = get;\n"
  },
  {
    "path": "packages/server/usecase/schema/insertMany.js",
    "content": "/* global MESSAGE,_ */\nconst mongoose = require('mongoose');\nconst fs = require('fs');\nconst formidable = require('formidable');\n\nconst { validateProperties } = require('./util');\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst { PROPS } = require('../../constants/dataTypes/props');\nconst {\n  DEFAULT_FIELDS, DEFAULT_TABLE_NAME, DATA_TYPES,\n} = require('../../constants/schema');\nconst SchemaDetailRepo = require('../../repo/schemaDetail');\nconst ProjectRouteRepo = require('../../repo/projectRoute');\nconst routeInsertManyUseCase = require('../projectRoute/insertMany');\nconst getPermissionWiseRoute = require('../util/getPermissionWiseRoute');\nconst {\n  getDefaultFieldsForMongoDB, schemaJsonOptions, getAdditionalJsonWithoutAuthOptions, schemaJsonAuthPlatform,\n  schemaJsonAuthOptions, getAdditionalJsonAuthOptions, getAdditionalJsonAuthPlatform, reOrderSchemaJson,\n} = require('./util/staticData');\n\nconst SchemaDetail = new SchemaDetailRepo();\nconst projectRouteRepo = new ProjectRouteRepo();\n\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR, MODEL_UPLOADED,\n} = require('../../constants/message').message;\nconst { applicationIdValidation } = require('../util/validation/applicationId');\n/**\n * Function used to get request body and fileData.\n * @param  {} req\n */\nasync function getBodyAndFileData (req) {\n  const form = new formidable.IncomingForm();\n  form.multiples = true;\n  const getFilesData = await new Promise((resolve, reject) => {\n    form.parse(req, async (err, fields, files) => {\n      if (err) {\n        const errObj = {\n          code: SERVER_ERROR.code,\n          message: SERVER_ERROR.message,\n          data: err,\n        };\n        reject(errObj);\n      } else if (_.isEmpty(files)) {\n        const errObj = {\n          code: INVALID_REQUEST_PARAMS.code,\n          message: INVALID_REQUEST_PARAMS.message,\n        };\n        reject(errObj);\n      } else {\n        let fileArr = [];\n        if (!Array.isArray(files.file)) {\n          fileArr.push(files.file);\n        } else {\n          fileArr = files.file;\n        }\n        const succObj = {\n          code: OK.code,\n          message: OK.message,\n          data: {\n            fileData: fileArr,\n            params: fields,\n          },\n        };\n        resolve(succObj);\n      }\n    });\n  });\n\n  return getFilesData;\n}\n\n/**\n *\n * Function used to check `string` is valid `JSON` or not.\n * @param  {} str\n */\nasync function isJson (str) {\n  try {\n    JSON.parse(str);\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Function used to add default fields, if not exists.\n * @param  {} jsonSchemaData\n */\nasync function addDefaultFields (jsonSchemaData) {\n  const defaultFields = await getDefaultFieldsForMongoDB();\n  _.each(jsonSchemaData, (json) => {\n    const lowerSchemaJsonKeys = Object.keys(json.schemaJson).map((key) => key.toLowerCase());\n    Object.keys(defaultFields).forEach((field) => {\n      if (!_.includes(lowerSchemaJsonKeys, field.toLowerCase())) {\n        json.schemaJson[field] = defaultFields[field];\n      }\n    });\n    _.map(Object.keys(json.schemaJson), (key) => {\n      if ((key.toLowerCase() === DEFAULT_FIELDS.ADDED_BY || key.toLowerCase() === DEFAULT_FIELDS.UPDATED_BY)) {\n        if (typeof json.schemaJson[key] === 'string' && json.schemaJson[key].toLowerCase() === DATA_TYPES.OBJECTID.value.toLowerCase()) {\n          json.schemaJson[key] = { type: json.schemaJson[key] };\n          json.schemaJson[key][PROPS.REF] = DEFAULT_TABLE_NAME;\n        } else if (json?.schemaJson[key]?.type && json?.schemaJson[key]?.type.toLowerCase() === DATA_TYPES.OBJECTID.value.toLowerCase()) {\n          if (!json.schemaJson[key][PROPS.REF]) {\n            json.schemaJson[key][PROPS.REF] = DEFAULT_TABLE_NAME;\n          }\n        }\n      }\n    });\n  });\n\n  return jsonSchemaData;\n}\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (schemaRepo, applicationRepo) => async (req) => {\n  try {\n    // Get request body and file-data.\n    const getBodyAndFilesData = await getBodyAndFileData(req);\n    if (getBodyAndFilesData.code !== OK.code) {\n      return getBodyAndFilesData;\n    }\n    let { params } = _.cloneDeep(getBodyAndFilesData.data);\n\n    const { fileData } = _.cloneDeep(getBodyAndFilesData.data);\n\n    const {\n      value, error,\n    } = applicationIdValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    // Validate application.\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['name', 'configInput', 'isArchive', 'definitionId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n    const existingProject = applicationData?.data;\n\n    // Read file and validate JSON format in file.\n    let fileErrors = [];\n    const jsonData = [];\n    await Promise.all(fileData.map(async (val) => {\n      const err = [];\n      const rawData = fs.readFileSync(val.path);\n      const checkJson = await isJson(rawData.toString());\n      if (!checkJson) {\n        fileErrors.push({\n          modelName: `${val.name}`,\n          isFileErr: true,\n          error: ['Invalid JSON file.'],\n        });\n      } else {\n        let jsonSchemaData = JSON.parse(rawData.toString());\n        if (!_.isArray(jsonSchemaData)) {\n          err.push({\n            modelName: `${val.name}`,\n            isFileErr: true,\n            error: ['Invalid JSON file.'],\n          });\n        }\n\n        if (_.isEmpty(jsonSchemaData)) {\n          err.push({\n            modelName: `${val.name}`,\n            isFileErr: true,\n            error: ['Empty JSON file.'],\n          });\n        }\n        if (err && _.size(err) > 0) {\n          fileErrors.push(err);\n        } else {\n          jsonSchemaData = await addDefaultFields(jsonSchemaData);\n\n          // Validate JSON data property.\n          const validateProps = await validateProperties(_.cloneDeep(jsonSchemaData));\n          if (validateProps && (validateProps.errors && _.size(validateProps.errors) > 0)) {\n            fileErrors.push(validateProps.errors);\n          }\n\n          if (validateProps?.originJson) {\n            const originJson = _.cloneDeep(validateProps.originJson);\n            jsonData.push(originJson);\n          } else {\n            jsonData.push(jsonSchemaData);\n          }\n          /*\n           * if (validateProps && (validateProps.jsonSchema && _.size(validateProps.jsonSchema) > 0)) {\n           * jsonData.push(validateProps.jsonSchema);\n           * }\n           */\n        }\n      }\n      return true;\n    }));\n\n    // Return bad-request error, If empty JSON file.\n    if (_.isEmpty(jsonData)) {\n      fileErrors = _.cloneDeep(_.flattenDeep(_.uniq(fileErrors)));\n      return {\n        ...OK,\n        data: {\n          error: fileErrors,\n          success: [],\n        },\n      };\n    }\n\n    // Prepare JSON data.\n    let jsonDetails = [];\n    _.each(jsonData, (val) => {\n      _.each(val, (v) => {\n        jsonDetails.push(v);\n      });\n    });\n    jsonDetails = _.cloneDeep(_.compact(jsonDetails));\n\n    const mJsonData = jsonDetails.map((json) => {\n      if (json?.modelName) {\n        json.modelName = json.modelName.replace(/ /g, '_');\n      }\n      Object.keys(json.schemaJson).forEach((key) => {\n        if (json.schemaJson[key][PROPS.REF]) {\n          json.schemaJson[key][PROPS.REF] = json.schemaJson[key][PROPS.REF].replace(/ /g, '_');\n        }\n\n        if (json.schemaJson[key].type && json.schemaJson[key].description && json.schemaJson[key].type.toUpperCase() === 'JSON') {\n          json.schemaJson[key] = _.cloneDeep(json.schemaJson[key].description);\n        } else if (json.schemaJson[key].type && json.schemaJson[key].description && _.isArray(json.schemaJson[key].description) && json.schemaJson[key].type.toUpperCase() === 'ARRAY') {\n          json.schemaJson[key] = [_.cloneDeep(json.schemaJson[key].description[0])];\n        }\n\n        const schemaJson = json.schemaJson[key];\n        if (_.isArray(schemaJson)) {\n          const arrData = schemaJson[0];\n          Object.keys(arrData).forEach((subKey) => {\n            if (arrData[subKey][PROPS.REF]) {\n              arrData[subKey][PROPS.REF] = arrData[subKey][PROPS.REF].replace(/ /g, '_');\n            }\n          });\n        } else if (!_.isArray(schemaJson) && typeof schemaJson === 'object') {\n          Object.keys(schemaJson).forEach((subKey) => {\n            if (schemaJson[subKey][PROPS.REF]) {\n              schemaJson[subKey][PROPS.REF] = schemaJson[subKey][PROPS.REF].replace(/ /g, '_');\n            }\n          });\n        }\n      });\n      return json;\n    });\n\n    const schemas = mJsonData;\n    let schemaErrors = [];\n\n    // Check model already exists.\n    const modelNames = _.map(schemas, 'modelName');\n    const schemaExists = await schemaRepo.getDetails({\n      find: { applicationId: params.applicationId },\n      multipleSearch: {\n        keywords: modelNames,\n        keys: ['name'],\n      },\n    });\n\n    let schemaList = await Promise.all(schemas.map(async (schema) => {\n      let checkSchemaExists = {};\n      if (schemaExists && _.size(schemaExists) > 0) {\n        checkSchemaExists = _.reject(_.map(schemaExists, (schemaVal) => {\n          if (schemaVal.name.toUpperCase() === schema.modelName.toUpperCase()) {\n            return schemaVal;\n          }\n          return {};\n        }), _.isEmpty);\n\n        if (!_.isEmpty(checkSchemaExists)) {\n          schemaErrors.push({\n            modelName: schema.modelName,\n            isExists: true,\n            schemaId: checkSchemaExists[0]._id,\n            schemaJson: schema.schemaJson,\n            error: ['Schema of same name already exists.'],\n          });\n        }\n      }\n\n      let created = [];\n      if (_.isEmpty(checkSchemaExists)) {\n        const schemaData = {\n\n          name: schema.modelName,\n          applicationId: params.applicationId,\n          description: schema.description,\n          schemaJson: schema.schemaJson,\n        };\n\n        if (schemaData?.schemaJson && !_.isEmpty(schemaData.schemaJson)) {\n          schemaData.schemaJson = await reOrderSchemaJson(_.cloneDeep(schemaData.schemaJson));\n        }\n        created = await schemaRepo.create(schemaData);\n\n        let schemaJson = {};\n        const additionalSetting = {};\n        // add schema detail according to accessible platform.\n        if (existingProject?.configInput?.loginAccess && existingProject?.configInput?.platform) {\n          const customPlatform = existingProject.configInput.platform;\n          let uniqPlatform = [];\n          _.each(existingProject.configInput.loginAccess, (v) => {\n            uniqPlatform = uniqPlatform.concat(v);\n          });\n          uniqPlatform = _.uniq(uniqPlatform);\n          if (customPlatform && _.size(customPlatform)) {\n            _.each(customPlatform, (data) => {\n              let schemaJsonOpt = [];\n              let additionalSettingOpt = [];\n\n              if (_.includes(uniqPlatform, data)) {\n                schemaJsonOpt = schemaJsonAuthOptions();\n                additionalSettingOpt = getAdditionalJsonAuthOptions();\n              } else {\n                schemaJsonOpt = schemaJsonOptions();\n                additionalSettingOpt = getAdditionalJsonWithoutAuthOptions();\n              }\n\n              schemaJson[data] = schemaJsonOpt;\n              additionalSetting[data] = additionalSettingOpt;\n            });\n          }\n        }\n\n        if (schemaJson && !_.size(schemaJson)) {\n          schemaJson = schemaJsonAuthPlatform();\n        }\n\n        let additionalJson = {};\n        if (additionalSetting && !_.isEmpty(additionalSetting)) {\n          additionalJson = { additionalSetting };\n        } else if (!additionalSetting || _.isEmpty(additionalSetting)) {\n          additionalJson = getAdditionalJsonAuthPlatform();\n        }\n        const detail = {\n          schemaId: created._id,\n          schemaJson,\n          additionalJson,\n        };\n\n        const schemaDetails = await SchemaDetail.create(detail);\n        const allRouts = getPermissionWiseRoute(schemaDetails.schemaJson, created);\n        await (routeInsertManyUseCase(projectRouteRepo))({ routes: allRouts });\n      }\n      return created;\n    }));\n    schemaList = _.cloneDeep(_.compact(_.filter(schemaList, _.size)));\n    fileErrors = _.compact(_.flattenDeep(fileErrors));\n    schemaErrors = _.compact(_.flattenDeep(schemaErrors));\n\n    let modelErrors = _.map(fileErrors, (val) => {\n      const schemaEx = _.find(schemaErrors, { modelName: val.modelName });\n      if (schemaEx) {\n        return {};\n      }\n      return val;\n    });\n\n    modelErrors = _.cloneDeep(_.compact(_.reject(modelErrors, _.isEmpty)));\n\n    const errData = _.compact(_.flattenDeep(modelErrors));\n    return {\n      ...MODEL_UPLOADED,\n      data: {\n        error: errData,\n        success: schemaList,\n        existsModels: _.compact(_.flattenDeep(schemaErrors)),\n      },\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/schema/paginate.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst paginate = (schemaRepo) => async (param) => {\n  try {\n    let params = param;\n    if (!params) {\n      params = {};\n    }\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    if (!params.find) {\n      params.find = {};\n    }\n    params.find.applicationId = params.applicationId;\n\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    const filter = params;\n    const response = {\n      list: await schemaRepo.getDetails(filter),\n      count: await schemaRepo.getCount(filter),\n    };\n\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/schema/searchSchema.js",
    "content": "/* global _ */\nconst axios = require('axios');\nconst cheerio = require('cheerio');\nconst { DATABASE_TYPE } = require('../../models/constants/applicationConfig');\nconst mongoDBDataTypes = require('../../constants/schema').DATA_TYPES;\nconst { SCHEMA_ORG_URL } = require('../../constants/schema');\nconst {\n  mySqlDataTypes, postGreSqlDataTypes, sqlDataTypes,\n} = require('../../constants/dataTypes/sequelize');\n\nconst { schemaSearchValidation } = require('../util/validation/schema');\n\nconst {\n  OK, SERVER_ERROR, SCHEMA_SEARCH_FAILED, APPLICATION_DETAILS_NOT_FOUND, BAD_REQUEST,\n} = require('../../constants/message').message;\n\nconst searchSchema = (applicationRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = schemaSearchValidation(params);\n    if (error) {\n      return {\n        ...BAD_REQUEST,\n        message: error,\n      };\n    }\n    params = _.cloneDeep(value);\n\n    const applicationDetails = await applicationRepo.get({ find: { _id: params.applicationId } });\n    if (!applicationDetails) {\n      return APPLICATION_DETAILS_NOT_FOUND;\n    }\n\n    const url = `${SCHEMA_ORG_URL}/${params.schemaName}`;\n    const apiResponse = await axios(url)\n      .then((response) => {\n        const html = response.data;\n        const $ = cheerio.load(html);\n        const statsTable = $('.definition-table > tbody > tr');\n        const schemaData = [];\n        statsTable.each(() => {\n          const group = $(this).find('tr.supertype > th > a').text();\n          const attribute = $(this).find('tr > th.prop-nam > code > a').text();\n          const dataType = $(this).find('tr > td.prop-ect > a').text();\n          const description = $(this).find('tr > td.prop-desc').text();\n\n          schemaData.push({\n            group,\n            attribute,\n            dataType,\n            description,\n          });\n        });\n        return schemaData;\n      })\n      .catch((errors) => errors);\n\n    if (!apiResponse || !_.isArray(apiResponse) || apiResponse.length <= 0) {\n      return {\n        ...SCHEMA_SEARCH_FAILED,\n        data: apiResponse.toString(),\n      };\n    }\n\n    // Mapping dataTypes\n    let dataTypes = _.keys(mongoDBDataTypes);\n    let defaultDataType = _.cloneDeep(mongoDBDataTypes.STRING.value);\n    if (applicationDetails?.stepInput?.databaseType === DATABASE_TYPE.SQL) {\n      dataTypes = _.keys(sqlDataTypes.DATA_TYPES);\n      defaultDataType = _.cloneDeep(sqlDataTypes.DATA_TYPES.STRING.VALUE);\n    } else if (applicationDetails?.stepInput?.databaseType === DATABASE_TYPE.MYSQL) {\n      dataTypes = _.keys(mySqlDataTypes.DATA_TYPES);\n      defaultDataType = _.cloneDeep(mySqlDataTypes.DATA_TYPES.STRING.VALUE);\n    } else if (applicationDetails?.stepInput?.databaseType === DATABASE_TYPE.POSTGRE_SQL) {\n      dataTypes = _.keys(postGreSqlDataTypes.DATA_TYPES);\n      defaultDataType = _.cloneDeep(postGreSqlDataTypes.DATA_TYPES.STRING.VALUE);\n    }\n\n    const schemaJsonData = {\n      name: params.schemaName,\n      schemaJson: {},\n    };\n    _.each(apiResponse, (schema) => {\n      let dataTypeMatch = false;\n      if (schema?.attribute && schema.attribute !== '') {\n        if (schema?.attribute && schema.attribute !== '' && schema?.dataType && schema.dataType !== '') {\n          _.each(dataTypes, (type) => {\n            let schDataType = schema.dataType.replace(/([a-z](?=[A-Z]))/g, '$1 ').split(' ');\n            schDataType = schDataType.map((v) => v.toLowerCase());\n            if (_.includes(schDataType, type.toLowerCase())) {\n              dataTypeMatch = true;\n              schema.dataType = type;\n            }\n          });\n        }\n        if (!dataTypeMatch) {\n          schema.dataType = defaultDataType;\n        }\n        const { attribute } = schema;\n        schemaJsonData.schemaJson[attribute] = {\n          type: schema.dataType,\n          description: schema.description,\n        };\n      }\n    });\n    return {\n      ...OK,\n      data: schemaJsonData,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = searchSchema;\n"
  },
  {
    "path": "packages/server/usecase/schema/sequelize/existsSchemaUpdate.js",
    "content": "/* global MESSAGE, _ */\nconst {\n  DATABASE_TYPE, ORM_TYPE,\n} = require('../../../models/constants/applicationConfig');\nconst {\n  SERVER_ERROR, MODELS_UPDATED, BAD_REQUEST,\n} = require('../../../constants/message').message;\n\nconst {\n  VALIDATION_MESSAGES, DEFAULT_FIELDS,\n} = require('../../../constants/schema');\n\nconst { getApplicationDetail } = require('../../util/getApplicationData');\nconst validateSequelizeDataTypes = require('../util/sequelize/validateDataTypes');\nconst {\n  mySqlDataTypes, sqlDataTypes, postGreSqlDataTypes,\n} = require('../../../constants/dataTypes/sequelize');\nconst { sequelizeExistingSchemaUpdateValidation } = require('../../util/validation/schema');\nconst { PROPS } = require('../../../constants/dataTypes/props');\n\nconst {\n  getDefaultFieldsForSequelize, reOrderSchemaJson,\n} = require('../util/staticData');\n\nconst existsSchemaUpdate = (schemaRepo, applicationRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = sequelizeExistingSchemaUpdateValidation(params);\n    if (error) {\n      return {\n        ...BAD_REQUEST,\n        message: error,\n      };\n    }\n\n    params = _.cloneDeep(value);\n\n    // Validate application.\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: params.applicationId,\n      fields: ['name', 'configInput', 'stepInput', 'isArchive', 'definitionId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n\n    const applicationDetails = _.cloneDeep(applicationData.data);\n\n    const dbType = applicationDetails.stepInput.databaseType;\n    const { ormType } = applicationDetails.stepInput;\n\n    let modelErrors = [];\n    const success = [];\n\n    await Promise.all(params.models.map(async (model) => {\n      let propErrors = [];\n      if (model.isUploadedFile === true) {\n        const schemaFilter = {\n          find: {\n            applicationId: params.applicationId,\n            _id: model.schemaId,\n          },\n        };\n        const schema = await schemaRepo.get(schemaFilter);\n        if (!schema) {\n          modelErrors.push({\n            modelName: model.modelName,\n            error: VALIDATION_MESSAGES.MODEL_NOT_FOUND,\n          });\n        } else {\n          if (ormType === ORM_TYPE.SEQUELIZE && dbType === DATABASE_TYPE.SQL) {\n            // eslint-disable-next-line no-await-in-loop\n            propErrors = await validateSequelizeDataTypes({\n              model,\n              dataTypes: sqlDataTypes.DATA_TYPES,\n            });\n          } else if (ormType === ORM_TYPE.SEQUELIZE && dbType === DATABASE_TYPE.MYSQL) {\n            // eslint-disable-next-line no-await-in-loop\n            propErrors = await validateSequelizeDataTypes({\n              model,\n              dataTypes: mySqlDataTypes.DATA_TYPES,\n            });\n          } else if (ormType === ORM_TYPE.SEQUELIZE && dbType === DATABASE_TYPE.POSTGRE_SQL) {\n            // eslint-disable-next-line no-await-in-loop\n            propErrors = await validateSequelizeDataTypes({\n              model,\n              dataTypes: postGreSqlDataTypes.DATA_TYPES,\n            });\n          }\n\n          if (propErrors && (propErrors.errors && _.size(propErrors.errors) > 0)) {\n            modelErrors.push(propErrors.errors);\n          }\n\n          if (propErrors?.model && _.size(propErrors.model) > 0) {\n            model.schemaJson = _.cloneDeep(propErrors.model.schemaJson);\n          }\n\n          const defaultFields = await getDefaultFieldsForSequelize({ ormType: applicationDetails?.stepInput?.ormType });\n\n          const lowerSchemaJsonKeys = Object.keys(model.schemaJson).map((key) => key.toLowerCase());\n          Object.keys(defaultFields).forEach((field) => {\n            if (!_.includes(lowerSchemaJsonKeys, field.toLowerCase())) {\n              model.schemaJson[field] = defaultFields[field];\n            }\n          });\n\n          _.map(Object.keys(model.schemaJson), (key) => {\n            if (key.toLowerCase() === DEFAULT_FIELDS.ID) {\n              model.schemaJson[key][PROPS.IS_AUTO_INCREMENT] = true;\n              model.schemaJson[key][PROPS.PRIMARY] = true;\n            }\n          });\n\n          const updateModelInput = { schemaJson: model.schemaJson };\n          if (updateModelInput?.schemaJson && !_.isEmpty(updateModelInput.schemaJson)) {\n            updateModelInput.schemaJson = await reOrderSchemaJson(_.cloneDeep(updateModelInput.schemaJson));\n          }\n          const schemaUpdate = await schemaRepo.update(model.schemaId, updateModelInput);\n          if (schemaUpdate) {\n            success.push(schemaUpdate.toObject());\n          } else {\n            modelErrors.push({\n              modelName: model.modelName,\n              error: VALIDATION_MESSAGES.UPDATE_MODEL_ERROR,\n            });\n          }\n        }\n      }\n    }));\n\n    modelErrors = _.cloneDeep(_.flattenDeep(_.uniq(modelErrors)));\n\n    return {\n      ...MODELS_UPDATED,\n      data: {\n        error: modelErrors,\n        success,\n      },\n    };\n  } catch (err) {\n    // eslint-disable-next-line no-console\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = existsSchemaUpdate;\n"
  },
  {
    "path": "packages/server/usecase/schema/update.js",
    "content": "/* global MESSAGE, _ */\nconst mongoose = require('mongoose');\n\nconst {\n  ORM_TYPE, DATABASE_TYPE,\n} = require('../../models/constants/applicationConfig');\nconst { ROUTE_GENERATE_TYPE } = require('../../models/constants/project');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst { getApplicationDetail } = require('../util/getApplicationData');\nconst updateSchemaReferences = require('./util/updateSchemaReferences');\n\nconst validateSequelizeDataTypes = require('./util/sequelize/validateDataTypes');\nconst {\n  mySqlDataTypes, sqlDataTypes, postGreSqlDataTypes,\n} = require('../../constants/dataTypes/sequelize');\nconst SchemaDetailsRepository = require('../../repo/schemaDetail');\nconst ProjectRouteRepository = require('../../repo/projectRoute');\n\nconst schemaDetailsRepo = new SchemaDetailsRepository();\nconst projectRouteRepo = new ProjectRouteRepository();\n\nconst { reOrderSchemaJson } = require('./util/staticData');\n\nconst {\n  INVALID_REQUEST_PARAMS, SCHEMA_NOT_FOUND, OK, SERVER_ERROR, MODEL_UPDATED, RECORD_WITH_SAME_NAME_EXISTS, INVALID_SCHEMA_ATTR,\n} = require('../../constants/message').message;\nconst { schemaUpdateValidation } = require('../util/validation/schema');\nconst { updateSchemaRefAttribute } = require('./util');\nconst { validateRegEx } = require('./util');\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (schemaRepo, applicationRepo) => async (id, params) => {\n  try {\n    const {\n      value, error,\n    } = schemaUpdateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    // Validate Unique Criteria\n    const filter = { find: { _id: id } };\n    const isValidId = mongoose.Types.ObjectId.isValid(id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const schema = await schemaRepo.get({ filter });\n\n    if (!schema) {\n      return SCHEMA_NOT_FOUND;\n    }\n\n    // Check schema already exists.\n    const schemaData = await schemaRepo.get({\n      find: { applicationId: schema.applicationId },\n      nin: [{ _id: id }],\n      search: {\n        keyword: params.name,\n        keys: ['name'],\n      },\n    });\n    if (schemaData && schemaData.name.toUpperCase() === params.name.toUpperCase()) {\n      return RECORD_WITH_SAME_NAME_EXISTS;\n    }\n\n    const applicationData = await getApplicationDetail(applicationRepo)({\n      applicationId: schema.applicationId,\n      fields: ['stepInput.ormType', 'stepInput.databaseType', 'projectId'],\n    });\n\n    if (applicationData?.code !== MESSAGE.OK.code) {\n      return applicationData;\n    }\n    const application = applicationData?.data;\n\n    let dataTypeValidateErr = [];\n\n    // Validate sequelize dataTypes.\n    if (application?.stepInput?.ormType && application?.stepInput?.databaseType && _.includes([ORM_TYPE.SEQUELIZE, ORM_TYPE.ELOQUENT], application.stepInput.ormType) && params?.schemaJson) {\n      const {\n        databaseType, ormType,\n      } = application.stepInput;\n      if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.SQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: sqlDataTypes.DATA_TYPES,\n        });\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.MYSQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: mySqlDataTypes.DATA_TYPES,\n        });\n      } else if (ormType === ORM_TYPE.SEQUELIZE && databaseType === DATABASE_TYPE.POSTGRE_SQL) {\n        dataTypeValidateErr = await validateSequelizeDataTypes({\n          model: params,\n          dataTypes: postGreSqlDataTypes.DATA_TYPES,\n        });\n      }\n    } else {\n      // Validate `RegExp` pattern.\n      // eslint-disable-next-line no-lonely-if\n      if (params?.schemaJson) {\n        const validateRegExp = await validateRegEx(params.schemaJson);\n        if (validateRegExp.code !== OK.code) {\n          return validateRegExp;\n        }\n      }\n    }\n\n    if (dataTypeValidateErr.errors && dataTypeValidateErr.errors.length) {\n      return {\n        ...INVALID_SCHEMA_ATTR,\n        data: dataTypeValidateErr.errors,\n      };\n    }\n\n    if (params?.schemaJson && dataTypeValidateErr?.model?.schemaJson) {\n      params.schemaJson = _.cloneDeep(dataTypeValidateErr.model.schemaJson);\n    }\n\n    if (params?.schemaJson && !_.isEmpty(params.schemaJson)) {\n      params.schemaJson = await reOrderSchemaJson(_.cloneDeep(params.schemaJson));\n    }\n    const updateResponse = await schemaRepo.update(id, params);\n\n    if (schema.name !== updateResponse.name) {\n      // if schema name changed, then update all references.\n      const updatedRes = await updateSchemaReferences({\n        oldSchema: schema,\n        updatedSchema: updateResponse,\n      });\n      if (updatedRes.code !== OK.code) {\n        throw new Error(updatedRes.data);\n      }\n    }\n\n    // Update `attributes` in `schema-details` and `project-routes`;\n    if (params?.customJson?.dependencySetting) {\n      const updatedSchemaJson = params.customJson.dependencySetting;\n\n      // Update `additionalSetting.additionalJson.attributes` in `schema-details` collection.\n      const schemaDetailsData = await schemaDetailsRepo.get({ find: { schemaId: updateResponse._id } });\n      if (schemaDetailsData?.additionalJson?.additionalSetting) {\n        _.each(schemaDetailsData.additionalJson.additionalSetting, (platform) => {\n          _.each(platform, (p) => {\n            if (p?.attributes.length > 0) {\n              _.map(p?.attributes, (attr, index) => {\n                const objKey = attr.split('.');\n                let updatedKey = {};\n                let isChild = false;\n                let isParent = false;\n                if (objKey[0] && objKey[1]) {\n                  // Child key name changes.\n                  updatedKey = _.find(updatedSchemaJson, {\n                    oldKey: objKey[1],\n                    parentKey: objKey[0],\n                  });\n\n                  // Parent key name changes.\n                  if (!_.isEmpty(updatedKey)) {\n                    isChild = true;\n                  } else {\n                    updatedKey = _.find(updatedSchemaJson, { oldKey: objKey[0] });\n                    isParent = true;\n                  }\n                } else {\n                  updatedKey = _.find(updatedSchemaJson, { oldKey: attr });\n                }\n                if (updatedKey?.isDelete) {\n                  delete (p.attributes[index]);\n                } else if (updatedKey?.parentKey && updatedKey.parentKey !== '' && updatedKey.newKey !== '' && isChild) {\n                  delete (p.attributes[index]);\n                  p.attributes.push(`${objKey[0]}.${updatedKey.newKey}`);\n                } else if (updatedKey?.newKey && updatedKey.newKey !== '' && isParent) {\n                  delete (p.attributes[index]);\n                  p.attributes.push(`${updatedKey.newKey}.${objKey[1]}`);\n                } else if (updatedKey?.newKey && updatedKey.newKey !== '') {\n                  delete (p.attributes[index]);\n                  p.attributes.push(updatedKey.newKey);\n                }\n              });\n              p.attributes = _.compact(p.attributes);\n            }\n          });\n        });\n        await schemaDetailsRepo.update(schemaDetailsData._id, { 'additionalJson.additionalSetting': schemaDetailsData.additionalJson.additionalSetting });\n      }\n\n      // Update `attributes` in `project-routes`.\n      const projectRouteData = await projectRouteRepo.getDetails({\n        find: {\n          modelId: updateResponse._id,\n          applicationId: application._id,\n          type: ROUTE_GENERATE_TYPE.MANUAL,\n        },\n      });\n      if (projectRouteData && projectRouteData.length > 0) {\n        for (let i = 0; i < projectRouteData.length; i += 1) {\n          const route = projectRouteData[i];\n          if (route?.attributes && route?.attributes.length > 0) {\n            _.map(route.attributes, (attr, index) => {\n              const objKey = attr.split('.');\n              let updatedKey = {};\n              let isChild = false;\n              let isParent = false;\n              if (objKey[0] && objKey[1]) {\n                // Child key name changes.\n                updatedKey = _.find(updatedSchemaJson, {\n                  oldKey: objKey[1],\n                  parentKey: objKey[0],\n                });\n\n                // Parent key name changes.\n                if (!_.isEmpty(updatedKey)) {\n                  isChild = true;\n                } else {\n                  updatedKey = _.find(updatedSchemaJson, { oldKey: objKey[0] });\n                  isParent = true;\n                }\n              } else {\n                updatedKey = _.find(updatedSchemaJson, { oldKey: attr });\n              }\n              if (updatedKey?.isDelete) {\n                delete (route.attributes[index]);\n              } else if (updatedKey?.parentKey && updatedKey.parentKey !== '' && updatedKey.newKey !== '' && isChild) {\n                delete (route.attributes[index]);\n                route.attributes.push(`${objKey[0]}.${updatedKey.newKey}`);\n              } else if (updatedKey?.newKey && updatedKey.newKey !== '' && isParent) {\n                delete (route.attributes[index]);\n                route.attributes.push(`${updatedKey.newKey}.${objKey[1]}`);\n              } else if (updatedKey?.newKey && updatedKey.newKey !== '') {\n                delete (route.attributes[index]);\n                route.attributes.push(updatedKey.newKey);\n              }\n            });\n            route.attributes = _.compact(route.attributes);\n\n            // eslint-disable-next-line no-await-in-loop\n            await projectRouteRepo.update(route._id, { attributes: route.attributes });\n          }\n        }\n      }\n    }\n\n    const schemaParams = {\n      applicationId: schema.applicationId,\n      oldName: schema.name,\n      updatedName: params.name,\n      updateSchema: updateResponse,\n    };\n    if (params?.customJson?.dependencySetting) {\n      schemaParams.dependencySetting = params.customJson.dependencySetting;\n    }\n    // Update `ref` attribute of all models.\n    const updateRefRes = await updateSchemaRefAttribute({\n      schemaRepo,\n      schemaParams,\n    });\n    if (updateRefRes?.code && updateRefRes.code !== OK.code) {\n      throw new Error(updateRefRes.data);\n    }\n    const updatedSchema = await schemaRepo.get({ find: { _id: id } });\n\n    projectApplicationUpdate({\n      params: {\n        projectId: application?.projectId,\n        applicationId: schema?.applicationId,\n      },\n    });\n\n    let responseMsg = OK;\n    responseMsg = MODEL_UPDATED;\n\n    return {\n      ...responseMsg,\n      data: updatedSchema,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/deleteSchemaRefInfo.js",
    "content": "/* global _ */\n\nconst SchemaRepository = require('../../../repo/schema');\n\nconst schemaRepo = new SchemaRepository();\n\nconst {\n  OK, SERVER_ERROR,\n} = require('../../../constants/message').message;\n\n// Function used to give info and update schema-name related data, `schema` collection.\nconst deleteSchemaRefInfo = async ({\n  delSchemaDetails, isInfo,\n}) => {\n  try {\n    const filter = { find: { applicationId: delSchemaDetails.applicationId } };\n    const schemaData = await schemaRepo.getDetails(filter);\n    const schemaErrors = [];\n    if (schemaData && schemaData.length > 0) {\n      for (let i = 0; i < schemaData.length; i += 1) {\n        const {\n          schemaJson, name, _id,\n        } = schemaData[i];\n        _.each(schemaJson, async (val, key) => {\n          if (schemaJson[key]?.ref && schemaJson[key].ref.toUpperCase() === delSchemaDetails.name.toUpperCase()) {\n            if (isInfo) {\n              schemaErrors.push({\n                modelName: name,\n                key,\n              });\n            } else {\n              delete schemaJson[key];\n            }\n          }\n          // JSON\n          if (typeof schemaJson[key] === 'object') {\n            _.each(schemaJson[key], (jVal, jKey) => {\n              if (schemaJson[key][jKey]?.ref && schemaJson[key][jKey].ref.toUpperCase() === delSchemaDetails.name.toUpperCase()) {\n                if (isInfo) {\n                  schemaErrors.push({\n                    modelName: name,\n                    key: jKey,\n                    parentKey: key,\n                  });\n                } else {\n                  delete schemaJson[key][jKey];\n                }\n              }\n            });\n          }\n          // Array\n          if (_.isArray(schemaJson[key])) {\n            _.each(schemaJson[key][0], (jVal, jKey) => {\n              if (schemaJson[key][0][jKey]?.ref && schemaJson[key][0][jKey].ref.toUpperCase() === delSchemaDetails.name.toUpperCase()) {\n                if (isInfo) {\n                  schemaErrors.push({\n                    modelName: name,\n                    key: jKey,\n                    parentKey: key,\n                  });\n                } else {\n                  delete schemaJson[key][0][jKey];\n                }\n              }\n            });\n          }\n        });\n        if (!isInfo) {\n          // eslint-disable-next-line no-await-in-loop\n          await schemaRepo.update(_id, { schemaJson });\n        }\n      }\n    }\n\n    return {\n      ...OK,\n      data: { schemaErrors },\n    };\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n};\n\nmodule.exports = deleteSchemaRefInfo;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/deleteSchemaReferences.js",
    "content": "/* global _ */\nconst {\n  OK, SERVER_ERROR,\n} = require('../../../constants/message').message;\n\nconst ProjectRouteRepository = require('../../../repo/projectRoute');\nconst QueryBuilderRepository = require('../../../repo/queryBuilder');\nconst NestedQueryBuilderRepository = require('../../../repo/nestedQueryBuilder');\nconst SchemaDetailRepository = require('../../../repo/schemaDetail');\n\nconst projectRouteRepo = new ProjectRouteRepository();\nconst queryBuilderRepo = new QueryBuilderRepository();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepository();\nconst schemaDetailRepo = new SchemaDetailRepository();\n\n/**\n * Function used to delete schema related details in `project-route`.\n * @param  {} {schemaData\n * @param  {} isHardDelete\n * @param  {} }\n */\nasync function delProjectRoute ({\n  schemaData, isHardDelete,\n}) {\n  try {\n    const filter = {\n      find: {\n        applicationId: schemaData.applicationId,\n        modelId: schemaData._id,\n      },\n    };\n    const routeData = await projectRouteRepo.getDetails(filter);\n    if (routeData && routeData.length > 0) {\n      const ids = _.map(routeData, '_id');\n      if (isHardDelete) {\n        await projectRouteRepo.deleteMany({ find: { _id: ids } });\n      } else {\n        const updateFilter = {\n          filter: { find: { _id: ids } },\n          data: { isDeleted: true },\n        };\n        await projectRouteRepo.updateMany(updateFilter);\n      }\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to delete schema related details in `query-builder`.\n * @param  {} {schemaData\n * @param  {} isHardDelete\n * @param  {} }\n */\nasync function delQueryBuilder ({\n  schemaData, isHardDelete,\n}) {\n  try {\n    const filter = {\n      find: {\n        applicationId: schemaData.applicationId,\n        modelId: schemaData._id,\n      },\n    };\n    const queryBuilderData = await queryBuilderRepo.getDetails(filter);\n    if (queryBuilderData && queryBuilderData.length > 0) {\n      const ids = _.map(queryBuilderData, '_id');\n      if (isHardDelete) {\n        await queryBuilderRepo.deleteMany({ find: { _id: ids } });\n      } else {\n        const updateFilter = {\n          filter: { find: { _id: ids } },\n          data: { isDeleted: true },\n        };\n        await queryBuilderRepo.updateMany(updateFilter);\n      }\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to delete schema related details in `nested-query-builder`.\n * @param  {} {schemaData\n * @param  {} isHardDelete\n * @param  {} }\n */\nasync function delNestedQueryBuilder ({\n  schemaData, isHardDelete,\n}) {\n  try {\n    const filter = {\n      find: {\n        applicationId: schemaData.applicationId,\n        modelId: schemaData._id,\n      },\n    };\n    const nQueryBuilderData = await nestedQueryBuilderRepo.getDetails(filter);\n    if (nQueryBuilderData && nQueryBuilderData.length > 0) {\n      const ids = _.map(nQueryBuilderData, '_id');\n      if (isHardDelete) {\n        await nestedQueryBuilderRepo.deleteMany({ find: { _id: ids } });\n      } else {\n        const updateFilter = {\n          filter: { find: { _id: ids } },\n          data: { isDeleted: true },\n        };\n        await nestedQueryBuilderRepo.updateMany(updateFilter);\n      }\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to delete schema related details in `schema-details`.\n * @param  {} {schemaData\n * @param  {} isHardDelete\n * @param  {} }\n */\nasync function deleteSchemaDetails ({\n  schemaData, isHardDelete,\n}) {\n  try {\n    const filter = { find: { schemaId: schemaData._id } };\n    const schemaDetails = await schemaDetailRepo.getDetails(filter);\n    if (schemaDetails && schemaDetails.length > 0) {\n      const ids = _.map(schemaDetails, '_id');\n      if (isHardDelete) {\n        await schemaDetailRepo.deleteMany({ find: { _id: ids } });\n      } else {\n        const updateFilter = {\n          filter: { find: { _id: ids } },\n          data: { isDeleted: true },\n        };\n        await schemaDetailRepo.updateMany(updateFilter);\n      }\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\nconst deleteSchemaReferences = async ({\n  schemaData, isHardDelete,\n}) => {\n  try {\n    // Delete schema reference in `Project-Route`.\n    const routeRes = await delProjectRoute({\n      schemaData,\n      isHardDelete,\n    });\n    if (routeRes?.code !== OK.code) {\n      throw new Error(routeRes.data);\n    }\n\n    // Delete schema reference in `Query-Builder`.\n    const queryBuilderRes = await delQueryBuilder({\n      schemaData,\n      isHardDelete,\n    });\n    if (queryBuilderRes?.code !== OK.code) {\n      throw new Error(queryBuilderRes.data);\n    }\n\n    // Delete schema reference in `Nested-Query-Builder`.\n    const nQueryBuilderRes = await delNestedQueryBuilder({\n      schemaData,\n      isHardDelete,\n    });\n    if (nQueryBuilderRes?.code !== OK.code) {\n      throw new Error(nQueryBuilderRes.data);\n    }\n\n    // Delete schema reference in `Schema-Details`.\n    const schemaDetailsRes = await deleteSchemaDetails({\n      schemaData,\n      isHardDelete,\n    });\n    if (schemaDetailsRes?.code !== OK.code) {\n      throw new Error(schemaDetailsRes.data);\n    }\n\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n};\n\nmodule.exports = deleteSchemaReferences;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/index.js",
    "content": "const validateProperties = require('./validateProps');\nconst updateSchemaRefAttribute = require('./updateSchemaRefAttribute');\nconst validateRegEx = require('./validateRegEx');\nconst isRegExp = require('./isRegExp');\nconst updateSchemaReferences = require('./updateSchemaReferences');\nconst deleteSchemaReferences = require('./deleteSchemaReferences');\nconst deleteSchemaRefInfo = require('./deleteSchemaRefInfo');\n\nmodule.exports = {\n  validateProperties,\n  updateSchemaRefAttribute,\n  validateRegEx,\n  isRegExp,\n  updateSchemaReferences,\n  deleteSchemaReferences,\n  deleteSchemaRefInfo,\n};\n"
  },
  {
    "path": "packages/server/usecase/schema/util/isRegExp.js",
    "content": "const isRegExp = (string) => {\n  try {\n    // eslint-disable-next-line no-new-func\n    return new Function(`\n              \"use strict\";\n              try {\n                  new RegExp(${string});\n                  return true;\n              } catch (e) {\n                  return false;\n              }\n          `)();\n  } catch (e) {\n    return false;\n  }\n};\n\nmodule.exports = isRegExp;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/sequelize/validateDataTypes.js",
    "content": "/* global _ */\nconst {\n  VALIDATION_MESSAGES, RELATIONS_TYPES,\n} = require('../../../../constants/schema');\nconst { PROPS } = require('../../../../constants/dataTypes/props');\nconst {\n  INTEGER, BIGINT, FLOAT, REAL, DOUBLE, DECIMAL, UnsignedBigInt,\n} = require('../../../../constants/dataTypes/dataTypes');\nconst isRegExp = require('../isRegExp');\n\nconst validateDataTypes = async ({\n  model, dataTypes,\n}) => {\n  const notNullDataTypes = [INTEGER.VALUE, BIGINT.VALUE, FLOAT.VALUE, REAL.VALUE, DOUBLE.VALUE, DECIMAL.VALUE];\n\n  // Convert case-sensitive properties to proper name.\n  const dataTypesKeyValArr = [];\n  Object.keys(PROPS).forEach((v) => {\n    dataTypesKeyValArr.push({\n      key: PROPS[v].toUpperCase(),\n      val: PROPS[v],\n    });\n  });\n  _.map(model.schemaJson, (val) => {\n    _.map(_.keys(val), (k) => {\n      const dType = _.find(dataTypesKeyValArr, { key: k.toUpperCase() });\n      if (dType) {\n        const keyVal = val[k];\n        delete val[k];\n        val[dType.val] = keyVal;\n      }\n    });\n  });\n\n  const errors = [];\n  const schemaJson = _.cloneDeep(model.schemaJson);\n  const keys = _.keys(model.schemaJson);\n\n  for (let i = 0; i < keys.length; i += 1) {\n    const keyErr = [];\n    if (schemaJson[keys[i]].type) {\n      if (schemaJson[keys[i]].type !== UnsignedBigInt.VALUE) {\n        schemaJson[keys[i]].type = _.cloneDeep(schemaJson[keys[i]].type.toUpperCase());\n      }\n      const keyObj = schemaJson[keys[i]];\n\n      let TYPE = keyObj.type;\n      if (keyObj.type !== UnsignedBigInt.VALUE) {\n        TYPE = keyObj.type.toUpperCase();\n      }\n\n      if (dataTypes[TYPE]) {\n        const keyProps = _.keys(keyObj);\n        let allowProps = _.cloneDeep(dataTypes[TYPE].ALLOW_PROPS);\n        if (dataTypes[TYPE].NA_PROPS && dataTypes[TYPE].NA_PROPS.length) {\n          allowProps = _.compact(_.difference(allowProps, dataTypes[TYPE].NA_PROPS));\n        }\n        allowProps.push('type');\n\n        const NAProps = _.compact(_.difference(keyProps, allowProps));\n        // Not allowed props.\n        if (NAProps && NAProps.length) {\n          _.map(NAProps, (v) => {\n            keyErr.push(`${VALIDATION_MESSAGES.PROP_NOT_ALLOWED} - ${v}`);\n          });\n        }\n\n        // Validate RegExp pattern.\n        if (typeof keyObj === 'object' && keyObj[PROPS.PATTERN]) {\n          const validPattern = isRegExp(keyObj[PROPS.PATTERN]);\n          if (!validPattern) {\n            keyErr.push(`${VALIDATION_MESSAGES.INVALID_REGEXP} - ${keyObj[PROPS.PATTERN]}`);\n          }\n        }\n\n        // Validate MAX & DEFAULT prop.\n        if (keyObj[PROPS.DEFAULT] && _.includes(allowProps, PROPS.DEFAULT)\n        && keyObj[PROPS.MAX] && _.includes(allowProps, PROPS.MAX)) {\n          if (keyObj[PROPS.DEFAULT] > keyObj[PROPS.MAX]) {\n            keyErr.push(`${VALIDATION_MESSAGES.DEFAULT_MUST_LOWER_OR_EQUAL_TO_MAX}`);\n          }\n        }\n\n        // Validate MIN & DEFAULT prop.\n        if (keyObj[PROPS.DEFAULT] && _.includes(allowProps, PROPS.DEFAULT)\n        && keyObj[PROPS.MIN] && _.includes(allowProps, PROPS.MIN)) {\n          if (keyObj[PROPS.DEFAULT] < keyObj[PROPS.MIN]) {\n            keyErr.push(`${VALIDATION_MESSAGES.DEFAULT_MUST_GREATER_OR_EQUAL_TO_MIN}`);\n          }\n        }\n\n        // Validate MIN & MAX prop.\n        if (keyObj[PROPS.MAX] && _.includes(allowProps, PROPS.MAX)\n        && keyObj[PROPS.MIN] && _.includes(allowProps, PROPS.MIN)) {\n          if (keyObj[PROPS.MAX] < keyObj[PROPS.MIN]) {\n            keyErr.push(`${VALIDATION_MESSAGES.MAX_MUST_GREATER_TO_MIN}`);\n          }\n        }\n\n        // Validate MAX_LENGTH & DEFAULT prop.\n        if (keyObj[PROPS.DEFAULT] && _.includes(allowProps, PROPS.DEFAULT)\n        && keyObj[PROPS.MAX_LENGTH] && _.includes(allowProps, PROPS.MAX_LENGTH)) {\n          if (keyObj[PROPS.DEFAULT] > keyObj[PROPS.MAX_LENGTH]) {\n            keyErr.push(`${VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_LOWER_OR_EQUAL_TO_MAX_LENGTH}`);\n          }\n        }\n\n        // Validate MIN_LENGTH & DEFAULT prop.\n        if (keyObj[PROPS.DEFAULT] && _.includes(allowProps, PROPS.DEFAULT)\n        && keyObj[PROPS.MIN_LENGTH] && _.includes(allowProps, PROPS.MIN_LENGTH)) {\n          if (keyObj[PROPS.DEFAULT] < keyObj[PROPS.MIN_LENGTH]) {\n            keyErr.push(`${VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_GREATER_OR_EQUAL_TO_MIN_LENGTH}`);\n          }\n        }\n\n        // Validate MIN_LENGTH & MAX_LENGTH prop.\n        if (keyObj[PROPS.MAX_LENGTH] && _.includes(allowProps, PROPS.MAX_LENGTH)\n        && keyObj[PROPS.MIN_LENGTH] && _.includes(allowProps, PROPS.MIN_LENGTH)) {\n          if (keyObj[PROPS.MAX_LENGTH] < keyObj[PROPS.MIN_LENGTH]) {\n            keyErr.push(`${VALIDATION_MESSAGES.MAX_LENGTH_MUST_GREATER_TO_MIN_LENGTH}`);\n          }\n        }\n\n        // Validate `ref` field attribute.\n        if (keyObj[PROPS.REF] && _.includes(allowProps, PROPS.REF)) {\n          if (!keyObj[PROPS.REF_ATTR]) {\n            keyErr.push(`${VALIDATION_MESSAGES.MISSING_RELATION_ATTR_PROP}`);\n          }\n        }\n\n        // Do not allow `NULL` value in `default` prop, when field contain `required` property.\n        if (keyObj[PROPS.REQUIRED] && (keyObj[PROPS.DEFAULT] === null || keyObj[PROPS.DEFAULT] === 'NULL' || keyObj[PROPS.DEFAULT] === 'null')) {\n          keyErr.push(`${VALIDATION_MESSAGES.INVALID_DEFAULT_PROP_VALUE}`);\n        }\n\n        // Validate `relType` field attribute value.\n        if (keyObj[PROPS.RELATION_TYPE] && _.includes(allowProps, PROPS.RELATION_TYPE)) {\n          if (!_.includes([RELATIONS_TYPES.HAS_ONE, RELATIONS_TYPES.HAS_MANY], keyObj[PROPS.RELATION_TYPE])) {\n            keyErr.push(`${VALIDATION_MESSAGES.INVALID_RELATION_TYPE_VAL}`);\n          }\n        }\n\n        // Do not allow `default` as NULL, for below dataTypes.\n        if (_.includes(notNullDataTypes, TYPE) && (keyObj[PROPS.DEFAULT] === null || keyObj[PROPS.DEFAULT] === 'NULL' || keyObj[PROPS.DEFAULT] === 'null')) {\n          keyErr.push(`${VALIDATION_MESSAGES.INVALID_DEFAULT_PROP_VALUE}`);\n        }\n      } else {\n        // Invalid type property.\n        keyErr.push(`${VALIDATION_MESSAGES.INVALID_TYPE_PROP}`);\n      }\n    } else {\n      // Missing type property.\n      keyErr.push(`${VALIDATION_MESSAGES.MISSING_TYPE_PROP}`);\n    }\n\n    if (keyErr && keyErr.length > 0) {\n      errors.push({\n        modelName: model.modelName,\n        attribute: keys[i],\n        error: keyErr,\n      });\n    }\n  }\n  model.schemaJson = _.cloneDeep(schemaJson);\n  return {\n    errors,\n    model,\n  };\n};\nmodule.exports = validateDataTypes;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/staticData.js",
    "content": "/* global _ */\nconst { DEFAULT_POLICY_NAME } = require('../../../models/constants/application');\nconst { ORM_TYPE } = require('../../../models/constants/applicationConfig');\nconst DATA_TYPES = require('../../../constants/dataTypes/dataTypes');\nconst { PROPS } = require('../../../constants/dataTypes/props');\nconst mongoDB = require('../../../constants/schema');\nconst {\n  DEFAULT_TABLE_NAME, DEFAULT_FIELDS, RELATIONS_TYPES,\n} = require('../../../constants/schema');\n\nconst getAdditionalJsonAuthPlatform = () => {\n  const additionalJson = {\n    additionalSetting: {\n      admin: {\n        C: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        R: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        U: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        D: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BC: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BU: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n      },\n      device: {\n        C: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        R: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        U: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        D: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BC: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BU: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n      },\n      client: {\n        C: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        R: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        U: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        D: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BC: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BU: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n      },\n      desktop: {\n        C: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        R: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        U: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        D: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BC: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n        BU: {\n          selected: true,\n          policy: [DEFAULT_POLICY_NAME],\n          isAuth: true,\n          attributes: [],\n        },\n      },\n    },\n  };\n\n  return additionalJson;\n};\n\nconst getAdditionalJsonAuthOptions = () => {\n  const additionalJsonOptions = {\n    C: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n    R: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n    U: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n    D: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n    BC: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n    BU: {\n      selected: true,\n      policy: [DEFAULT_POLICY_NAME],\n      isAuth: true,\n      attributes: [],\n    },\n  };\n\n  return additionalJsonOptions;\n};\n\nconst getAdditionalJsonWithoutAuthOptions = () => {\n  const additionalJsonOptions = {\n    C: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n    R: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n    U: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n    D: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n    BC: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n    BU: {\n      selected: true,\n      policy: [],\n      attributes: [],\n    },\n  };\n\n  return additionalJsonOptions;\n};\n\nconst schemaJsonAuthPlatform = () => {\n  const schemaJson = {\n    admin: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n      {\n        isAuth: true,\n        policy: [DEFAULT_POLICY_NAME],\n      },\n    ],\n    device: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n      {\n        isAuth: true,\n        policy: [DEFAULT_POLICY_NAME],\n      },\n    ],\n    client: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n      {\n        isAuth: true,\n        policy: [DEFAULT_POLICY_NAME],\n      },\n    ],\n    desktop: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n      {\n        isAuth: true,\n        policy: [DEFAULT_POLICY_NAME],\n      },\n    ],\n  };\n\n  return schemaJson;\n};\n\nconst schemaJsonWithoutAuthPlatform = () => {\n  const schemaJson = {\n    admin: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n    ],\n    device: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n    ],\n    client: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n    ],\n    desktop: [\n      'C',\n      'R',\n      'U',\n      'D',\n      'BC',\n      'BU',\n    ],\n  };\n\n  return schemaJson;\n};\n\nconst schemaJsonAuthOptions = () => {\n  const authOptions = [\n    'C',\n    'R',\n    'U',\n    'D',\n    'BC',\n    'BU',\n    {\n      isAuth: true,\n      policy: [DEFAULT_POLICY_NAME],\n    },\n  ];\n  return authOptions;\n};\n\nconst schemaJsonOptions = () => {\n  const options = [\n    'C',\n    'R',\n    'U',\n    'D',\n    'BC',\n    'BU',\n  ];\n  return options;\n};\n\n/**\n * Static fields for `SEQUELIZE`.\n */\nconst getDefaultFieldsForSequelize = ({ ormType }) => {\n  const relationType = {};\n  relationType.type = DATA_TYPES.INTEGER.VALUE;\n  relationType[PROPS.REF] = DEFAULT_TABLE_NAME;\n  relationType[PROPS.REF_ATTR] = DEFAULT_FIELDS.ID;\n\n  const idType = {};\n  idType.type = DATA_TYPES.INTEGER.VALUE;\n  idType[PROPS.IS_AUTO_INCREMENT] = true;\n  idType[PROPS.PRIMARY] = true;\n\n  let fields = {};\n  fields = {\n    id: idType,\n    isActive: { type: DATA_TYPES.BOOLEAN.VALUE },\n    createdAt: { type: DATA_TYPES.DATE.VALUE },\n    updatedAt: { type: DATA_TYPES.DATE.VALUE },\n  };\n\n  if (ormType && ormType === ORM_TYPE.ELOQUENT) {\n    if (relationType?.ref) {\n      relationType.ref = _.capitalize(relationType.ref);\n    }\n    if (relationType?.type) {\n      relationType.type = DATA_TYPES.UnsignedBigInt.VALUE;\n    }\n    relationType[PROPS.RELATION_TYPE] = RELATIONS_TYPES.HAS_ONE;\n    idType.type = DATA_TYPES.UnsignedBigInt.VALUE;\n    fields = {\n      id: idType,\n      is_active: { type: DATA_TYPES.BOOLEAN.VALUE },\n      created_at: { type: DATA_TYPES.TIMESTAMP.VALUE },\n      updated_at: { type: DATA_TYPES.TIMESTAMP.VALUE },\n      added_by: relationType,\n      updated_by: relationType,\n    };\n    fields.is_active[PROPS.DEFAULT] = true;\n  }\n\n  return fields;\n};\n\n/**\n * Static fields for `MongoDB`.\n */\nconst getDefaultFieldsForMongoDB = () => {\n  const relationType = {};\n  relationType.type = mongoDB.DATA_TYPES.OBJECTID.value;\n  relationType.ref = DEFAULT_TABLE_NAME;\n\n  const fields = {\n    _id: { type: mongoDB.DATA_TYPES.STRING.value },\n    isActive: { type: mongoDB.DATA_TYPES.BOOLEAN.value },\n    createdAt: { type: mongoDB.DATA_TYPES.DATE.value },\n    updatedAt: { type: mongoDB.DATA_TYPES.DATE.value },\n  };\n\n  return fields;\n};\n\n/**\n * Function used to re-order schemaJson keys.\n * @param  {} schemaJson\n */\nasync function reOrderSchemaJson (schemaJson) {\n  const newSchemaJson = {};\n  if (schemaJson?.id) {\n    newSchemaJson.id = schemaJson?.id;\n  }\n  if (schemaJson?._id) {\n    newSchemaJson._id = schemaJson?._id;\n  }\n  Object.keys(schemaJson).forEach((key) => {\n    if (key !== '_id' && key !== 'id') {\n      newSchemaJson[key] = _.cloneDeep(schemaJson[key]);\n    }\n  });\n\n  return newSchemaJson;\n}\n\nmodule.exports = {\n  getAdditionalJsonAuthPlatform,\n  getAdditionalJsonAuthOptions,\n  getAdditionalJsonWithoutAuthOptions,\n  schemaJsonAuthPlatform,\n  schemaJsonWithoutAuthPlatform,\n  getDefaultFieldsForSequelize,\n  getDefaultFieldsForMongoDB,\n  schemaJsonAuthOptions,\n  schemaJsonOptions,\n  reOrderSchemaJson,\n};\n"
  },
  {
    "path": "packages/server/usecase/schema/util/updateSchemaRefAttribute.js",
    "content": "/* global  _ */\nconst { PROPS } = require('../../../constants/dataTypes/props');\nconst {\n  SERVER_ERROR, OK,\n} = require('../../../constants/message').message;\n\nconst updateSchemaRefAttribute = async ({\n  schemaRepo, schemaParams,\n}) => {\n  try {\n    const {\n      dependencySetting, updatedName,\n    } = schemaParams;\n    const schemaFilter = { find: { applicationId: schemaParams.applicationId } };\n    const schemas = await schemaRepo.getDetails(schemaFilter);\n    if (schemas && schemas.length) {\n      for (let i = 0; i < schemas.length; i += 1) {\n        const schema = schemas[i];\n        if (schema?.schemaJson) {\n          _.each(schema.schemaJson, (val, key) => {\n            if (schema.schemaJson[key] && schema.schemaJson[key][PROPS.REF] && schema.schemaJson[key][PROPS.REF].toUpperCase() === schemaParams.oldName.toUpperCase()) {\n              schema.schemaJson[key][PROPS.REF] = updatedName;\n            }\n            // refAttribute key.\n            if (schema?.schemaJson[key] && schema?.schemaJson[key][PROPS.REF_ATTR]) {\n              const attrName = schema?.schemaJson[key][PROPS.REF_ATTR];\n              const dependentKey = _.find(dependencySetting, { oldKey: attrName });\n              if (dependentKey?.newKey && !dependentKey.parentKey && !dependentKey?.isDelete) {\n                schema.schemaJson[key][PROPS.REF_ATTR] = _.cloneDeep(dependentKey.newKey);\n              } else if (dependentKey?.isDelete) {\n                delete schema.schemaJson[key][PROPS.REF_ATTR];\n              }\n            }\n            // foreignField key.\n            if (schema?.schemaJson[key] && schema?.schemaJson[key][PROPS.REF]\n              && schema?.schemaJson[key][PROPS.FOREIGN_FIELD]\n              && updatedName === schema.schemaJson[key][PROPS.REF]) {\n              const dependentKey = _.find(dependencySetting, { oldKey: schema.schemaJson[key][PROPS.FOREIGN_FIELD] });\n              if (dependentKey?.newKey && !dependentKey.parentKey && !dependentKey?.isDelete) {\n                schema.schemaJson[key][PROPS.FOREIGN_FIELD] = _.cloneDeep(dependentKey.newKey);\n              } else if (dependentKey?.isDelete) {\n                delete schema.schemaJson[key][PROPS.FOREIGN_FIELD];\n              }\n            }\n            // localField key.\n            if (schema?.schemaJson[key] && schema?.schemaJson[key][PROPS.LOCAL_FIELD]) {\n              const dependentKey = _.find(dependencySetting, { oldKey: schema.schemaJson[key][PROPS.LOCAL_FIELD] });\n              if (dependentKey?.newKey && !dependentKey.parentKey && !dependentKey?.isDelete) {\n                schema.schemaJson[key][PROPS.LOCAL_FIELD] = _.cloneDeep(dependentKey.newKey);\n              } else if (dependentKey?.isDelete) {\n                delete schema.schemaJson[key][PROPS.LOCAL_FIELD];\n              }\n            }\n\n            // JSON type attribute.\n            if (_.isObject(schema.schemaJson[key]) && !_.isArray(schema.schemaJson[key])) {\n              _.each(schema.schemaJson[key], (jsonVal, jsonKey) => {\n                if (schema.schemaJson[key] && schema.schemaJson[key][jsonKey] && schema.schemaJson[key][jsonKey][PROPS.REF]\n                  && schema.schemaJson[key][jsonKey][PROPS.REF].toUpperCase() === schemaParams.oldName.toUpperCase()) {\n                  schema.schemaJson[key][jsonKey][PROPS.REF] = updatedName;\n                }\n              });\n            }\n            // Array type attribute.\n            if (_.isArray(schema.schemaJson[key])) {\n              const arraySchema = _.cloneDeep(schema.schemaJson[key][0]);\n              if (arraySchema) {\n                _.each(arraySchema, (jsonVal, jsonKey) => {\n                  if (arraySchema[jsonKey] && arraySchema[jsonKey][PROPS.REF] && arraySchema[jsonKey][PROPS.REF].toUpperCase() === schemaParams.oldName.toUpperCase()) {\n                    arraySchema[jsonKey][PROPS.REF] = updatedName;\n                  }\n                });\n              }\n              schema.schemaJson[key] = [arraySchema];\n            }\n          });\n\n          const schemaUpdateData = { schemaJson: schema.schemaJson };\n          // eslint-disable-next-line no-await-in-loop\n          await schemaRepo.update(schema._id, schemaUpdateData);\n        }\n      }\n    }\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n};\n\nmodule.exports = updateSchemaRefAttribute;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/updateSchemaReferences.js",
    "content": "/* global _ */\nconst { ROUTE_GENERATE_TYPE } = require('../../../models/constants/project');\n\nconst {\n  OK, SERVER_ERROR,\n} = require('../../../constants/message').message;\n\nconst ProjectRouteRepository = require('../../../repo/projectRoute');\nconst QueryBuilderRepository = require('../../../repo/queryBuilder');\nconst NestedQueryBuilderRepository = require('../../../repo/nestedQueryBuilder');\nconst ApplicationConfigRepository = require('../../../repo/applicationConfig');\n\nconst projectRouteRepo = new ProjectRouteRepository();\nconst queryBuilderRepo = new QueryBuilderRepository();\nconst nestedQueryBuilderRepo = new NestedQueryBuilderRepository();\nconst applicationConfigRepo = new ApplicationConfigRepository();\n\n/**\n * Function used to update schema related details in `project-route`.\n * @param  {} {updatedSchema\n * @param  {} }\n */\nasync function updateProjectRoute ({\n  oldSchema, updatedSchema,\n}) {\n  try {\n    const filter = {\n      find: {\n        applicationId: updatedSchema.applicationId,\n        modelId: updatedSchema._id,\n      },\n    };\n    const routeData = await projectRouteRepo.getDetails(filter);\n    if (routeData && routeData.length > 0) {\n      await Promise.all(routeData.map(async (route) => {\n        const updateData = {};\n        if (route.type === ROUTE_GENERATE_TYPE.AUTO) {\n          const updateRoute = route.route.replace(oldSchema.name.toLowerCase(), updatedSchema.name.toLowerCase());\n          updateData.route = updateRoute;\n        }\n        updateData.groupName = updatedSchema.name;\n        await projectRouteRepo.update(route._id, updateData);\n      }));\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to update schema related details in `query-builder`.\n * @param  {} {updatedSchema\n * @param  {} }\n */\nasync function updateQueryBuilder ({ updatedSchema }) {\n  try {\n    const filter = {\n      find: {\n        applicationId: updatedSchema.applicationId,\n        modelId: updatedSchema._id,\n      },\n    };\n    const queryBuilderData = await queryBuilderRepo.getDetails(filter);\n    if (queryBuilderData && queryBuilderData.length > 0) {\n      const ids = _.map(queryBuilderData, '_id');\n      const updateFilter = {\n        filter: { find: { _id: ids } },\n        data: { model: updatedSchema.name },\n      };\n      await queryBuilderRepo.updateMany(updateFilter);\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to update schema related details in `nested-query-builder`.\n * @param  {} {updatedSchema\n * @param  {} }\n */\nasync function updateNestedQueryBuilder ({ updatedSchema }) {\n  try {\n    const filter = {\n      find: {\n        applicationId: updatedSchema.applicationId,\n        modelId: updatedSchema._id,\n      },\n    };\n    const nQueryBuilderData = await nestedQueryBuilderRepo.getDetails(filter);\n    if (nQueryBuilderData && nQueryBuilderData.length > 0) {\n      const ids = _.map(nQueryBuilderData, '_id');\n      const updateFilter = {\n        filter: { find: { _id: ids } },\n        data: { model: updatedSchema.name },\n      };\n      await nestedQueryBuilderRepo.updateMany(updateFilter);\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\n/**\n * Function used to update schema related details in `application-config`.\n * @param  {} {updatedSchema\n * @param  {} }\n */\nasync function updateApplicationConfig ({ updatedSchema }) {\n  try {\n    const appConfigFilter = {\n      find: {\n        applicationId: updatedSchema.applicationId,\n        authModuleId: updatedSchema._id,\n      },\n    };\n    const appConfig = await applicationConfigRepo.get(appConfigFilter);\n    if (appConfig) {\n      const appConfigUpdateData = { authModule: updatedSchema.name };\n      await applicationConfigRepo.update(appConfig._id, appConfigUpdateData);\n    }\n    return OK;\n  } catch (err) {\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n}\n\nconst updateSchemaReferences = async ({\n  oldSchema, updatedSchema,\n}) => {\n  try {\n    // Update model reference in `Project-Route`.\n    const routeRes = await updateProjectRoute({\n      oldSchema,\n      updatedSchema,\n    });\n    if (routeRes?.code !== OK.code) {\n      throw new Error(routeRes.data);\n    }\n\n    // Update model reference in `Query-Builder`.\n    const queryBuilderRes = await updateQueryBuilder({ updatedSchema });\n    if (queryBuilderRes?.code !== OK.code) {\n      throw new Error(queryBuilderRes.data);\n    }\n\n    // Update model reference in `Nested-Query-Builder`.\n    const nQueryBuilderRes = await updateNestedQueryBuilder({ updatedSchema });\n    if (nQueryBuilderRes?.code !== OK.code) {\n      throw new Error(nQueryBuilderRes.data);\n    }\n\n    // Update model reference in `Application-Config`.\n    const appConfigRes = await updateApplicationConfig({ updatedSchema });\n    if (appConfigRes?.code !== OK.code) {\n      throw new Error(appConfigRes.data);\n    }\n\n    return OK;\n  } catch (err) {\n    // console.log('err: ', err);\n    return {\n      ...SERVER_ERROR,\n      data: err.toString(),\n    };\n  }\n};\n\nmodule.exports = updateSchemaReferences;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/validateProps.js",
    "content": "/* global _ */\nconst {\n  DATA_TYPES, DATA_TYPES_DEFAULT_PROPS, MONGOOSE_TYPES,\n} = require('../../../constants/schema');\n\nconst { VALIDATION_MESSAGES } = require('../../../constants/schema');\nconst isRegExp = require('./isRegExp');\n\n/**\n * Function used to make proper `schemaJson` `object`.\n * @param  {} jsonSchemaObj\n */\nasync function objSetAttribute (jsonSchemaObj, isJsonObj = false) {\n  const keys = _.keys(jsonSchemaObj);\n\n  /**\n   * ------------------------------------------\n   * Convert minlength & maxlength properties AND convert mongoDB types to ObjectId.\n   * ------------------------------------------\n   */\n  Object.keys(jsonSchemaObj).forEach((val) => {\n    if (jsonSchemaObj[val].minlength) {\n      jsonSchemaObj[val].minLength = _.cloneDeep(jsonSchemaObj[val].minlength);\n      delete jsonSchemaObj[val].minlength;\n    }\n    if (jsonSchemaObj[val].maxlength) {\n      jsonSchemaObj[val].maxLength = _.cloneDeep(jsonSchemaObj[val].maxlength);\n      delete jsonSchemaObj[val].maxlength;\n    }\n    if (typeof jsonSchemaObj[val] === 'string'\n        && (_.includes(MONGOOSE_TYPES, jsonSchemaObj[val].toLowerCase()))) {\n      jsonSchemaObj[val] = DATA_TYPES.OBJECTID.value;\n    }\n\n    if (typeof jsonSchemaObj[val] === 'object' && jsonSchemaObj[val].type\n    && (_.includes(MONGOOSE_TYPES, jsonSchemaObj[val].type.toLowerCase()))) {\n      jsonSchemaObj[val].type = DATA_TYPES.OBJECTID.value;\n    }\n  });\n  // ------------------------------------------\n\n  const keyCnt = _.size(jsonSchemaObj);\n  if (!isJsonObj && keyCnt === 1 && jsonSchemaObj.type && DATA_TYPES[jsonSchemaObj.type.toUpperCase()]\n  && DATA_TYPES[jsonSchemaObj.type.toUpperCase()].value.toUpperCase() === jsonSchemaObj.type.toUpperCase()) {\n    return jsonSchemaObj;\n  }\n\n  const jsonSchemaObjCpy = _.cloneDeep(jsonSchemaObj);\n  for (let j = 0; j < keys.length; j += 1) {\n    const key = keys[j];\n    if (typeof jsonSchemaObjCpy[key] === 'string' && DATA_TYPES[jsonSchemaObjCpy[key].toUpperCase()]?.value) {\n      jsonSchemaObjCpy[key] = { type: DATA_TYPES[jsonSchemaObjCpy[key].toUpperCase()].value };\n    } else if (typeof jsonSchemaObjCpy[key] === 'string') {\n      jsonSchemaObjCpy[key] = { type: jsonSchemaObjCpy[key] };\n    }\n  }\n\n  let isObj = true;\n  _.each(jsonSchemaObjCpy, (val) => {\n    if (typeof val !== 'object') {\n      isObj = false;\n    }\n  });\n\n  let jsonResponse = {};\n  if (!isObj) {\n    jsonResponse = _.cloneDeep(jsonSchemaObj);\n  } else {\n    jsonResponse = _.cloneDeep(jsonSchemaObjCpy);\n  }\n\n  return jsonResponse;\n}\n\n/**\n * Function used make proper `schemaJson`.\n * @param  {} jsonData\n */\nasync function setAttribute (jsonData) {\n  for (let k = 0; k < jsonData.length; k += 1) {\n    const jsonSchemaObj = jsonData[k].schemaJson;\n\n    const keys = _.keys(jsonSchemaObj);\n    for (let i = 0; i < keys.length; i += 1) {\n      const objKey = keys[i];\n\n      /**\n       * ------------------------------------------\n       * Convert minlength & maxlength properties.\n       * ------------------------------------------\n       */\n      if (jsonSchemaObj[objKey].minlength) {\n        jsonSchemaObj[objKey].minLength = _.cloneDeep(jsonSchemaObj[objKey].minlength);\n        delete jsonSchemaObj[objKey].minlength;\n      }\n      if (jsonSchemaObj[objKey].maxlength) {\n        jsonSchemaObj[objKey].maxLength = _.cloneDeep(jsonSchemaObj[objKey].maxlength);\n        delete jsonSchemaObj[objKey].maxlength;\n      }\n      // ------------------------------------------\n\n      /**\n       * ------------------------------------------\n       * Convert mongoDB types to `ObjectId`.\n       * ------------------------------------------\n       */\n      if (typeof jsonSchemaObj[objKey] === 'string'\n          && (_.includes(MONGOOSE_TYPES, jsonSchemaObj[objKey].toLowerCase()))) {\n        jsonSchemaObj[objKey] = DATA_TYPES.OBJECTID.value;\n      }\n\n      if (typeof jsonSchemaObj[objKey] === 'object' && jsonSchemaObj[objKey].type && typeof jsonSchemaObj[objKey].type === 'string') {\n        if (_.includes(MONGOOSE_TYPES, jsonSchemaObj[objKey].type.toLowerCase())) {\n          jsonSchemaObj[objKey].type = DATA_TYPES.OBJECTID.value;\n        }\n      }\n      // ------------------------------------------\n\n      if (typeof jsonSchemaObj[objKey] === 'string') {\n        if (DATA_TYPES[jsonSchemaObj[objKey].toUpperCase()] && DATA_TYPES[jsonSchemaObj[objKey].toUpperCase()].value) {\n          jsonSchemaObj[objKey] = { type: DATA_TYPES[jsonSchemaObj[objKey].toUpperCase()].value };\n        } else {\n          jsonSchemaObj[objKey] = { type: jsonSchemaObj[objKey] };\n        }\n      } else if (\n        (typeof jsonSchemaObj[objKey] === 'object' && !_.isArray(jsonSchemaObj[objKey]) && !jsonSchemaObj[objKey].type)\n        || (jsonSchemaObj[objKey]?.type\n        && (typeof jsonSchemaObj[objKey].type === 'string' && jsonSchemaObj[objKey].type.toUpperCase() === 'JSON' && !_.isArray(jsonSchemaObj[objKey].description)))) {\n        if (jsonSchemaObj[objKey].description) {\n        // eslint-disable-next-line no-await-in-loop\n          jsonSchemaObj[objKey].description = await objSetAttribute(jsonSchemaObj[objKey].description, true);\n        } else {\n        // eslint-disable-next-line no-await-in-loop\n          jsonSchemaObj[objKey] = await objSetAttribute(jsonSchemaObj[objKey]);\n        }\n      } else if (\n        (_.isArray(jsonSchemaObj[objKey]))\n      || (jsonSchemaObj[objKey]?.type && (typeof jsonSchemaObj[objKey].type === 'string'\n      && jsonSchemaObj[objKey].type.toUpperCase() === 'ARRAY' && jsonSchemaObj[objKey].description && jsonSchemaObj[objKey].description.length > 0))) {\n        if (jsonSchemaObj[objKey].description && jsonSchemaObj[objKey].description.length > 0) {\n        // eslint-disable-next-line no-await-in-loop\n          const arrayObj = await objSetAttribute(jsonSchemaObj[objKey].description[0], true);\n          jsonSchemaObj[objKey].description = [arrayObj];\n        } else {\n        // eslint-disable-next-line no-await-in-loop\n          const arrayObj = await objSetAttribute(jsonSchemaObj[objKey][0], true);\n          jsonSchemaObj[objKey] = [arrayObj];\n        }\n      }\n    }\n    jsonData[k].schemaJson = jsonSchemaObj;\n  }\n  return jsonData;\n}\n\n/**\n * Function used to validate schema properties.\n * @param  {} jsonDetails\n */\nconst validateProps = async (jsonDetails) => {\n  const allFieldTypes = DATA_TYPES;\n  const defaultProps = DATA_TYPES_DEFAULT_PROPS;\n  const attErrors = [];\n  // Validate property\n  jsonDetails = await setAttribute(jsonDetails);\n  _.each(jsonDetails, async (json) => {\n    Object.keys(json.schemaJson).forEach(async (key) => {\n      if (json.schemaJson && json.schemaJson[key] && typeof json.schemaJson[key].type === 'string' && json.schemaJson[key].type\n      && !_.includes(['JSON', 'ARRAY'], json.schemaJson[key].type.toUpperCase())) {\n        const typeKey = json.schemaJson[key].type.toUpperCase();\n        const allowProps = allFieldTypes[typeKey];\n\n        if (typeKey === 'JSON' && typeKey === 'ARRAY') {\n          json.schemaJson[key].type = _.cloneDeep(allowProps.value);\n        } else if (allowProps && allowProps.attributes) {\n          const aProps = _.compact(_.uniq([...defaultProps, ...allowProps.attributes]));\n\n          let appliedProps = Object.keys(json.schemaJson[key]);\n          appliedProps = _.cloneDeep(_.compact(_.remove(appliedProps, (v) => {\n            if (v === 'type') {\n              return '';\n            }\n            return v;\n          })));\n\n          const keyErr = [];\n          if (!_.isEmpty(appliedProps)) {\n            _.each(appliedProps, (prop) => {\n              if (!_.includes(aProps, prop)) {\n                keyErr.push(`Property not allowed - ${prop}.`);\n              }\n            });\n          }\n\n          // Validate RegExp.\n          if (json?.schemaJson[key]?.match) {\n            const match = isRegExp(json.schemaJson[key].match);\n            if (!match) {\n              keyErr.push(`${key} - Invalid regular expression - ${json.schemaJson[key].match}`);\n            }\n          }\n\n          json.schemaJson[key].type = _.cloneDeep(allowProps.value);\n          /**\n           * -----------------------------------------------\n           * Check properties of virtual-relation.\n           * -----------------------------------------------\n           */\n          if (typeKey === 'VIRTUAL_RELATION') {\n            if (!_.includes(appliedProps, 'ref')) {\n              keyErr.push(VALIDATION_MESSAGES.MISSING_REF_PROPS);\n            }\n            if (!_.includes(appliedProps, 'localField')) {\n              keyErr.push(VALIDATION_MESSAGES.MISSING_LOCAL_FIELD_PROPS);\n            }\n            if (!_.includes(appliedProps, 'foreignField')) {\n              keyErr.push(VALIDATION_MESSAGES.MISSING_FOREIGN_FIELD_PROPS);\n            }\n          }\n          //-----------------------------------------------\n\n          /**\n           * -----------------------------------------------\n           * Validate Min-Max property.\n           * -----------------------------------------------\n           */\n          if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'max')) {\n            if (json.schemaJson[key].min > json.schemaJson[key].max) {\n              keyErr.push(VALIDATION_MESSAGES.MAX_MUST_GREATER_TO_MIN);\n            }\n          }\n\n          if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'default')) {\n            if (json.schemaJson[key].default < json.schemaJson[key].min) {\n              keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_GREATER_OR_EQUAL_TO_MIN);\n            }\n          }\n\n          if (_.includes(appliedProps, 'max') && _.includes(appliedProps, 'default')) {\n            if (json.schemaJson[key].default > json.schemaJson[key].max) {\n              keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_LOWER_OR_EQUAL_TO_MAX);\n            }\n          }\n          //-----------------------------------------------\n\n          /**\n           * -----------------------------------------------\n           * Validate minLength-maxLength property.\n           * -----------------------------------------------\n           */\n          if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'maxLength')) {\n            if (json.schemaJson[key].minLength > json.schemaJson[key].maxLength) {\n              keyErr.push(VALIDATION_MESSAGES.MAX_LENGTH_MUST_GREATER_TO_MIN_LENGTH);\n            }\n          }\n\n          if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'default')) {\n            if (json.schemaJson[key].default < json.schemaJson[key].minLength) {\n              keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_GREATER_OR_EQUAL_TO_MIN_LENGTH);\n            }\n          }\n\n          if (_.includes(appliedProps, 'maxLength') && _.includes(appliedProps, 'default')) {\n            if (json.schemaJson[key].default > json.schemaJson[key].maxLength) {\n              keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_LOWER_OR_EQUAL_TO_MAX_LENGTH);\n            }\n          }\n          //-----------------------------------------------\n\n          // Do not allow `NULL` value in `default` prop, when field contain `required` property.\n          if (json.schemaJson[key].required && (json.schemaJson[key].default === null || json.schemaJson[key].default === 'NULL' || json.schemaJson[key].default === 'null')) {\n            keyErr.push(`${VALIDATION_MESSAGES.INVALID_DEFAULT_PROP_VALUE}`);\n          }\n\n          if (keyErr && _.size(keyErr) > 0) {\n            attErrors.push({\n              modelName: json.modelName,\n              attribute: key,\n              error: keyErr,\n            });\n          }\n        } else {\n          attErrors.push({\n            modelName: json.modelName,\n            attribute: key,\n            error: [VALIDATION_MESSAGES.INVALID_TYPE_PROP],\n          });\n        }\n      } else if (_.isObject(json.schemaJson[key]) || _.isArray(json.schemaJson[key])) {\n        // Check validation for `JSON` Object.\n        if ((!json.schemaJson[key].type && _.isObject(json.schemaJson[key]) && !_.isArray(json.schemaJson[key]))\n          || (json.schemaJson[key].type\n            && ((typeof json.schemaJson[key].type === 'string' && json.schemaJson[key].type.toUpperCase() === 'JSON'\n            && json.schemaJson[key].description && !_.isArray(json.schemaJson[key].description))\n              || (typeof json.schemaJson[key].type === 'object')))) {\n          let jsonObj = json.schemaJson[key];\n          if (json.schemaJson[key].description && json.schemaJson[key].type && typeof json.schemaJson[key].type === 'string' && json.schemaJson[key].type.toUpperCase() === 'JSON') {\n            jsonObj = json.schemaJson[key].description;\n          }\n\n          Object.keys(jsonObj).forEach((key1) => {\n            const nestedJsonKey = jsonObj[key1];\n            if (!nestedJsonKey.type) {\n              attErrors.push({\n                modelName: json.modelName,\n                attribute: `${key}.${key1}`,\n                error: [VALIDATION_MESSAGES.MISSING_TYPE_PROP],\n              });\n            } else {\n              const typeKey = nestedJsonKey.type.toUpperCase();\n              const allowProps = allFieldTypes[typeKey];\n              if (allowProps && allowProps.attributes) {\n                const aProps = _.compact(_.uniq([...defaultProps, ...allowProps.attributes]));\n                let appliedProps = Object.keys(jsonObj[key1]);\n                appliedProps = _.cloneDeep(_.compact(_.remove(appliedProps, (v) => {\n                  if (v === 'type' || v === 'description') {\n                    return '';\n                  }\n                  return v;\n                })));\n\n                const keyErr = [];\n                if (!_.isEmpty(appliedProps)) {\n                  _.each(appliedProps, (prop) => {\n                    if (!_.includes(aProps, prop)) {\n                      keyErr.push(`Property not allowed - ${prop}.`);\n                    }\n                  });\n                }\n\n                // Validate RegExp\n                if (jsonObj[key1]?.match) {\n                  const match = isRegExp(jsonObj[key1].match);\n                  if (!match) {\n                    keyErr.push(`${key}.${key1} - Invalid regular expression - ${jsonObj[key1].match}`);\n                  }\n                }\n\n                jsonObj[key1].type = _.cloneDeep(allowProps.value);\n                json.schemaJson[key] = _.cloneDeep(jsonObj);\n\n                /**\n                 * -----------------------------------------------\n                 * Check properties of virtual-relation.\n                 * -----------------------------------------------\n                 */\n                if (typeKey === 'VIRTUAL_RELATION') {\n                  if (!_.includes(appliedProps, 'ref')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_REF_PROPS);\n                  }\n                  if (!_.includes(appliedProps, 'localField')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_LOCAL_FIELD_PROPS);\n                  }\n                  if (!_.includes(appliedProps, 'foreignField')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_FOREIGN_FIELD_PROPS);\n                  }\n                }\n                //-----------------------------------------------\n\n                /**\n                 * -----------------------------------------------\n                 * Validate Min-Max property.\n                 * -----------------------------------------------\n                 */\n                if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'max')) {\n                  if (jsonObj[key1].min > jsonObj[key1].max) {\n                    keyErr.push(VALIDATION_MESSAGES.MAX_MUST_GREATER_TO_MIN);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'default')) {\n                  if (jsonObj[key1].default < jsonObj[key1].min) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_GREATER_OR_EQUAL_TO_MIN);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'max') && _.includes(appliedProps, 'default')) {\n                  if (jsonObj[key1].default > jsonObj[key1].max) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_LOWER_OR_EQUAL_TO_MAX);\n                  }\n                }\n                //-----------------------------------------------\n\n                /**\n                 * -----------------------------------------------\n                 * Validate minLength-maxLength property.\n                 * -----------------------------------------------\n                 */\n                if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'maxLength')) {\n                  if (jsonObj[key1].minLength > jsonObj[key1].maxLength) {\n                    keyErr.push(VALIDATION_MESSAGES.MAX_LENGTH_MUST_GREATER_TO_MIN_LENGTH);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'default')) {\n                  if (jsonObj[key1].default < jsonObj[key1].minLength) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_GREATER_OR_EQUAL_TO_MIN_LENGTH);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'maxLength') && _.includes(appliedProps, 'default')) {\n                  if (jsonObj[key1].default > jsonObj[key1].maxLength) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_LOWER_OR_EQUAL_TO_MAX_LENGTH);\n                  }\n                }\n                //-----------------------------------------------\n\n                // Do not allow `NULL` value in `default` prop, when field contain `required` property.\n                if (jsonObj[key1].required && (jsonObj[key1].default === null || jsonObj[key1].default === 'NULL' || jsonObj[key1].default === 'null')) {\n                  keyErr.push(`${VALIDATION_MESSAGES.INVALID_DEFAULT_PROP_VALUE}`);\n                }\n\n                if (keyErr && _.size(keyErr) > 0) {\n                  attErrors.push({\n                    modelName: json.modelName,\n                    attribute: `${key}.${key1}`,\n                    error: keyErr,\n                  });\n                }\n              } else {\n                attErrors.push({\n                  modelName: json.modelName,\n                  attribute: `${key}.${key1}`,\n                  error: [VALIDATION_MESSAGES.INVALID_TYPE_PROP],\n                });\n              }\n            }\n          });\n        }\n\n        // Check validation for `ARRAY` Object.\n        if ((!json.schemaJson[key].type && _.isArray(json.schemaJson[key]))\n        || (json.schemaJson[key].type && typeof json.schemaJson[key].type === 'string'\n          && json.schemaJson[key].type.toUpperCase() === 'ARRAY' && json.schemaJson[key].description && _.isArray(json.schemaJson[key].description))) {\n          let jsonArr = json.schemaJson[key];\n          if (json.schemaJson[key].description && json.schemaJson[key].type && json.schemaJson[key].type.toUpperCase() === 'ARRAY') {\n            jsonArr = json.schemaJson[key].description;\n          }\n\n          if (jsonArr.length > 1) {\n            attErrors.push({\n              modelName: json.modelName,\n              attribute: `${key}`,\n              error: [VALIDATION_MESSAGES.ONLY_ZERO_INDEX_ALLOW],\n            });\n          }\n\n          const indexObj = jsonArr[0];\n          Object.keys(indexObj).forEach((key1) => {\n            const nestedJsonKey = indexObj[key1];\n            if (!nestedJsonKey.type && key1 !== '_id') {\n              attErrors.push({\n                modelName: json.modelName,\n                attribute: `${key}.${key1}`,\n                error: [VALIDATION_MESSAGES.MISSING_TYPE_PROP],\n              });\n            } else if (nestedJsonKey?.type) {\n              const typeKey = nestedJsonKey.type.toUpperCase();\n              const allowProps = allFieldTypes[typeKey];\n              if (allowProps && allowProps.attributes) {\n                const aProps = _.compact(_.uniq([...defaultProps, ...allowProps.attributes]));\n                let appliedProps = Object.keys(indexObj[key1]);\n                appliedProps = _.cloneDeep(_.compact(_.remove(appliedProps, (v) => {\n                  if (v === 'type' || v === 'description') {\n                    return '';\n                  }\n                  return v;\n                })));\n\n                const keyErr = [];\n                if (!_.isEmpty(appliedProps)) {\n                  _.each(appliedProps, (prop) => {\n                    if (!_.includes(aProps, prop)) {\n                      keyErr.push(`Property not allowed - ${prop}.`);\n                    }\n                  });\n                }\n\n                // Validate RegExp.\n                if (jsonArr[0][key1]?.match) {\n                  const match = isRegExp(jsonArr[0][key1].match);\n                  if (!match) {\n                    keyErr.push(`${key}.${key1} - Invalid regular expression - ${jsonArr[0][key1].match}`);\n                  }\n                }\n\n                jsonArr[0][key1].type = _.cloneDeep(allowProps.value);\n                json.schemaJson[key] = _.cloneDeep(jsonArr);\n\n                /**\n                 * -----------------------------------------------\n                 * Check properties of virtual-relation.\n                 * -----------------------------------------------\n                 */\n                if (typeKey === 'VIRTUAL_RELATION') {\n                  if (!_.includes(appliedProps, 'ref')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_REF_PROPS);\n                  }\n                  if (!_.includes(appliedProps, 'localField')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_LOCAL_FIELD_PROPS);\n                  }\n                  if (!_.includes(appliedProps, 'foreignField')) {\n                    keyErr.push(VALIDATION_MESSAGES.MISSING_FOREIGN_FIELD_PROPS);\n                  }\n                }\n                //-----------------------------------------------\n\n                /**\n                 * -----------------------------------------------\n                 * Validate Min-Max property.\n                 * -----------------------------------------------\n                 */\n                if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'max')) {\n                  if (indexObj[key1].min > indexObj[key1].max) {\n                    keyErr.push(VALIDATION_MESSAGES.MAX_MUST_GREATER_TO_MIN);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'min') && _.includes(appliedProps, 'default')) {\n                  if (indexObj[key1].default < indexObj[key1].min) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_GREATER_OR_EQUAL_TO_MIN);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'max') && _.includes(appliedProps, 'default')) {\n                  if (indexObj[key1].default > indexObj[key1].max) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_MUST_LOWER_OR_EQUAL_TO_MAX);\n                  }\n                }\n                //-----------------------------------------------\n\n                /**\n                 * -----------------------------------------------\n                 * Validate minLength-maxLength property.\n                 * -----------------------------------------------\n                 */\n                if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'maxLength')) {\n                  if (indexObj[key1].minLength > indexObj[key1].maxLength) {\n                    keyErr.push(VALIDATION_MESSAGES.MAX_LENGTH_MUST_GREATER_TO_MIN_LENGTH);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'minLength') && _.includes(appliedProps, 'default')) {\n                  if (indexObj[key1].default < indexObj[key1].minLength) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_GREATER_OR_EQUAL_TO_MIN_LENGTH);\n                  }\n                }\n\n                if (_.includes(appliedProps, 'maxLength') && _.includes(appliedProps, 'default')) {\n                  if (indexObj[key1].default > indexObj[key1].maxLength) {\n                    keyErr.push(VALIDATION_MESSAGES.DEFAULT_LENGTH_MUST_LOWER_OR_EQUAL_TO_MAX_LENGTH);\n                  }\n                }\n                //-----------------------------------------------\n\n                // Do not allow `NULL` value in `default` prop, when field contain `required` property.\n                if (indexObj[key1].required && (indexObj[key1].default === null || indexObj[key1].default === 'NULL' || indexObj[key1].default === 'null')) {\n                  keyErr.push(`${VALIDATION_MESSAGES.INVALID_DEFAULT_PROP_VALUE}`);\n                }\n\n                if (keyErr && _.size(keyErr) > 0) {\n                  attErrors.push({\n                    modelName: json.modelName,\n                    attribute: `${key}.${key1}`,\n                    error: keyErr,\n                  });\n                }\n              } else {\n                attErrors.push({\n                  modelName: json.modelName,\n                  attribute: `${key}.${key1}`,\n                  error: [VALIDATION_MESSAGES.INVALID_TYPE_PROP],\n                });\n              }\n            }\n          });\n        }\n      } else {\n        attErrors.push({\n          modelName: json.modelName,\n          attribute: key,\n          error: [VALIDATION_MESSAGES.MISSING_TYPE_PROP],\n        });\n      }\n    });\n  });\n\n  let models = _.map(jsonDetails, (val) => {\n    const errModel = _.find(attErrors, { modelName: val.modelName });\n    if (errModel) {\n      return {};\n    }\n    return val;\n  });\n  models = _.compact(_.reject(models, _.isEmpty));\n  return {\n    errors: attErrors,\n    jsonSchema: models,\n    originJson: jsonDetails,\n  };\n};\n\nmodule.exports = validateProps;\n"
  },
  {
    "path": "packages/server/usecase/schema/util/validateRegEx.js",
    "content": "/* global _ */\nconst {\n  OK, INVALID_REGEXP,\n} = require('../../../constants/message').message;\nconst isRegExp = require('./isRegExp');\n\n/**\n * Function used to validate regExp;\n * @param  {} key\n * @param  {} pattern\n */\nasync function isValidRegExp (key, pattern) {\n  try {\n    const match = isRegExp(pattern);\n    if (!match) {\n      return {\n        flag: false,\n        msg: `${key} - Invalid regular expression - ${pattern}`,\n      };\n    }\n    return { flag: true };\n  } catch (err) {\n    return {\n      flag: false,\n      msg: `${key} - Invalid regular expression - ${pattern}`,\n    };\n  }\n}\n\nconst validateRegEx = async (schemaJson) => {\n  const error = [];\n\n  const keys = _.keys(schemaJson);\n  for (let i = 0; i < keys.length; i += 1) {\n    const field = schemaJson[keys[i]];\n    if (typeof field === 'object' && field?.match) {\n      // eslint-disable-next-line no-await-in-loop\n      const validate = await isValidRegExp(keys[i], field.match);\n      if (!validate.flag) {\n        error.push(validate.msg);\n      }\n    }\n\n    // JSON type attribute.\n    if (_.isObject(field) && !_.isArray(field)) {\n      const jsonTypeKeys = _.keys(field);\n      for (let jKey = 0; jKey < jsonTypeKeys.length; jKey += 1) {\n        const jsonField = field[jsonTypeKeys[jKey]];\n        if (typeof jsonField === 'object' && jsonField?.match) {\n          // eslint-disable-next-line no-await-in-loop\n          const validate = await isValidRegExp(`${keys[i]}.${jsonTypeKeys[jKey]}`, jsonField.match);\n          if (!validate.flag) {\n            error.push(validate.msg);\n          }\n        }\n      }\n    }\n\n    // ARRAY type attribute.\n    if (_.isObject(field) && _.isArray(field)) {\n      if (field[0]) {\n        const jsonTypeKeys = _.keys(field[0]);\n        for (let jKey = 0; jKey < jsonTypeKeys.length; jKey += 1) {\n          const jsonField = field[0][jsonTypeKeys[jKey]];\n          if (typeof jsonField === 'object' && jsonField?.match) {\n          // eslint-disable-next-line no-await-in-loop\n            const validate = await isValidRegExp(`${keys[i]}.${jsonTypeKeys[jKey]}`, jsonField.match);\n            if (!validate.flag) {\n              error.push(validate.msg);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  if (error && error.length > 0) {\n    return {\n      ...INVALID_REGEXP,\n      data: error,\n    };\n  }\n\n  return OK;\n};\n\nmodule.exports = validateRegEx;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/create.js",
    "content": "/* global MESSAGE, */\nconst {\n  FAILED_TO_CREATE, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\nconst { schemaDetailCreateValidation } = require('../util/validation/schemaDetail');\n\n/**\n * Function used for create new user.\n * @return json\n */\nconst useCase = (schemaDetailRepo) => async (params) => {\n  try {\n    const {\n      value, error,\n    } = schemaDetailCreateValidation(params);\n    if (error) {\n      return {\n        data: null,\n        code: MESSAGE.BAD_REQUEST.code,\n        message: error,\n      };\n    }\n    params = value;\n    const created = await schemaDetailRepo.create(params);\n\n    if (!created) {\n      return FAILED_TO_CREATE;\n    }\n    return {\n      ...OK,\n      data: created,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = useCase;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/delete.js",
    "content": "const mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR,\n} = require('../../constants/message').message;\n\nconst deleteSchemaDetailUseCase = require('./deleteDependency');\n\nconst deleteById = (schemaDetailRepo) => async (params) => {\n  try {\n    if (!params.id) return INVALID_REQUEST_PARAMS;\n    const isValidId = mongoose.Types.ObjectId.isValid(params.id);\n    if (!isValidId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    const response = await (deleteSchemaDetailUseCase(schemaDetailRepo))({ find: { _id: params.id } }, params.isHardDelete);\n    return response;\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = deleteById;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/deleteDependency.js",
    "content": "const {\n  INVALID_REQUEST_PARAMS, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n// {  find: { schemaId: params.id } }\nconst deleteMany = (schemaDetailRepo) => async (filter, isHardDelete = false) => {\n  try {\n    if (!filter) return INVALID_REQUEST_PARAMS;\n    const response = await schemaDetailRepo.getDetails(filter);\n    if (response && response.length) {\n      if (isHardDelete) {\n        await schemaDetailRepo.deleteMany(filter);\n      } else {\n        const updateData = {\n          filter,\n          data: { isDeleted: true },\n        };\n        await schemaDetailRepo.updateMany(updateData);\n      }\n    }\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return SERVER_ERROR;\n  }\n};\n\nmodule.exports = deleteMany;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/paginate.js",
    "content": "/* global _ */\nconst mongoose = require('mongoose');\nconst {\n  INVALID_REQUEST_PARAMS, SCHEMA_NOT_FOUND, OK, SERVER_ERROR, APPLICATION_NOT_FOUND,\n} = require('../../constants/message').message;\n\nconst ApplicationRepository = require('../../repo/application');\n\nconst applicationRepo = new ApplicationRepository();\n\nconst paginate = (schemaDetailRepo, schemaRepo) => async (params) => {\n  try {\n    const filter = { find: {} };\n    if (!params.applicationId) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    if (params.applicationId) {\n      const isValidId = mongoose.Types.ObjectId.isValid(params.applicationId);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const applicationData = await applicationRepo.get({ find: { _id: params.applicationId } });\n\n    if (!applicationData) {\n      return APPLICATION_NOT_FOUND;\n    }\n\n    if (params.find) {\n      filter.find = params.find;\n    }\n\n    filter.find.applicationId = params.applicationId;\n    /*\n     * params = {\n     *     fields: \"\",\n     *     find: {},\n     *     page: 1,\n     *     limit: 1\n     * }\n     */\n    const schemas = await schemaRepo.getDetails(filter);\n    if (!schemas.length) {\n      return SCHEMA_NOT_FOUND;\n    }\n    const detailFilter = {\n      find: { schemaId: _.map(schemas, '_id') },\n      populate: [{ schemaId: ['name'] }],\n    };\n    /*\n     * if (params.schemaId) {\n     *   detailFilter.find.schemaId = params.schemaId;\n     * }\n     */\n    const listData = await schemaDetailRepo.getDetails(detailFilter);\n\n    if (applicationData?.configInput?.platform && listData && listData.length > 0) {\n      const { platform } = applicationData.configInput;\n\n      _.each(listData, (sJson) => {\n        _.map(platform, (val) => {\n          if (sJson?.schemaJson && !sJson.schemaJson[val]) {\n            sJson.schemaJson[val] = [{\n              isAuth: false,\n              policy: [],\n            }];\n          }\n\n          if (sJson?.additionalJson?.additionalSetting && !sJson.additionalJson.additionalSetting[val]) {\n            sJson.additionalJson.additionalSetting[val] = {};\n          }\n        });\n      });\n    }\n\n    const response = { list: listData };\n    return {\n      ...OK,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = paginate;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/update.js",
    "content": "const mongoose = require('mongoose');\n\nconst {\n  INVALID_REQUEST_PARAMS, SCHEMA_NOT_FOUND, OK, SERVER_ERROR,\n} = require('../../constants/message').message;\n\n/**\n *\n * Function used for update user.\n * @return json\n */\nconst update = (schemaDetailRepo) => async (id, params) => {\n  try {\n    // Validate Unique Criteria\n    const filter = { _id: id };\n    if (id) {\n      const isValidId = mongoose.Types.ObjectId.isValid(id);\n      if (!isValidId) {\n        return INVALID_REQUEST_PARAMS;\n      }\n    }\n    const schema = await schemaDetailRepo.get({ filter });\n\n    if (!schema) {\n      return SCHEMA_NOT_FOUND;\n    }\n\n    const updateResponse = await schemaDetailRepo.update(id, params);\n    return {\n      ...OK,\n      data: updateResponse,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\n\nmodule.exports = update;\n"
  },
  {
    "path": "packages/server/usecase/schemaDetail/upsert.js",
    "content": "/* global _ */\nconst { ROUTE_GENERATE_TYPE } = require('../../models/constants/project');\n\nconst ProjectRouteRepo = require('../../repo/projectRoute');\nconst ApplicationRepo = require('../../repo/application');\nconst SchemaRepo = require('../../repo/schema');\n\nconst projectRouteRepo = new ProjectRouteRepo();\nconst applicationRepo = new ApplicationRepo();\nconst schemaRepo = new SchemaRepo();\n\nconst RouteDeleteUseCase = require('../projectRoute/deleteDependency');\nconst getPermissionWiseRoute = require('../util/getPermissionWiseRoute');\nconst routeInsertManyUseCase = require('../projectRoute/insertMany');\nconst projectApplicationUpdate = require('../common/projectApplicationUpdate');\n\nconst {\n  INVALID_REQUEST_PARAMS, SERVER_ERROR, MODEL_PERMISSION_UPDATED,\n} = require('../../constants/message').message;\n\nconst upsert = (schemaDetailRepo) => async (params) => {\n  try {\n    if (!params || !params.data || !params.data.length) {\n      return INVALID_REQUEST_PARAMS;\n    }\n    let applicationId = null;\n    let existsData = await schemaDetailRepo.getDetails({ find: { _id: { $in: _.map(params.data, '_id') } } });\n    existsData = _.groupBy(existsData, '_id');\n    const response = {\n      success: [],\n      failed: [],\n    };\n    let applicationDetails = null;\n    let definitionDetails = null;\n\n    await Promise.all(_.map(params.data, async (detail) => {\n      if (detail._id && existsData[detail._id]) {\n        await schemaDetailRepo.update(detail._id, _.omit(detail, ['_id', 'createdAt', 'updatedAt']));\n\n        if (detail.schemaJson) {\n          const filter = {\n            filter: {\n              find: {\n                _id: detail.schemaId,\n                isActive: { $in: [true, false] },\n              },\n            },\n            fields: ['_id', 'name', 'applicationId'],\n          };\n          const schemaDetail = await schemaRepo.get(filter);\n\n          if (schemaDetail && schemaDetail.applicationId) {\n            applicationId = schemaDetail.applicationId;\n\n            if (!applicationDetails) {\n              applicationDetails = await applicationRepo.get({ find: { _id: applicationId } });\n              if (applicationDetails) {\n                definitionDetails = {};// await getProjectDefinition({ _id: applicationDetails.definitionId });\n              }\n            }\n\n            // update route based on permission\n            await (RouteDeleteUseCase(projectRouteRepo, applicationRepo))({\n              find: {\n                modelId: detail.schemaId,\n                type: ROUTE_GENERATE_TYPE.AUTO,\n              },\n            }, true);\n            // create route based on permission\n            const allRouts = getPermissionWiseRoute(detail.schemaJson, schemaDetail, definitionDetails?.code);\n            await (routeInsertManyUseCase(projectRouteRepo))({ routes: allRouts });\n          }\n        }\n\n        response.success.push(detail);\n      } else {\n        response.failed.push(detail);\n      }\n      return true;\n    }));\n    projectApplicationUpdate({\n      params: { applicationId },\n      isProjectId: true,\n    });\n    return {\n      ...MODEL_PERMISSION_UPDATED,\n      data: response,\n    };\n  } catch (err) {\n    // console.log('error', err);\n    return { ...SERVER_ERROR };\n    // return { ...SERVER_ERROR, data: err.toString() };\n  }\n};\nmodule.exports = upsert;\n"
  },
  {
    "path": "packages/server/usecase/util/fieldsList.js",
    "content": "const APPLICATION_FIELDS = [\n  '_id',\n  'updatedAt',\n  'name',\n  'description',\n  'addedBy',\n  'createdAt',\n  'isArchive',\n  'projectId',\n  'definitionId',\n  'configInput',\n  'statics',\n  'projectType',\n  'processStep',\n  'generatedId',\n  'tempGeneratedId',\n  'isClone',\n  'stepInput.figmaFileId',\n  'stepInput.ormType',\n  'stepInput.databaseType',\n  'imageScale',\n  'adminPanelGeneratedId',\n  'parentId',\n  'fireStoreProjectId',\n  'isConstraint',\n];\n\nconst USER_FIELDS = [\n  '_id',\n  'image',\n  'firstName',\n  'lastName',\n  'email',\n  'username',\n];\n\nconst PROJECT_FIELDS = [\n  '_id',\n  'image',\n  'name',\n  'updatedAt',\n  'description',\n  'isArchive',\n  'createdAt',\n];\n\nconst PROJECT_DEFINITION_FIELDS = [\n  '_id',\n  'name',\n  'code',\n  'frontJson',\n];\n\nconst GENERATOR_FIELDS = [\n  '_id',\n  'type',\n  'status',\n  'createdAt',\n  'updatedAt',\n];\n\nmodule.exports = {\n  APPLICATION_FIELDS,\n  USER_FIELDS,\n  PROJECT_FIELDS,\n  PROJECT_DEFINITION_FIELDS,\n  GENERATOR_FIELDS,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/getApplicationData.js",
    "content": "const mongoose = require('mongoose');\n/* global MESSAGE */\n\nconst getApplicationDetail = (applicationRepo) => async ({\n  applicationId, fields, isAllFields = false,\n}) => {\n  if (!applicationId) {\n    return MESSAGE.BAD_REQUEST;\n  }\n  const isValidId = mongoose.Types.ObjectId.isValid(applicationId);\n  if (!isValidId) {\n    return MESSAGE.BAD_REQUEST;\n  }\n\n  let newFields = ['isArchive', 'isDeleted', 'definitionId', 'generatedId', 'name', 'tempGeneratedId'];\n  if (fields) {\n    newFields = [...newFields, ...fields];\n  }\n\n  if (isAllFields) {\n    newFields = [];\n  }\n\n  const application = await applicationRepo.get({\n    filter: {\n      find: {\n        _id: applicationId,\n        isDeleted: [true, false],\n      },\n    },\n    fields: newFields,\n  });\n\n  if (!application) {\n    return MESSAGE.NOT_FOUND;\n  }\n  if (application?.isDeleted === true) {\n    return MESSAGE.APPLICATION_IS_DELETED;\n  }\n\n  return {\n    ...MESSAGE.OK,\n    data: application,\n  };\n};\n\n/**\n * Function used to get application detail\n * @param {*} applicationRepo\n * @returns\n */\nconst getApplicationDetailById = (applicationRepo) => async ({ applicationId }) => {\n  if (!applicationId) {\n    return MESSAGE.BAD_REQUEST;\n  }\n\n  const filter = { id: applicationId };\n\n  const application = await applicationRepo.getById(filter);\n\n  if (!application) {\n    return MESSAGE.NOT_FOUND;\n  }\n  if (application?.isDeleted === true) {\n    return MESSAGE.APPLICATION_IS_DELETED;\n  }\n\n  return {\n    ...MESSAGE.OK,\n    data: application,\n  };\n};\n\nmodule.exports = {\n  getApplicationDetail,\n  getApplicationDetailById,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/getBaseUrl.js",
    "content": "const getBaseUrl = () => {\n  if (process.env.BASE_URL) {\n    return process.env.BASE_URL;\n  }\n  const port = 3053;\n  const host = 'localhost';\n  return `${host}:${port}`;\n};\nmodule.exports = { getBaseUrl };\n"
  },
  {
    "path": "packages/server/usecase/util/getPermissionWiseRoute.js",
    "content": "/* global _ */\nconst getRoutes = require('./getRoutes');\n\nfunction getPermissionWiseRoute (schemaJson, schemaDetail, definitionCode = null) {\n  let allRouts = [];\n\n  _.each(schemaJson, (val, key) => {\n    if (key && !_.isEmpty(schemaJson[key])) {\n      allRouts = allRouts.concat(getRoutes(key, schemaDetail.name, true, schemaJson[key], definitionCode));\n    }\n  });\n  /*\n   * if (schemaJson.admin) {\n   * allRouts = allRouts.concat(getRoutes('admin', schemaDetail.name, true, schemaJson.admin));\n   * }\n   * if (schemaJson.device) {\n   * allRouts = allRouts.concat(getRoutes('device', schemaDetail.name, true, schemaJson.device));\n   * }\n   *\n   * if (schemaJson.desktop) {\n   * allRouts = allRouts.concat(getRoutes('desktop', schemaDetail.name, true, schemaJson.desktop));\n   * }\n   *\n   * if (schemaJson.client) {\n   * allRouts = allRouts.concat(getRoutes('client', schemaDetail.name, true, schemaJson.client));\n   * }\n   */\n\n  _.each(allRouts, (r) => {\n    r.modelId = schemaDetail._id;\n    r.applicationId = schemaDetail.applicationId;\n    r.groupName = schemaDetail.name;\n  });\n\n  return allRouts;\n}\n\nmodule.exports = getPermissionWiseRoute;\n"
  },
  {
    "path": "packages/server/usecase/util/getRoutes.js",
    "content": "function getRoutes (platform, model, isAuth, permission = ['C', 'R', 'U', 'D']) {\n  const requestArr = [];\n\n  let addMethod = {};\n  let insertBulkObj = {};\n  let findAllUserObj = {};\n  let findOneObj = {};\n  let updateObj = {};\n  let updateBulkObj = {};\n  let deleteObj = {};\n\n  addMethod = {\n    method: 'post',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/create` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/create`,\n    controller: `${model}Controller`,\n    platform,\n    action: `add${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  insertBulkObj = {\n    method: 'post',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/addBulk` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/addBulk`,\n    controller: `${model}Controller`,\n    platform,\n    action: `bulkInsert${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  findAllUserObj = {\n    method: 'post',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/list` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/list`,\n    controller: `${model}Controller`,\n    platform,\n    action: `findAll${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  findOneObj = {\n    method: 'get',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/{{id}}` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/{{id}}`,\n    controller: `${model}Controller`,\n    platform,\n    action: `get${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  updateObj = {\n    method: 'put',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/update/{{id}}` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/update/{{id}}`,\n    controller: `${model}Controller`,\n    platform,\n    action: `update${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  updateBulkObj = {\n    method: 'put',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/updateBulk` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/updateBulk`,\n    controller: `${model}Controller`,\n    platform,\n    action: `bulkUpdate${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n  deleteObj = {\n    method: 'delete',\n    route: platform.toLowerCase() === 'admin' ? `/${platform.toLowerCase()}/${model.toLowerCase()}/delete/{{id}}` : `/${platform.toLowerCase()}/route/v1/${model.toLowerCase()}/delete/{{id}}`,\n    controller: `${model}Controller`,\n    platform,\n    action: `delete${model.charAt(0).toUpperCase() + model.slice(1)}`,\n    isAuth,\n    fileName: `${model}Route`,\n  };\n\n  if (permission.includes('C')) {\n    requestArr.push(addMethod);\n  }\n\n  if (permission.includes('BC')) {\n    requestArr.push(insertBulkObj);\n  }\n\n  if (permission.includes('R')) {\n    requestArr.push(findAllUserObj);\n    requestArr.push(findOneObj);\n  }\n\n  if (permission.includes('U')) {\n    requestArr.push(updateObj);\n  }\n\n  if (permission.includes('BU')) {\n    requestArr.push(updateBulkObj);\n  }\n\n  if (permission.includes('D')) {\n    requestArr.push(deleteObj);\n  }\n\n  return requestArr;\n}\n\nmodule.exports = getRoutes;\n"
  },
  {
    "path": "packages/server/usecase/util/randomNumber.js",
    "content": "/* eslint-disable no-plusplus */\nconst randomNumber = (length = 6) => {\n  const numbers = '01234567890123456789';\n  let result = '';\n  for (let i = length; i > 0; --i) {\n    result += numbers[Math.round(Math.random() * (numbers.length - 1))];\n  }\n  return result;\n};\n\nmodule.exports = { randomNumber };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/accessPermission.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst accessPermissionCreateValidation = (params) => {\n  const schema = Joi.object({\n    permissionJson: Joi.array()\n      .required()\n      .messages(validationCustomMessage('Permission Json')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { accessPermissionCreateValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/actionValidation.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst actionValidationValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    screenId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('screen Id')),\n    customJson: Joi.object()\n      .required()\n      .messages(validationCustomMessage('custom Json')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { actionValidationValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/apiIntegration.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst apiIntegrationValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    screenId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('screen Id')),\n    routeId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('route Id')),\n    apis: Joi.object({\n      requestBinding: Joi.object({\n        body: Joi.array().items(Joi.object({\n          type: Joi.string().trim().required().messages(validationCustomMessage('requestBinding-body-type')),\n          viewId: Joi.string().trim().allow('').messages(validationCustomMessage('requestBinding-body-viewId')),\n          apiKey: Joi.array().required().messages(validationCustomMessage('requestBinding-body-apiKey')),\n          rectCords: Joi.object().optional().messages(validationCustomMessage('requestBinding-body-rectCords')),\n        }).unknown(true)),\n        params: Joi.array().items(Joi.object({\n          type: Joi.string().trim().required().messages(validationCustomMessage('requestBinding-params-type')),\n          viewId: Joi.string().trim().allow('').messages(validationCustomMessage('requestBinding-params-viewId')),\n          apiKey: Joi.array().required().messages(validationCustomMessage('requestBinding-params-apiKey')),\n          rectCords: Joi.object().optional().messages(validationCustomMessage('requestBinding-params-rectCords')),\n        }).unknown(true)),\n      })\n        .unknown(true)\n        .required()\n        .messages(validationCustomMessage('requestBinding')),\n      responseBinding: Joi.array().items(Joi.object({\n        type: Joi.string().trim().required().messages(validationCustomMessage('type')),\n        // viewId: Joi.string().trim().messages(validationCustomMessage('viewId')),\n        apiKey: Joi.array().required().messages(validationCustomMessage('apiKey')),\n        // rectCords: Joi.object().required().messages(validationCustomMessage('rectCords')),\n      }).unknown(true))\n        .required()\n        .messages(validationCustomMessage('responseBinding')),\n    })\n      .required()\n      .messages(validationCustomMessage('apis')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { apiIntegrationValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/applicationConfig.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst appConfigCreateValidation = (params) => {\n  const schema = Joi.object({\n    responseFormatter: Joi.array().items(Joi.object({\n      isAllModels: Joi.boolean().required().messages(validationCustomMessage('responseFormatter.isAllModels')),\n      modelId: Joi.any().when('isAllModels',\n        {\n          is: false,\n          then: Joi.string().required().messages(validationCustomMessage('responseFormatter.modelId')),\n        }),\n      dataType: Joi.string().required().messages(validationCustomMessage('responseFormatter.dataType')),\n      targetAttr: Joi.string().messages(validationCustomMessage('responseFormatter.targetAttr')),\n      operator: Joi.string().messages(validationCustomMessage('responseFormatter.operator')),\n      attribute: Joi.any().required().messages(validationCustomMessage('responseFormatter.attribute')),\n      title: Joi.string().required().messages(validationCustomMessage('responseFormatter.title')),\n    })).unique().messages(validationCustomMessage('responseFormatter')),\n    socialPlatform: Joi.array().optional().items(Joi.object({\n      credential: Joi.object({\n        isGoogle: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isGoogle')),\n        isFacebook: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isFacebook')),\n        callbackUrl: Joi.string().optional().messages(validationCustomMessage('socialPlatform.callbackUrl')),\n        errorUrl: Joi.string().optional().messages(validationCustomMessage('socialPlatform.errorUrl')),\n      }),\n      type: Joi.string().messages(validationCustomMessage('socialPlatform.type')),\n      typeId: Joi.string().messages(validationCustomMessage('socialPlatform.typeId')),\n      platform: Joi.array().optional().messages(validationCustomMessage('socialPlatform.platform')),\n      isChecked: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isChecked')),\n    })),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst appConfigUpdateValidation = (params) => {\n  const schema = Joi.object({\n    responseFormatter: Joi.array().items(Joi.object({\n      isAllModels: Joi.boolean().required().messages(validationCustomMessage('responseFormatter.isAllModels')),\n      modelId: Joi.any().when('isAllModels',\n        {\n          is: false,\n          then: Joi.string().required().messages(validationCustomMessage('responseFormatter.modelId')),\n        }),\n      dataType: Joi.string().required().messages(validationCustomMessage('responseFormatter.dataType')),\n      targetAttr: Joi.string().messages(validationCustomMessage('responseFormatter.targetAttr')),\n      operator: Joi.string().messages(validationCustomMessage('responseFormatter.operator')),\n      attribute: Joi.any().required().messages(validationCustomMessage('responseFormatter.attribute')),\n      title: Joi.string().required().messages(validationCustomMessage('responseFormatter.title')),\n    })).unique().messages(validationCustomMessage('responseFormatter')),\n    socialPlatform: Joi.array().optional().items(Joi.object({\n      credential: Joi.object({\n        isGoogle: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isGoogle')),\n        isFacebook: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isFacebook')),\n        callbackUrl: Joi.string().optional().messages(validationCustomMessage('socialPlatform.callbackUrl')),\n        errorUrl: Joi.string().optional().messages(validationCustomMessage('socialPlatform.errorUrl')),\n      }),\n      type: Joi.string().messages(validationCustomMessage('socialPlatform.type')),\n      typeId: Joi.string().messages(validationCustomMessage('socialPlatform.typeId')),\n      platform: Joi.array().optional().messages(validationCustomMessage('socialPlatform.platform')),\n      isChecked: Joi.boolean().optional().messages(validationCustomMessage('socialPlatform.isChecked')),\n    })),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  appConfigUpdateValidation,\n  appConfigCreateValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/applicationCreate.js",
    "content": "/* global */\nconst Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage, validateMongoId,\n} = require('../../../util-service/validation');\nconst { PROJECT_DEFINITION_CODE } = require('../../../models/constants/projectDefinition');\nconst {\n  ORM_TYPE, DATABASE_TYPE,\n} = require('../../../models/constants/applicationConfig');\n\nconst {\n  validation, VALIDATION_RULES,\n} = require('../../../constants/validation');\n\nconst applicationCreationValidation = (params) => {\n  const schema = Joi.object({\n    projectDefinitionCode: Joi.string()\n      .trim()\n      .required()\n      .regex(VALIDATION_RULES.PROJECT_DEFINITION_CODE)\n      .valid(...Object.values(PROJECT_DEFINITION_CODE))\n      .messages(validationCustomMessage('Project definition code')),\n    definitionId: Joi.string()\n      .trim()\n      .required()\n      .custom(validateMongoId('Definition Id'))\n      .messages(validationCustomMessage('Definition id'))\n      .allow(null, ''),\n    projectId: Joi.string()\n      .trim()\n      .custom(validateMongoId('Project Id'))\n      .optional()\n      .messages(validationCustomMessage('Project id'))\n      .allow(null, ''),\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(VALIDATION_RULES.APPLICATION.NAME.MIN)\n      .max(VALIDATION_RULES.APPLICATION.NAME.MAX)\n      .regex(VALIDATION_RULES.APPLICATION.NAME.REGEX)\n      .messages(validationCustomMessage('Name')),\n    description: Joi.string()\n      .trim()\n      .optional()\n      .allow('')\n      .max(VALIDATION_RULES.DESCRIPTION.MAX)\n      .messages(validationCustomMessage('Description')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst nodeExpressValidation = (params) => {\n  if (params?.stepInput?.ormType === ORM_TYPE.MONGOOSE) {\n    params.stepInput.databaseType = DATABASE_TYPE.MONGODB;\n  }\n\n  const databaseTypeWithMongoDb = Object.values(DATABASE_TYPE).filter((i) => i !== DATABASE_TYPE.MONGODB);\n\n  const schema = Joi.object({\n    authModel: Joi.number()\n      .min(validation.authModel.min)\n      .max(validation.authModel.max)\n      .messages(validationCustomMessage('Auth model')),\n    configInput: Joi.object({\n\n      databaseName: Joi.string()\n        .trim()\n        .required()\n        .min(validation.databaseName.min)\n        .max(validation.databaseName.max)\n        .messages(validationCustomMessage('Database name')),\n      port: Joi.string()\n        .trim()\n        .required()\n        /*\n         * .min(validation.port.min)\n         * .max(validation.port.max)\n         */\n        .messages(validationCustomMessage('port')),\n      types: Joi.array()\n        .messages(validationCustomMessage('types')),\n      platform: Joi.array()\n        .messages(validationCustomMessage('platform')),\n      noPlatform: Joi.array()\n        .messages(validationCustomMessage('noPlatform')),\n      isAuthentication: Joi.boolean()\n        .optional()\n        .messages(validationCustomMessage('isAuthentication')),\n      loginAccess: Joi.object({\n        User: Joi.array()\n          .optional()\n          .messages(validationCustomMessage('User')),\n      })\n        .optional()\n        .messages(validationCustomMessage('loginAccess'))\n        .unknown(true),\n    }).required()\n      .messages(validationCustomMessage('configInput')),\n    stepInput: Joi.object({\n      ormType: Joi.number()\n        .required()\n        .valid(...Object.values(ORM_TYPE))\n        .messages(validationCustomMessage('ORM type')),\n      databaseType: Joi.number()\n        .when('ormType', {\n          is: ORM_TYPE.MONGOOSE,\n          then: Joi.optional().valid(DATABASE_TYPE.MONGODB),\n          otherwise: Joi.required().valid(...databaseTypeWithMongoDb),\n        })\n        .messages(validationCustomMessage('Database type')),\n    }).required()\n      .messages(validationCustomMessage('Step input')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst applicationCreationV2Validation = (params) => {\n  const schema = Joi.object({\n    projectDefinitionCode: Joi.string()\n      .trim()\n      .required()\n      .valid(...Object.values(PROJECT_DEFINITION_CODE))\n      .messages(validationCustomMessage('Project definition code')),\n    definitionId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Definition id')),\n    projectId: Joi.string()\n      .trim()\n      .optional()\n      .messages(validationCustomMessage('Project id')),\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(validation.name.min)\n      .max(validation.name.max)\n      .messages(validationCustomMessage('Name')),\n    description: Joi.string()\n      .trim()\n      .optional()\n      .allow('')\n      .max(VALIDATION_RULES.DESCRIPTION.MAX)\n      .messages(validationCustomMessage('Description')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  applicationCreationValidation,\n  nodeExpressValidation,\n  applicationCreationV2Validation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/applicationId.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst applicationIdValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { applicationIdValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/applicationUpdate.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\nconst { VALIDATION_RULES } = require('../../../constants/validation');\n\nconst applicationUpdateValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(VALIDATION_RULES.APPLICATION.NAME.MIN)\n      .max(VALIDATION_RULES.APPLICATION.NAME.MAX)\n      .regex(VALIDATION_RULES.APPLICATION.NAME.REGEX)\n      .messages(validationCustomMessage('Name')),\n    description: Joi.string()\n      .trim()\n      .optional()\n      .allow('')\n      .max(VALIDATION_RULES.DESCRIPTION.MAX)\n      .messages(validationCustomMessage('description')),\n    configInput: Joi.object({\n      port: Joi.string().optional().regex(VALIDATION_RULES.PORT_REGEX).messages(validationCustomMessage('Port')),\n      databaseName: Joi.string()\n        .min(VALIDATION_RULES.APPLICATION.NAME.MIN)\n        .max(VALIDATION_RULES.APPLICATION.NAME.MAX)\n        .optional()\n        .regex(VALIDATION_RULES.APPLICATION.NAME.REGEX)\n        .messages(validationCustomMessage('Database Name')),\n      loginAccess: Joi.object(),\n      platform: Joi.array()\n        .items(Joi.string()\n          .regex(VALIDATION_RULES.APPLICATION.NAME.REGEX)\n          .min(VALIDATION_RULES.APPLICATION.NAME.MIN)\n          .max(VALIDATION_RULES.APPLICATION.NAME.MAX)).messages(validationCustomMessage('Platform')),\n      noPlatform: Joi.array()\n        .messages(validationCustomMessage('noPlatform')),\n      types: Joi.array()\n        .items(Joi.string()\n          .regex(VALIDATION_RULES.APPLICATION.NAME.REGEX)\n          .min(VALIDATION_RULES.APPLICATION.NAME.MIN)\n          .max(VALIDATION_RULES.APPLICATION.NAME.MAX)).messages(validationCustomMessage('Types')),\n      isAuthentication: Joi.boolean(),\n      applicationToken: Joi.string().optional(),\n      authModel: Joi.string().optional(),\n    }),\n    stepInput: Joi.object({\n      packageName: Joi\n        .string()\n        .regex(VALIDATION_RULES.APPLICATION.PACKAGE_NAME.REGEX)\n        .trim()\n        .optional()\n        .messages(validationCustomMessage('package name')),\n    }).unknown(true),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst applicationUploadFolderUpdate = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    dirStructure: Joi.object()\n      .required()\n      .messages(validationCustomMessage('Dir Structure')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  applicationUpdateValidation,\n  applicationUploadFolderUpdate,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/applicationUpsert.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst applicationUpsertValidation = (params) => {\n  const schema = Joi.object({\n    isArchive: Joi.boolean()\n      .required()\n      .messages(validationCustomMessage('isArchive')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { applicationUpsertValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/defaultInsertModels.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst defaultInsertModels = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    models: Joi.array().items(Joi.object({\n      modelName: Joi.string().trim().required().messages(validationCustomMessage('models.modelName')),\n      description: Joi.string().trim().optional().messages(validationCustomMessage('models.description')),\n      schemaJson: Joi.object().messages(validationCustomMessage('models.schemaJson')),\n      hooks: Joi.array().messages(validationCustomMessage('models.hooks')),\n      modelIndexes: Joi.array().messages(validationCustomMessage('models.modelIndexes')),\n    }))\n      .required()\n      .messages(validationCustomMessage('models')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { defaultInsertModels };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/group.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\nconst { validation } = require('../../../constants/validation');\n\nconst groupValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(validation.name.min)\n      .max(validation.name.max)\n      .messages(validationCustomMessage('name')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { groupValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/masterValidation.js",
    "content": "const Joi = require('joi');\nconst {\n  validationCustomMessage,\n  validateSchema,\n} = require('../../../util-service/validation');\n\nconst masterCreateValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .trim()\n      .min(1)\n      .required()\n      .messages(validationCustomMessage('Token')),\n    code: Joi.string()\n      .trim()\n      .min(1)\n      .required()\n      .messages(validationCustomMessage('Otp')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst masterCodeValidation = (params) => {\n  const schema = Joi.object({\n    parentCode: Joi.string()\n      .trim()\n      .messages(validationCustomMessage('Parent Code')),\n    code: Joi.string()\n      .trim()\n      .messages(validationCustomMessage('Code')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  masterCreateValidation,\n  masterCodeValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectConstant.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst {\n  validation, VALIDATION_RULES,\n} = require('../../../constants/validation');\n\nconst projectConstantValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    fileName: Joi.string()\n      .trim()\n      .min(validation.fileName.min)\n      .max(validation.fileName.max)\n      .required()\n      .regex(VALIDATION_RULES.CONSTANT_FILE_NAME)\n      .messages(validationCustomMessage('File Name')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .required()\n     * .messages(validationCustomMessage('Description')),\n     */\n    /*\n     * customJson: Joi\n     *   .object()\n     *   .messages(validationCustomMessage('Custom Json')),\n     */\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { projectConstantValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectCreate.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\nconst { VALIDATION_RULES } = require('../../../constants/validation');\n\nconst projectCreationValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(VALIDATION_RULES.PROJECT_NAME.MIN)\n      .max(VALIDATION_RULES.PROJECT_NAME.MAX)\n      .regex(VALIDATION_RULES.PROJECT_NAME.REGEX)\n      .messages(validationCustomMessage('Name')),\n    description: Joi.string()\n      .trim()\n      // .required()\n      .min(VALIDATION_RULES.DESCRIPTION.MIN)\n      .max(VALIDATION_RULES.DESCRIPTION.MAX)\n      .messages(validationCustomMessage('Description')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { projectCreationValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectPolicy.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst {\n  validation, VALIDATION_RULES,\n} = require('../../../constants/validation');\n\nconst projectPolicyCreateValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    fileName: Joi.string()\n      .trim()\n      .min(validation.fileName.min)\n      .max(validation.fileName.max)\n      .required()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME)\n      .messages(validationCustomMessage('File Name')),\n    customJson: Joi\n      .optional()\n      .messages(validationCustomMessage('Custom Json')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .required()\n     * .messages(validationCustomMessage('Description')),\n     */\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst projectPolicyUpdateValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('Application Id')),\n    fileName: Joi.string()\n      .trim()\n      .min(validation.fileName.min)\n      .max(validation.fileName.max)\n      .required()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME)\n      .messages(validationCustomMessage('File Name')),\n    customJson: Joi\n      .required()\n      .messages(validationCustomMessage('Custom Json')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .required()\n     * .messages(validationCustomMessage('Description')),\n     */\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  projectPolicyCreateValidation,\n  projectPolicyUpdateValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectRoleAccessPermission.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\nconst { validation } = require('../../../constants/validation');\n\nconst projectRoleAccessPermissionValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    name: Joi.string()\n      .min(validation.name.min)\n      .max(validation.name.max)\n      .trim()\n      .required()\n      .messages(validationCustomMessage('name')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .messages(validationCustomMessage('description')),\n     */\n    customJson: Joi.array()\n      .required()\n      .messages(validationCustomMessage('customJson')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { projectRoleAccessPermissionValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectRoute.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\n\nconst {\n  validation, VALIDATION_RULES,\n} = require('../../../constants/validation');\n\nconst projectRouteCreateValidation = (params, isNodeApp) => {\n  const schema = Joi.object({\n    method: Joi.string()\n      .min(validation.method.min)\n      .max(validation.method.max)\n      .trim()\n      .required()\n      .messages(validationCustomMessage('method')),\n    route: Joi.string()\n      .trim()\n      .min(validation.route.min)\n      .max(validation.route.max)\n      .required()\n      .regex(isNodeApp ? VALIDATION_RULES.ROUTE_REGEX : VALIDATION_RULES.URL_REGEX)\n      .messages(validationCustomMessage('route')),\n    controller: Joi.string()\n      .min(validation.controller.min)\n      .max(validation.controller.max)\n      .trim()\n      .optional()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME_WITHOUT_DASH)\n      .messages(validationCustomMessage('controller')),\n    action: Joi.string()\n      .trim()\n      .optional()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME_WITHOUT_DASH)\n      .messages(validationCustomMessage('action')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .optional()\n     * .messages(validationCustomMessage('description')),\n     */\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    params: Joi.array()\n      .optional()\n      .messages(validationCustomMessage('params')),\n    request: Joi.object()\n      .optional()\n      .messages(validationCustomMessage('request')),\n    response: Joi.object()\n      .optional()\n      .messages(validationCustomMessage('response')),\n    queryBuilder: Joi.array()\n      .optional()\n      .messages(validationCustomMessage('queryBuilder')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst projectRouteUpdateValidation = (params, isNodeApp) => {\n  const schema = Joi.object({\n    method: Joi.string()\n      .min(validation.method.min)\n      .max(validation.method.max)\n      .trim()\n      .messages(validationCustomMessage('method')),\n    route: Joi.string()\n      .trim()\n      .min(validation.route.min)\n      .max(validation.route.max)\n      .regex(isNodeApp ? VALIDATION_RULES.ROUTE_REGEX : VALIDATION_RULES.URL_REGEX)\n      .messages(validationCustomMessage('route')),\n    controller: Joi.string()\n      .min(validation.controller.min)\n      .max(validation.controller.max)\n      .trim()\n      .optional()\n      .messages(validationCustomMessage('controller')),\n    action: Joi.string()\n      .trim()\n      .optional()\n      .messages(validationCustomMessage('action')),\n    /*\n     * description: Joi.string()\n     * .min(validation.description.min)\n     * .max(validation.description.max)\n     * .trim()\n     * .optional()\n     * .messages(validationCustomMessage('description')),\n     */\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    params: Joi.array()\n      .optional()\n      .messages(validationCustomMessage('params')),\n    request: Joi.object()\n      .optional()\n      .messages(validationCustomMessage('request')),\n    response: Joi.object()\n      .optional()\n      .messages(validationCustomMessage('response')),\n    queryBuilder: Joi.array()\n      .optional()\n      .messages(validationCustomMessage('queryBuilder')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst projectRouteInsertManyValidation = (params) => {\n  const schema = Joi.object({\n    routes: Joi.array()\n      .required()\n      .messages(validationCustomMessage('routes')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst projectRouteRequestApiValidation = (params) => {\n  const schema = Joi.object({\n    url: Joi.string()\n      .required()\n      .messages(validationCustomMessage('Url')),\n    method: Joi.string()\n      .required()\n      .messages(validationCustomMessage('method')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  projectRouteCreateValidation,\n  projectRouteInsertManyValidation,\n  projectRouteUpdateValidation,\n  projectRouteRequestApiValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectUpdate.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\nconst { VALIDATION_RULES } = require('../../../constants/validation');\n\nconst projectUpdateValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .trim()\n      .required()\n      .min(VALIDATION_RULES.PROJECT_NAME.MIN)\n      .max(VALIDATION_RULES.PROJECT_NAME.MAX)\n      .regex(VALIDATION_RULES.PROJECT_NAME.REGEX)\n      .messages(validationCustomMessage('Name')),\n    description: Joi.string()\n      .trim()\n      // .required()\n      .min(VALIDATION_RULES.DESCRIPTION.MIN)\n      .max(VALIDATION_RULES.DESCRIPTION.MAX)\n      .messages(validationCustomMessage('Description')),\n\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { projectUpdateValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/projectUpsert.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst projectUpsertValidation = (params) => {\n  const schema = Joi.object({\n    isArchive: Joi.boolean()\n      .required()\n      .messages(validationCustomMessage('isArchive')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { projectUpsertValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/schema.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../../../util-service/validation');\nconst {\n  validation, VALIDATION_RULES,\n} = require('../../../constants/validation');\n\nconst schemaCreateValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    name: Joi.string()\n      .min(validation.name.min)\n      .max(validation.name.max)\n      .trim()\n      .required()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME_WITHOUT_DASH)\n      .messages(validationCustomMessage('name')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst schemaUpdateValidation = (params) => {\n  const schema = Joi.object({\n    name: Joi.string()\n      .min(validation.name.min)\n      .max(validation.name.max)\n      .trim()\n      .required()\n      .regex(VALIDATION_RULES.APPLICATION_FILE_NAME_WITHOUT_DASH)\n      .messages(validationCustomMessage('name')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst existingSchemaUpdateValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    models: Joi.array()\n      .required()\n      .messages(validationCustomMessage('models')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst sequelizeExistingSchemaUpdateValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    models: Joi.array()\n      .required()\n      .messages(validationCustomMessage('models')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst schemaSearchValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .trim()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    schemaName: Joi.string()\n      .required()\n      .messages(validationCustomMessage('schemaName')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  schemaCreateValidation,\n  existingSchemaUpdateValidation,\n  schemaUpdateValidation,\n  sequelizeExistingSchemaUpdateValidation,\n  schemaSearchValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation/schemaDetail.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst schemaDetailCreateValidation = (params) => {\n  const schema = Joi.object({\n    schemaId: Joi.string()\n      .required()\n      .messages(validationCustomMessage('schemaId')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = { schemaDetailCreateValidation };\n"
  },
  {
    "path": "packages/server/usecase/util/validation/sqlImport.js",
    "content": "const Joi = require('joi');\nconst {\n  validateSchema, validationCustomMessage,\n} = require('../validation');\n\nconst sqlImportValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nconst sqlInsertManyValidation = (params) => {\n  const schema = Joi.object({\n    applicationId: Joi.string()\n      .required()\n      .messages(validationCustomMessage('applicationId')),\n    schemaJson: Joi.array()\n      .required()\n      .messages(validationCustomMessage('schemaJson')),\n  }).unknown(true);\n\n  return validateSchema(schema, params);\n};\n\nmodule.exports = {\n  sqlImportValidation,\n  sqlInsertManyValidation,\n};\n"
  },
  {
    "path": "packages/server/usecase/util/validation.js",
    "content": "const validationCustomMessage = (label) => {\n  const lowerLabel = label?.toLowerCase();\n  return {\n    'any.required': `Please enter ${lowerLabel}.`,\n    'string.empty': `Please enter ${lowerLabel}.`,\n    'string.alphanum': `Please enter only characters in ${lowerLabel}`,\n    'string.min': `${label} should have a minimum length of {#limit}`,\n    'string.max': `${label} should have a maximum length of {#limit}`,\n    'string.base': `${label} must be a string.`,\n    'string.email': `Please enter valid ${lowerLabel}.`,\n    'string.pattern.base': `Please enter valid ${lowerLabel}.`,\n    'object.unknown': `${label} is not allowed.`,\n    'any.only': `Please enter valid ${lowerLabel}.`,\n    'number.base': `${label} must be a number.`,\n    'object.base': `${label} must be a object.`,\n    'array.base': `${label} must be a array.`,\n  };\n};\n\nconst validationErrorMessage = (error) => {\n  const [first] = error?.details?.map((i) => i?.message);\n  return first;\n};\n\nconst validateSchema = (schema, params) => {\n  let { error } = schema.validate(params);\n  const { value } = schema.validate(params);\n  if (error) {\n    error = validationErrorMessage(error);\n  }\n  return {\n    value,\n    error,\n  };\n};\n\nmodule.exports = {\n  validationCustomMessage,\n  validateSchema,\n};\n"
  },
  {
    "path": "packages/server/util-service/common/common.js",
    "content": "const fs = require('fs');\n\n/**\n * Function used get `directories, sub-directories, files` count.\n * @param  {} dirPath\n * @param  {} arrayOfFiles\n */\nasync function getAllDirFilesCount (dirPath, arrayOfFiles) {\n  const files = fs.readdirSync(dirPath);\n\n  arrayOfFiles = arrayOfFiles || [];\n\n  files.forEach(async (file) => {\n    if (fs.statSync(`${dirPath}/${file}`).isDirectory()) {\n      arrayOfFiles = await getAllDirFilesCount(`${dirPath}/${file}`, arrayOfFiles);\n    } else {\n      arrayOfFiles.push(file);\n    }\n  });\n\n  return arrayOfFiles.length;\n}\n\nmodule.exports = { getAllDirFilesCount };\n"
  },
  {
    "path": "packages/server/util-service/common/index.js",
    "content": "const { getAllDirFilesCount } = require('./common');\n\nmodule.exports = { getAllDirFilesCount };\n"
  },
  {
    "path": "packages/server/util-service/crypto/crypto.js",
    "content": "const CryptoJS = require('crypto-js');\n\nconst saltKey = 'nodejs-code-generator';\n\n/**\n * Function used to encrypt the string.\n * @param  {} str\n */\nasync function encrypt (str) {\n  return CryptoJS.AES.encrypt(str, saltKey).toString();\n}\n\n/**\n * Function used to deCrypt the encrypted string.\n * @param  {} str\n */\nasync function decrypt (str) {\n  const bytes = CryptoJS.AES.decrypt(str, saltKey);\n  return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nmodule.exports = {\n  encrypt,\n  decrypt,\n};\n"
  },
  {
    "path": "packages/server/util-service/crypto/index.js",
    "content": "const {\n  encrypt, decrypt,\n} = require('./crypto');\n\nmodule.exports = {\n  encrypt,\n  decrypt,\n};\n"
  },
  {
    "path": "packages/server/util-service/validation/index.js",
    "content": "const { ObjectID } = require('mongodb').ObjectID;\n\nconst validationCustomMessage = (label, customMessage) => {\n  const lowerLabel = label?.toLowerCase();\n  let rulesMessage = {\n    'any.required': `Please enter ${lowerLabel}.`,\n    'string.empty': `Please enter ${lowerLabel}.`,\n    'string.alphanum': `Please enter only characters in ${lowerLabel}`,\n    'string.min': `${label} should have a minimum length of {#limit}`,\n    'string.max': `${label} should have a maximum length of {#limit}`,\n    'string.base': `${label} must be a string.`,\n    'string.email': `Please enter valid ${lowerLabel}.`,\n    'string.pattern.base': `Please enter valid ${lowerLabel}.`,\n    'object.unknown': `${label} is not allowed.`,\n    'any.only': `Please enter valid ${lowerLabel}.`,\n    'number.base': `${label} must be a number.`,\n    'object.base': `${label} must be a object.`,\n    'boolean.base': `${label} must be a boolean.`,\n    'array.unique': `${label} contains a duplicate value.`,\n  };\n\n  if (customMessage && typeof customMessage === 'object') {\n    rulesMessage = {\n      ...rulesMessage,\n      ...customMessage,\n    };\n  }\n  return rulesMessage;\n};\n\nconst validationErrorMessage = (error) => {\n  const [first] = error?.details?.map((i) => i?.message);\n  return first;\n};\n\nconst validateSchema = (schema, params) => {\n  let { error } = schema.validate(params);\n  const { value } = schema.validate(params);\n  if (error) {\n    error = validationErrorMessage(error);\n  }\n  return {\n    value,\n    error,\n  };\n};\n\nconst validateMongoId = (label) => (value, helpers) => {\n  if (ObjectID.isValid(value)) {\n    return value;\n  }\n  const lowerLabel = label?.toLowerCase();\n  return helpers.message({ custom: `Enter valid value for ${lowerLabel}` });\n};\n\nmodule.exports = {\n  validationCustomMessage,\n  validateSchema,\n  validateMongoId,\n};\n"
  }
]