├── app ├── app.module.json ├── menus.registry.js ├── routes.registry.js ├── functions.registry.js ├── resources.registry.js ├── reducers.registry.js ├── validations.registry.js ├── styles │ ├── ModuleClasses.js │ ├── LargeModuleStyles.js │ ├── SmallModuleStyles.js │ ├── MediumModuleStyles.js │ ├── XLargeModuleStyles.js │ ├── DefaultModuleStyles.js │ └── XXLargeModuleStyles.js ├── types │ └── test.types.js ├── validations │ └── test.validation.js ├── components │ ├── ReportBug.js │ ├── RequestFeature.js │ ├── RequestSupport.js │ ├── RequestEnhancement.js │ └── ReportIssueForm.js ├── actions │ └── test.action.js ├── components.registry.js ├── utils │ └── app.utils.js └── reducers │ └── test.reducer.js ├── service ├── models.registry.ts ├── tasks.registry.ts ├── functions.registry.ts ├── middlewares.registry.ts ├── validations.registry.ts ├── controllers.registry.ts ├── validations │ └── support.validation.ts ├── controllers │ └── support.controller.ts ├── routes.registry.ts └── functions │ ├── support.functions.ts │ └── support.helper.ts ├── .husky ├── commit-msg └── pre-commit ├── lint-staged.config.js ├── module.meta.json ├── CONTRIBUTING.md ├── .vscode ├── extensions.json └── settings.json ├── jest.config.js ├── .wrappid └── wrappid.meta.json ├── .github ├── scripts │ └── attribution_header_adder.sh ├── pull_request_template.md └── workflows │ ├── create-tag.yml │ ├── auto-create-and-merge-pr.yml │ └── pr-guardrails.yml ├── .eslintrc.js ├── LICENSE ├── commitlint.config.js ├── .eslint ├── service │ └── .eslintrc.js └── app │ └── .eslintrc.js ├── package.json ├── .gitignore ├── scripts └── attributions.gen.js ├── CHANGELOG.md └── README.md /app/app.module.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /app/menus.registry.js: -------------------------------------------------------------------------------- 1 | export const MenusRegistry = {}; -------------------------------------------------------------------------------- /app/routes.registry.js: -------------------------------------------------------------------------------- 1 | export const RoutesRegistry = {}; -------------------------------------------------------------------------------- /app/functions.registry.js: -------------------------------------------------------------------------------- 1 | export const FunctionsRegistry = {}; -------------------------------------------------------------------------------- /app/resources.registry.js: -------------------------------------------------------------------------------- 1 | export const ResourcesRegistry = {}; -------------------------------------------------------------------------------- /app/reducers.registry.js: -------------------------------------------------------------------------------- 1 | export const ReducersRegistry = {}; 2 | -------------------------------------------------------------------------------- /app/validations.registry.js: -------------------------------------------------------------------------------- 1 | export const ValidationsRegistry = {}; -------------------------------------------------------------------------------- /service/models.registry.ts: -------------------------------------------------------------------------------- 1 | const ModelsRegistry = {}; 2 | 3 | export default ModelsRegistry; -------------------------------------------------------------------------------- /service/tasks.registry.ts: -------------------------------------------------------------------------------- 1 | const TasksRegistry = {}; 2 | 3 | export default TasksRegistry; -------------------------------------------------------------------------------- /service/functions.registry.ts: -------------------------------------------------------------------------------- 1 | const FunctionsRegistry = {}; 2 | 3 | export default FunctionsRegistry; 4 | -------------------------------------------------------------------------------- /service/middlewares.registry.ts: -------------------------------------------------------------------------------- 1 | const MiddlewaresRegistry = {}; 2 | 3 | export default MiddlewaresRegistry; -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit ${1} 5 | -------------------------------------------------------------------------------- /lint-staged.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { "**/*.{js,jsx,ts,tsx}": ["npm run code:lint:app", "npm run code:lint:service" ] }; -------------------------------------------------------------------------------- /module.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "web": true, 4 | "mobile": true 5 | }, 6 | "service": {} 7 | } -------------------------------------------------------------------------------- /app/styles/ModuleClasses.js: -------------------------------------------------------------------------------- 1 | const ModuleClasses = { TEST_WRAPPID_STYLE_CLASS: "testWrappidStyleClass" }; 2 | 3 | export default ModuleClasses; 4 | -------------------------------------------------------------------------------- /app/types/test.types.js: -------------------------------------------------------------------------------- 1 | export const TEST_SUCCESS = "TEST_SUCCESS"; 2 | export const TEST_FAILURE = "TEST_FAILURE"; 3 | export const RESET_TEST = "RESET_TEST"; -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## CONTRIBUTING 2 | All Wrappid repositories follow the same contributing guidelines available in the following link: 3 | https://github.com/wrappid/.github/blob/main/profile/CONTRIBUTING.md -------------------------------------------------------------------------------- /app/validations/test.validation.js: -------------------------------------------------------------------------------- 1 | export const checkEmailorPhone = { 2 | // eslint-disable-next-line no-undef 3 | message: yup 4 | .string() 5 | .required("Please enter a valid message."), 6 | }; -------------------------------------------------------------------------------- /service/validations.registry.ts: -------------------------------------------------------------------------------- 1 | import * as supportValidations from "./validations/support.validation"; 2 | 3 | const ValidationsRegistry = { 4 | ...supportValidations 5 | }; 6 | 7 | export default ValidationsRegistry; 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "vivaxy.vscode-conventional-commits", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode", 6 | "dsznajder.es7-react-js-snippets" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | transform: { 5 | '^.+\\.tsx?$': 'ts-jest' 6 | }, 7 | testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx?)$', 8 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 9 | clearMocks: true 10 | }; -------------------------------------------------------------------------------- /.wrappid/wrappid.meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectType": "module", 3 | "projectID": "", 4 | "projectName": "support", 5 | "wrTemplateVersion": "0.0.4", 6 | "remote": true, 7 | "repoProvider": "github.com", 8 | "repoOwner": "wrappid", 9 | "repoURL": "https://github.com/wrappid/support-module.git", 10 | "app": { 11 | "renderType": [] 12 | }, 13 | "service": {}, 14 | "modules": {} 15 | } -------------------------------------------------------------------------------- /app/components/ReportBug.js: -------------------------------------------------------------------------------- 1 | import { AppContainerLayout, CoreLayoutItem } from "@wrappid/core"; 2 | 3 | import ReportIssueForm from "./ReportIssueForm"; 4 | 5 | export default function ReportBug() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/components/RequestFeature.js: -------------------------------------------------------------------------------- 1 | import { AppContainerLayout, CoreLayoutItem } from "@wrappid/core"; 2 | 3 | import ReportIssueForm from "./ReportIssueForm"; 4 | 5 | export default function RequestFeature() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/components/RequestSupport.js: -------------------------------------------------------------------------------- 1 | import { AppContainerLayout, CoreLayoutItem } from "@wrappid/core"; 2 | 3 | import ReportIssueForm from "./ReportIssueForm"; 4 | 5 | export default function RequestSupport() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/components/RequestEnhancement.js: -------------------------------------------------------------------------------- 1 | import { AppContainerLayout, CoreLayoutItem } from "@wrappid/core"; 2 | 3 | import ReportIssueForm from "./ReportIssueForm"; 4 | 5 | export default function RequestEnhancement() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/LargeModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { LargeCoreStyles } from "@wrappid/core"; 2 | 3 | export default class LargeModuleStyles extends LargeCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using LargeUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/SmallModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { SmallCoreStyles } from "@wrappid/core"; 2 | 3 | export default class SmallModuleStyles extends SmallCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using smallUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/MediumModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { MediumCoreStyles } from "@wrappid/core"; 2 | 3 | export default class MediumModuleStyles extends MediumCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using defaultUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/XLargeModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { XLargeCoreStyles } from "@wrappid/core"; 2 | 3 | export default class XLargeModuleStyles extends XLargeCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using XLargeUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /service/controllers.registry.ts: -------------------------------------------------------------------------------- 1 | import { CoreMiddlewaresRegistry } from "@wrappid/service-core"; 2 | import * as supportController from "./controllers/support.controller"; 3 | import { createIssueReport } from "./validations/support.validation"; 4 | 5 | const ControllersRegistry = { 6 | createIssueReport: [ 7 | CoreMiddlewaresRegistry.validation(createIssueReport), 8 | supportController.createReportIssue, 9 | ], 10 | }; 11 | 12 | export default ControllersRegistry; 13 | -------------------------------------------------------------------------------- /.github/scripts/attribution_header_adder.sh: -------------------------------------------------------------------------------- 1 | REPONAME=$1 2 | HEADER="## ATTRIBUTIONS" 3 | echo $HEADER >> CONTENT.md 4 | CONTENT="This file lists the third-party libraries, frameworks, and other components used in the $REPONAME repository,
along with their respective licenses.
It is important to comply with the licensing terms of these components when using the code.
" 5 | echo $CONTENT >> CONTENT.md 6 | 7 | cat ATTRIBUTIONS.md >> CONTENT.md 8 | mv CONTENT.md ATTRIBUTIONS.md 9 | -------------------------------------------------------------------------------- /app/styles/DefaultModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { DefaultCoreStyles } from "@wrappid/core"; 2 | 3 | export default class DefaultModuleStyles extends DefaultCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using defaultUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/styles/XXLargeModuleStyles.js: -------------------------------------------------------------------------------- 1 | import { XXLargeCoreStyles } from "@wrappid/core"; 2 | 3 | export default class XXLargeModuleStyles extends XXLargeCoreStyles { 4 | constructor(){ 5 | super(); 6 | this.style = { 7 | /************************************************** 8 | * Using XXLargeUtilityStyles example 9 | *************************************************/ 10 | testWrappidStyleClass: { ...this.style.devBorder }, 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/actions/test.action.js: -------------------------------------------------------------------------------- 1 | import { RESET_TEST, TEST_FAILURE, TEST_SUCCESS } from "../types/test.types"; 2 | 3 | export const testSuccess = () => { 4 | return (dispatch) => { 5 | dispatch({ type: TEST_SUCCESS }); 6 | }; 7 | }; 8 | 9 | export const testFailure = () => { 10 | return (dispatch) => { 11 | dispatch({ type: TEST_FAILURE }); 12 | }; 13 | }; 14 | 15 | export const resetTest = () => { 16 | return (dispatch) => { 17 | dispatch({ type: RESET_TEST }); 18 | }; 19 | }; -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ignorePatterns: ["**/node_modules/*", ".eslintrc.js", "commitlint.config.js", "attributions.gen.js" ], 3 | overrides: [ 4 | { 5 | files: ["service/**/*.ts"], 6 | // Extend or merge with the service-specific configuration 7 | ...require("./.eslint/service/.eslintrc.js"), 8 | }, 9 | { 10 | files: ["app/**/*.js"], 11 | // Extend or merge with the app-specific configuration 12 | ...require("./.eslint/app/.eslintrc.js"), 13 | }, 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /service/validations/support.validation.ts: -------------------------------------------------------------------------------- 1 | import * as yup from "yup"; 2 | 3 | const createIssueReport = { 4 | body: yup 5 | .object({ 6 | title: yup.string().required(), 7 | description: yup.string(), 8 | stepsToCreate: yup.string(), 9 | stackTrace: yup.string(), 10 | isStacktrace: yup.string(), 11 | devInfo: yup.string().required(), 12 | reporterInfo: yup.string().required(), 13 | labels: yup.array() 14 | }) 15 | .noUnknown() 16 | .strict(), 17 | query: yup.object().noUnknown().strict(), 18 | }; 19 | 20 | export { 21 | createIssueReport 22 | }; -------------------------------------------------------------------------------- /app/components.registry.js: -------------------------------------------------------------------------------- 1 | import ReportBug from "./components/ReportBug"; 2 | import ReportIssueForm from "./components/ReportIssueForm"; 3 | import RequestEnhancement from "./components/RequestEnhancement"; 4 | import RequestFeature from "./components/RequestFeature"; 5 | import RequestSupport from "./components/RequestSupport"; 6 | 7 | export const ComponentsRegistry = { 8 | ReportBug : { comp: ReportBug }, 9 | ReportIssueForm : { comp: ReportIssueForm }, 10 | RequestEnhancement: { comp: RequestEnhancement }, 11 | RequestFeature : { comp: RequestFeature }, 12 | RequestSupport : { comp: RequestSupport }, 13 | }; 14 | -------------------------------------------------------------------------------- /app/utils/app.utils.js: -------------------------------------------------------------------------------- 1 | export function getLabel(string = "") { 2 | if (string) { 3 | string = string?.replace(/\s/g, ""); 4 | return (string?.substring(0, 1)?.toUpperCase() + string?.substring(1)) 5 | ?.replace(/([A-Z])/g, " $1") 6 | ?.trim(); 7 | } else { 8 | return ""; 9 | } 10 | } 11 | 12 | export function getFullName(data) { 13 | let name = ""; 14 | 15 | if (data?.firstName) { 16 | name += data?.firstName; 17 | } 18 | if (data?.middleName) { 19 | name += " " + data?.middleName; 20 | } 21 | if (data?.lastName) { 22 | name += " " + data?.lastName; 23 | } 24 | return name && name.length > 0 ? name : "Unnamed"; 25 | } -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | valid_branch_names_regex="^WRPD-(feature|bugfix|release|ci|enhancement|hotfix|refactor|deps|docs|experimental|security)?-[0-9]+$|^main$|^development$" 5 | branch="$(git rev-parse --abbrev-ref HEAD)" 6 | 7 | if [ "$branch" = "main" ] || [ "$branch" = "development" ]; then 8 | echo "Committing on the $branch branch is not allowed." 9 | exit 1 10 | fi 11 | 12 | if ! [[ $branch =~ $valid_branch_names_regex ]]; then 13 | echo "Invalid branch name: $branch; commit rejected" 14 | echo "Please rename your branch to conform to $valid_branch_names_regex pattern." 15 | exit 1 16 | fi 17 | 18 | npx lint-staged 19 | -------------------------------------------------------------------------------- /app/reducers/test.reducer.js: -------------------------------------------------------------------------------- 1 | import { RESET_TEST, TEST_FAILURE, TEST_SUCCESS } from "../types/test.types"; 2 | 3 | const initialState = { 4 | error : false, 5 | message: "This is a test module.", 6 | success: false 7 | }; 8 | 9 | const testReducer = (state = initialState, action) => { 10 | switch (action.type) { 11 | case TEST_SUCCESS: 12 | return { 13 | ...state, 14 | success: true 15 | }; 16 | 17 | case TEST_FAILURE: 18 | return { 19 | ...state, 20 | success: true 21 | }; 22 | 23 | case RESET_TEST: 24 | return initialState; 25 | 26 | default: 27 | return state; 28 | } 29 | }; 30 | 31 | export default testReducer; -------------------------------------------------------------------------------- /service/controllers/support.controller.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response} from "express"; 2 | import { createReportIssuePost } from "../functions/support.helper"; 3 | 4 | /** 5 | * Github - Error Reporting 6 | * 7 | * @param req 8 | * @param res 9 | */ 10 | export async function createReportIssue(req: Request, res: Response) { 11 | try { 12 | /** 13 | * GitHub - Post Issue 14 | */ 15 | const data = await createReportIssuePost(req); 16 | res.status(data?.status).json(data); 17 | } catch (error:any) { 18 | console.error("logout Error:: ", error); 19 | res.status(500).json({ 20 | message: "Error to create issue", 21 | error: { message: error.message, stackTrace: error.stack }, 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.eol": "\n", 3 | "[javascript]": { 4 | "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" 5 | }, 6 | "editor.formatOnSave": true, 7 | "editor.formatOnSaveMode": "file", 8 | "editor.guides.indentation": true, 9 | "editor.renderWhitespace": "boundary", 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll.eslint": "explicit" 12 | }, 13 | "eslint.validate": [ 14 | "javascript" 15 | ], 16 | "editor.defaultFormatter": "rvest.vs-code-prettier-eslint", 17 | "[dotenv]": { 18 | "editor.defaultFormatter": "foxundermoon.shell-format" 19 | }, 20 | "[shellscript]": { 21 | "editor.defaultFormatter": "foxundermoon.shell-format" 22 | }, 23 | "[json]": { 24 | "editor.defaultFormatter": "vscode.json-language-features" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 wrappid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * List of commit types allowed in commit messages. 3 | * 4 | * @author Ananta Kumar Ghosh 5 | */ 6 | const types = [ 7 | "build", 8 | "chore", 9 | "ci", 10 | "docs", 11 | "feat", 12 | "fix", 13 | "perf", 14 | "refactor", 15 | "revert", 16 | "style", 17 | "test" 18 | ]; 19 | 20 | /** 21 | * List of commit scopes allowed in commit messages. 22 | */ 23 | const scopes = ["config", "core", "global", "utils"]; 24 | 25 | // eslint-disable-next-line no-undef 26 | module.exports = { 27 | extends: ["@commitlint/config-conventional"], 28 | 29 | parserPreset: { parserOpts: { issuePrefixes: ["#"] } }, 30 | 31 | rules: { 32 | "body-leading-blank" : [2, "always"], 33 | "body-max-line-length": [2, "always", 250], 34 | "footer-empty" : [2, "never"], 35 | "footer-leading-blank": [2, "always"], 36 | "references-empty" : [2, "never"], 37 | "scope-case" : [2, "always", "camel-case"], 38 | "scope-empty" : [0, "always"], 39 | "scope-enum" : [2, "always", scopes], 40 | "type-enum" : [2, "always", types], 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /.eslint/service/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | extends: ["eslint:recommended", "plugin:import/recommended", "plugin:@typescript-eslint/recommended"], 8 | parserOptions: { 9 | ecmaVersion: 2021, 10 | sourceType: "module", 11 | }, 12 | parser: "@typescript-eslint/parser", 13 | plugins: ["import", "node", "promise", "unused-imports", "@typescript-eslint"], 14 | rules: { 15 | indent: ["error", 2, { MemberExpression: 1, SwitchCase: 1 }], 16 | "linebreak-style": ["error", "unix"], 17 | quotes: ["error", "double"], 18 | semi: ["error", "always"], 19 | "no-console": "off", 20 | "no-unused-vars": ["error", { args: "after-used", vars: "all" }], 21 | "import/order": [ 22 | "error", 23 | { alphabetize: { caseInsensitive: true, order: "asc" } }, 24 | ], 25 | "import/newline-after-import": "error", 26 | "@typescript-eslint/no-explicit-any": "warn" 27 | }, 28 | settings: { 29 | "import/resolver": { 30 | node: { 31 | extensions: [".js", ".jsx", ".ts", ".tsx"], 32 | paths: ["node_modules"] 33 | } 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Clearly describe the changes you've made in this pull request. Explain the purpose and reasoning behind the changes. Reference any relevant issues or discussions using keywords like "Fixes #" or "Resolves #". 4 | 5 | ## Related Issues 6 | 7 | 8 | 9 | ## Testing 10 | 11 | 12 | ## Checklist 13 | 14 | - [ ] I have performed a thorough self-review of my code. 15 | - [ ] I have added or updated relevant tests for my changes. 16 | - [ ] My code follows the project's style guidelines and best practices. 17 | - [ ] I have updated the documentation if necessary. 18 | - [ ] I have added or updated relevant comments in my code. 19 | - [ ] I have resolved any merge conflicts of my branch. 20 | 21 | 22 | ## Screenshots (if applicable) 23 | 24 | 25 | ## Additional Notes 26 | 27 | 28 | 29 | ## Reviewers 30 | 31 | 34 | 35 | --- 36 | 37 | ## Maintainer Notes 38 | 39 | - [ ] Has this change been tested in a staging environment? 40 | - [ ] Does this change introduce any breaking changes or deprecations? 41 | -------------------------------------------------------------------------------- /.github/workflows/create-tag.yml: -------------------------------------------------------------------------------- 1 | name: Create Tag - CI 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version_type: 7 | type: choice 8 | description: Choose version bump type 9 | options: 10 | - -r major 11 | - -r minor 12 | - -r patch 13 | - -p alpha 14 | - -p beta 15 | - -p build 16 | - -p hotfix 17 | - -p dev 18 | required: true 19 | default: "-r patch" 20 | pull_request: 21 | types: 22 | - closed 23 | branches: 24 | - 'development' 25 | 26 | jobs: 27 | call-create-tag: 28 | # runs-on: ubuntu-latest 29 | permissions: write-all 30 | if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'development') 31 | uses: wrappid/workflows/.github/workflows/util-create-tag.yml@main 32 | with: 33 | GIT_USER_NAME: ${{ vars.GIT_USER_NAME }} 34 | VERSION_TYPE_REPOSITORY_DEFAULT: ${{ vars.VERSION_TYPE_REPOSITORY_DEFAULT }} 35 | EMAIL_NOTIFY: ${{ vars.EMAIL_NOTIFY }} 36 | EMAIL_SENDER_NAME: ${{ vars.EMAIL_SENDER_NAME }} 37 | secrets: 38 | PAT: ${{ secrets.PAT }} 39 | GIT_USER_EMAIL: ${{ secrets.GIT_USER_EMAIL }} 40 | WRAPPID_REGISTRY_TOKEN: ${{ secrets.WRAPPID_REGISTRY_TOKEN }} 41 | EMAIL_SERVER_ADDRESS: ${{ secrets.EMAIL_SERVER_ADDRESS }} 42 | EMAIL_SERVER_PORT: ${{ secrets.EMAIL_SERVER_PORT }} 43 | EMAIL_USER_ID: ${{ secrets.EMAIL_USER_ID }} 44 | EMAIL_USER_PASSWORD: ${{ secrets.EMAIL_USER_PASSWORD }} 45 | EMAIL_TO: ${{ secrets.EMAIL_TO }} 46 | EMAIL_CC: ${{ secrets.EMAIL_CC }} ## Optional 47 | EMAIL_BCC: ${{ secrets.EMAIL_BCC }} ## Optional 48 | -------------------------------------------------------------------------------- /.github/workflows/auto-create-and-merge-pr.yml: -------------------------------------------------------------------------------- 1 | name: Auto Create and Merge PR 2 | 3 | on: 4 | workflow_dispatch: 5 | branches: 6 | - development 7 | 8 | jobs: 9 | create_and_merge_pr: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | issues: write 14 | pull-requests: write 15 | 16 | steps: 17 | 18 | - name: 🛠 Setup gh 19 | run: | 20 | echo ${{secrets.PAT}} | gh auth login --with-token 21 | 22 | - name: 🛒 Checkout code 23 | uses: actions/checkout@v3 24 | with: 25 | ref: development 26 | 27 | - name: 🕵️ Check for changes 28 | id: check_changes 29 | run: | 30 | git fetch origin main:main 31 | changes=$(git diff --name-only main..development) 32 | 33 | if [ -z "$changes" ]; then 34 | echo "No changes detected. Exiting." 35 | echo "::set-output name=changes::failiure" 36 | exit 0 37 | fi 38 | 39 | ## TODO: DIFFERENT WORKFLOW FOR EMAILS 40 | 41 | - name: 📧 Send Email 42 | if: ${{ steps.check_changes.outputs.changes != '' }} 43 | uses: dawidd6/action-send-mail@v3 44 | with: 45 | server_address: smtp.gmail.com 46 | server_port: 465 47 | username: ${{secrets.MAIL_USERNAME}} 48 | password: ${{secrets.MAIL_PASSWORD}} 49 | secure: true 50 | from: Wrappid Care 51 | to: ${{secrets.IDS}} 52 | cc: ${{secrets.MAINTAINER_ID}} 53 | subject: ${{ github.event.repository.name }} - No new commits since the last PR. 54 | body: | 55 | Hi Wrappid Managers, 56 | 57 | There were no new commits since the last PR in main branch from development branch in ${{ github.event.repository.name }} repository as of ${{ steps.date.outputs.date }}. 58 | 59 | Thank you for your attention and cooperation. 60 | 61 | Thanks and Regards, 62 | wrappidcare 63 | 64 | generated by Github Action Workflow 65 | 66 | ## NOT GETTING PR URL 67 | 68 | - name: 📤 Create PR 69 | run: | 70 | pr_url=$(gh pr create --base main --head development --title "Automated PR" --body "Automated PR created by GitHub Actions." | awk '/created/ {print $5}') 71 | echo "PR URL: $pr_url" 72 | 73 | - name: 🔀 Merge PR 74 | run: | 75 | pr_number=$(echo $pr_url | cut -d '/' -f 7) 76 | gh pr merge $pr_number --admin --rebase 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "support-module", 3 | "version": "0.0.14", 4 | "description": "This is support module for wrappid project.", 5 | "main": "index.js", 6 | "scripts": { 7 | "prepare": "husky install", 8 | "attributions:gen": "node ./scripts/attributions.gen.js", 9 | "code:lint": "eslint -c .eslintrc.js --ignore-path .gitignore .", 10 | "code:format": "npm run code:lint:app -- --fix", 11 | "code:lint:app": "eslint -c .eslintrc.js --ignore-path .gitignore ./app", 12 | "code:format:app": "npm run code:lint:app -- --fix", 13 | "code:lint:service": "eslint -c .eslintrc.js --ignore-path .gitignore service", 14 | "code:format:service": "npm run code:lint:service -- --fix", 15 | "test": "jest", 16 | "release": "standard-version --bumpFiles ./package.json ./package-lock.json " 17 | }, 18 | "license": "MIT", 19 | "author": { 20 | "name": "Wrappid", 21 | "email": "wrappid.framework@gmail.com", 22 | "url": "https://www.github.com/wrappid" 23 | }, 24 | "homepage": "https://github.com/wrappid/wrappid-module", 25 | "repository": { 26 | "type": "git", 27 | "url": "git:https://github.com/wrappid/support-module.git" 28 | }, 29 | "keywords": [ 30 | "wrappid", 31 | "module", 32 | "react", 33 | "react-native", 34 | "template" 35 | ], 36 | "devDependencies": { 37 | "@commitlint/cli": "~17.5.0", 38 | "@commitlint/config-conventional": "~17.4.4", 39 | "@commitlint/prompt-cli": "~17.5.0", 40 | "@faker-js/faker": "~8.1.0", 41 | "@types/supertest": "^6.0.2", 42 | "@wrappid/core": "0.0.605", 43 | "@wrappid/service-core": "0.0.134", 44 | "@wrappid/styles": "0.0.182", 45 | "eslint": "~8.40.0", 46 | "eslint-import-resolver-typescript": "~3.6.1", 47 | "eslint-plugin-etc": "~2.0.2", 48 | "eslint-plugin-import": "~2.27.5", 49 | "eslint-plugin-node": "~11.1.0", 50 | "eslint-plugin-promise": "~6.1.1", 51 | "eslint-plugin-react": "~7.33.2", 52 | "eslint-plugin-require-extensions": "~0.1.3", 53 | "eslint-plugin-sort-keys-fix": "~1.1.2", 54 | "eslint-plugin-unused-imports": "~2.0.0", 55 | "husky": "~8.0.3", 56 | "jest": "~29.7.0", 57 | "license-checker": "~25.0.1", 58 | "react-redux": "~8.0.5", 59 | "supertest": "~7.0.0", 60 | "yup": "~1.3.3", 61 | "ts-jest": "~29.1.2", 62 | "standard-version": "~9.5.0" 63 | }, 64 | "dependencies": { 65 | "@wrappid/core": "0.0.602", 66 | "@wrappid/styles": "0.0.181", 67 | "@wrappid/service-core": "0.0.134" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/components/ReportIssueForm.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { 4 | AppContainerLayout, 5 | CoreCard, CoreCardContent, 6 | CoreForm, CoreLayoutItem, FORM_EDIT_MODE, 7 | FORM_IDS 8 | } from "@wrappid/core"; 9 | import { WrappidDataContext } from "@wrappid/styles"; 10 | import { 11 | browserName, 12 | deviceType, 13 | fullBrowserVersion, 14 | isMobile, 15 | mobileModel, 16 | mobileVendor, 17 | osName, 18 | osVersion 19 | } from "react-device-detect"; 20 | import { useSelector } from "react-redux"; 21 | 22 | /** 23 | * @todo this package json is core's 24 | * should be the package json of user application 25 | */ 26 | 27 | import { getFullName, getLabel } from "../utils/app.utils"; 28 | 29 | export default function ReportIssueForm(props) { 30 | const { title, isStacktrace = true, stackTrace, labels } = props; 31 | const { config } = React.useContext(WrappidDataContext); 32 | const { packageInfo: packageJSON } = config; 33 | const { apiVersion } = useSelector((state) => state.app); 34 | const { role, user } = useSelector((state) => state.auth?.role || {}); 35 | 36 | return ( 37 | <> 38 | 39 | 40 | 41 | 74 | 75 | 76 | 77 | 78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Wrappid 2 | .wrappid/runtime 3 | .wrappid/wrappid.env 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # Snowpack dependency directory (https://snowpack.dev/) 49 | web_modules/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional stylelint cache 61 | .stylelintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variable files 79 | .env 80 | .env.development.local 81 | .env.test.local 82 | .env.production.local 83 | .env.local 84 | 85 | # parcel-bundler cache (https://parceljs.org/) 86 | .cache 87 | .parcel-cache 88 | 89 | # Next.js build output 90 | .next 91 | out 92 | 93 | # Nuxt.js build / generate output 94 | .nuxt 95 | dist 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and not Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # vuepress v2.x temp and cache directory 107 | .temp 108 | .cache 109 | 110 | # Docusaurus cache and generated files 111 | .docusaurus 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | 135 | # mac 136 | .DS_Store 137 | 138 | #attribution files 139 | scripts/attributions.gen.js 140 | # Package Config 141 | package-lock.json 142 | package.json 143 | -------------------------------------------------------------------------------- /service/routes.registry.ts: -------------------------------------------------------------------------------- 1 | const RoutesRegistry = { 2 | createIssueReport: { 3 | title: "Create Issue Github", 4 | url: "noauth/issue/create", 5 | authRequired: false, 6 | entityRef: "createIssueReport", 7 | reqMethod: "post", 8 | controllerRef: "createIssueReport", 9 | swaggerJson: { 10 | "tags": [ 11 | "Support Module" 12 | ], 13 | "requestBody": { 14 | "description": "Add education Info", 15 | "content": { 16 | "application/json": { 17 | "schema": { 18 | "type": "object", 19 | "properties": { 20 | "title": { 21 | "type": "string" 22 | }, 23 | "description": { 24 | "type": "string" 25 | }, 26 | "stepsToCreate": { 27 | "type": "string" 28 | }, 29 | "stackTrace": { 30 | "type": "string" 31 | }, 32 | "devInfo": { 33 | "type": "string" 34 | }, 35 | "reporterInfo": { 36 | "type": "string" 37 | }, 38 | "labels": { 39 | "type": "string" 40 | } 41 | } 42 | } 43 | } 44 | }, 45 | "required": true 46 | }, 47 | "responses": { 48 | "200": { 49 | "description": "Successful operation", 50 | "content": { 51 | "application/json": { 52 | "schema": { 53 | "type": "object", 54 | "properties": { 55 | "message": { 56 | "type": "string" 57 | } 58 | } 59 | }, 60 | "examples": { 61 | "CreateIssue": { 62 | "value": { 63 | "message": "Issue create success" 64 | } 65 | } 66 | } 67 | } 68 | } 69 | }, 70 | "404": { 71 | "description": "Request API Not Found!!" 72 | }, 73 | 74 | "500": { 75 | "description": "Internal Server Error", 76 | "content": { 77 | "application/json": { 78 | "schema": { 79 | "type": "object", 80 | "properties": { 81 | "message": { 82 | "type": "string" 83 | } 84 | } 85 | }, 86 | "examples": { 87 | "CreateIssue": { 88 | "value": { 89 | "message": "***" 90 | } 91 | } 92 | } 93 | } 94 | } 95 | } 96 | }, 97 | } 98 | } 99 | }; 100 | export default RoutesRegistry; 101 | -------------------------------------------------------------------------------- /scripts/attributions.gen.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | /* eslint-disable import/order */ 3 | /* eslint-disable no-console */ 4 | // eslint-disable-next-line no-undef 5 | const path = require("path"); 6 | // eslint-disable-next-line no-undef 7 | const licenseChecker = require("license-checker"); 8 | // eslint-disable-next-line no-undef, id-length 9 | const fs = require("fs"); 10 | 11 | // eslint-disable-next-line no-undef 12 | const packageJson = require("../package.json"); 13 | 14 | /** 15 | * Generate ATTRIBUTIONS.md file listing third-party dependencies and their licenses. 16 | */ 17 | 18 | try { 19 | // eslint-disable-next-line no-undef 20 | const packagePath = path.join(__dirname, "./../"); 21 | // eslint-disable-next-line no-undef 22 | const attributionMdPath = path.join(__dirname, "./../ATTRIBUTIONS.md"); 23 | 24 | // Attribution header 25 | const attributionHeader = ` 26 | ## ATTRIBUTIONS 27 | 28 | This file lists the third-party libraries, frameworks, and other components used in the ${packageJson?.name} repository, 29 | along with their respective licenses. 30 | It is important to comply with the licensing terms of these components when using the code 31 | \n`; 32 | 33 | licenseChecker.init({ start: packagePath }, function(err, packages) { 34 | if (err) { 35 | throw err; 36 | } else { 37 | let markdownContent = attributionHeader + generateMarkdown(packages); 38 | 39 | fs.writeFileSync(attributionMdPath, markdownContent); 40 | console.log("ATTRIBUTIONS.md file generated successfully."); 41 | } 42 | }); 43 | } catch (error) { 44 | console.error("An error occurred while generating ATTRIBUTIONS.md file."); 45 | console.error(error); 46 | } 47 | 48 | /** 49 | * Convert JSON data to markdown format. 50 | * @param {object} packages - JSON object containing package information. 51 | * @returns {string} Markdown content. 52 | */ 53 | function generateMarkdown(packages) { 54 | let markdownContent = ""; 55 | 56 | Object.keys(packages).forEach(packageName => { 57 | markdownContent += convertJsonToMDFormat(packageName, packages[packageName]); 58 | }); 59 | 60 | return markdownContent; 61 | } 62 | 63 | /** 64 | * Convert package information to markdown format. 65 | * @param {string} packageName - Name of the package. 66 | * @param {object} packageInfo - Information about the package. 67 | * @returns {string} Markdown content. 68 | */ 69 | function convertJsonToMDFormat(packageName, packageInfo) { 70 | const { 71 | licenses, repository, publisher, url, licenseFile, email 72 | } = packageInfo; 73 | 74 | const packageVersion = packageName.match(/[0-9.]+/g)?.join("") || "NA"; 75 | 76 | const extractPackageName = packageName => packageName.substring(0, packageName.lastIndexOf("@")).replace("@", ""); 77 | 78 | return ` 79 |
80 | ${packageName} 81 | 82 | #### Basic details about the package 83 | >| Key | Value | 84 | >| --- | --- | 85 | >| **Name** | ${extractPackageName(packageName) || "NA"} | 86 | >| **Version** | ${packageVersion} | 87 | >| **Repository** | ${repository || "NA"} | 88 | >| **Licenses** | [${licenses || "NA"}](${licenseFile}) | 89 | >| **Publisher** | ${publisher || "NA"} | 90 | >| **Contact** | ${email || "NA"} | 91 | >| **Homepage** | ${url || "NA"} | 92 | 93 | #### Use this package in your project 94 | \`\`\`bash 95 | npm i ${packageName} 96 | \`\`\` 97 |
98 | `; 99 | } -------------------------------------------------------------------------------- /service/functions/support.functions.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationContext } from "@wrappid/service-core"; 2 | 3 | import fetch from "node-fetch-commonjs"; 4 | 5 | /** 6 | * 7 | * @param {*} title 8 | * @param {*} description 9 | * @param {*} stepsToCreate 10 | * @param {*} stackTrace 11 | * @param {*} devInfo 12 | * @param {*} reporterInfo 13 | * @param {*} labels 14 | * @returns 15 | */ 16 | export const createIssue = async ( 17 | title: any, 18 | description: any, 19 | stepsToCreate: any, 20 | stackTrace: any, 21 | devInfo: any, 22 | reporterInfo: any, 23 | labels: any 24 | ) => { 25 | try { 26 | /** 27 | * @todo 28 | * - 29 | * 30 | */ 31 | // Description 32 | let issueBody = "## Description:\n"; 33 | if (description) { 34 | issueBody += description; 35 | } else { 36 | issueBody += "No description provided."; 37 | } 38 | // Steps to create 39 | issueBody += "\n## Steps To Create:\n"; 40 | if (stepsToCreate) { 41 | issueBody += stepsToCreate; 42 | } else { 43 | issueBody += "No steps provided."; 44 | } 45 | // Stack trace 46 | issueBody += "\n## Stack trace:\n"; 47 | if (stackTrace) { 48 | issueBody += "
" + stackTrace + "
"; 49 | } else { 50 | issueBody += "
No stack trace available.
"; 51 | } 52 | // Developer Information 53 | issueBody += "\n## Developer Information:\n"; 54 | if (devInfo) { 55 | issueBody += "| Key | Value |"; 56 | issueBody += "\n|---|---|"; 57 | issueBody += "\n| Frontend URL | " + devInfo?.frontend?.url + " |"; 58 | issueBody += "\n| Frontend Version | " + devInfo?.frontend?.version + " |"; 59 | issueBody += "\n| Backend URL | " + devInfo?.backend?.url + " |"; 60 | issueBody += "\n| Backend Version | " + devInfo?.backend?.version + " |"; 61 | issueBody += "\n| User Agent | " + devInfo?.client?.userAgent + " |"; 62 | issueBody += "\n| Device | " + devInfo?.client?.device + " |"; 63 | issueBody += "\n| Browser | " + devInfo?.client?.browser + " |"; 64 | issueBody += "\n| OS | " + devInfo?.client?.os + " |"; 65 | } else { 66 | issueBody += "No developer information provided."; 67 | } 68 | 69 | // Reporter Information 70 | issueBody += "\n## Reporter Information:\n"; 71 | if (reporterInfo) { 72 | issueBody += "| Key | Value |"; 73 | issueBody += "\n|---|---|"; 74 | issueBody += "\n| Name | " + reporterInfo?.name + " |"; 75 | issueBody += "\n| Email | " + reporterInfo?.email + " |"; 76 | issueBody += "\n| Phone | " + reporterInfo?.phone + " |"; 77 | issueBody += "\n| Role | " + reporterInfo?.role + " |"; 78 | issueBody += "\n| Creation Time | " + reporterInfo?.creationTime + " |"; 79 | } else { 80 | issueBody += "No reporter information provided."; 81 | } 82 | const issueData = { 83 | title: title, 84 | body: issueBody, 85 | labels: [...ApplicationContext.getContext("config").github.defaultLabels, ...labels], 86 | }; 87 | 88 | const result = await fetch(ApplicationContext.getContext("config").github.createIssueURL, { 89 | method: "POST", 90 | headers: { 91 | "Content-Type": "application/json", 92 | Authorization: "Bearer " + ApplicationContext.getContext("config").github.token, 93 | }, 94 | body: JSON.stringify(issueData), 95 | }) 96 | .then((response) => response.json()) 97 | .then((data) => { 98 | if (data) { 99 | return data; 100 | } else { 101 | throw new Error("Something went wrong."); 102 | } 103 | }) 104 | .catch((error:any) => { 105 | console.error("error: ", error); 106 | throw new Error(error); 107 | }); 108 | return result; 109 | } catch (error:any) { 110 | console.error(error); 111 | throw new Error(error?.message || "Something went wrong."); 112 | } 113 | }; 114 | 115 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.0.14](https://https//github.com/wrappid/support-module/compare/v0.0.13...v0.0.14) (2025-03-21) 6 | 7 | ### [0.0.13](https://https//github.com/wrappid/support-module/compare/v0.0.12...v0.0.13) (2025-02-20) 8 | 9 | ### [0.0.12](https://https//github.com/wrappid/support-module/compare/v0.0.11...v0.0.12) (2025-02-18) 10 | 11 | ### [0.0.11](https://https//github.com/wrappid/support-module/compare/v0.0.10...v0.0.11) (2025-02-13) 12 | 13 | ### [0.0.10](https://https//github.com/wrappid/support-module/compare/v0.0.9...v0.0.10) (2025-02-12) 14 | 15 | ### [0.0.9](https://https//github.com/wrappid/support-module/compare/v0.0.8...v0.0.9) (2025-02-10) 16 | 17 | ### [0.0.8](https://https//github.com/wrappid/support-module/compare/v0.0.7...v0.0.8) (2025-01-29) 18 | 19 | ### [0.0.7](https://https//github.com/wrappid/support-module/compare/v0.0.6...v0.0.7) (2025-01-28) 20 | 21 | ### [0.0.6](https://https//github.com/wrappid/support-module/compare/v0.0.5...v0.0.6) (2024-12-09) 22 | 23 | ### [0.0.5](https://https//github.com/wrappid/support-module/compare/v0.0.4...v0.0.5) (2024-11-18) 24 | 25 | 26 | ### Bug Fixes 27 | 28 | * **core:** :bug: core and auth related impact handled ([5460c3c](https://https//github.com/wrappid/support-module/commit/5460c3c7013cadd9709be2a95dad4d3637715e3b)) 29 | 30 | ### [0.0.4](https://https//github.com/wrappid/support-module/compare/v0.0.3...v0.0.4) (2024-10-25) 31 | 32 | 33 | ### Bug Fixes 34 | 35 | * **core:** :recycle: liniting fix ([e4377f4](https://https//github.com/wrappid/support-module/commit/e4377f46c4496c88942fa3d96fca3e75fa0f5307)), closes [#20](https://https//github.com/wrappid/support-module/issues/20) 36 | 37 | ### [0.0.3](https://https//github.com/wrappid/support-module/compare/v0.0.2...v0.0.3) (2024-05-07) 38 | 39 | 40 | ### Bug Fixes 41 | 42 | * **global:** :ambulance: impact handling for change in configprovider ([ca265c2](https://https//github.com/wrappid/support-module/commit/ca265c209ce5b4d07ae8caf14c82ce523ecf059c)), closes [#17](https://https//github.com/wrappid/support-module/issues/17) 43 | 44 | ### 0.0.2 (2024-03-23) 45 | 46 | 47 | ### Features 48 | 49 | * **global:** :bug: added validation for create issue req body ([5973448](https://https//github.com/wrappid/support-module/commit/59734483369b3210b2747da385934bb272b50140)), closes [#12](https://https//github.com/wrappid/support-module/issues/12) 50 | * **global:** :sparkles: cheking github issue exist or not ([d828887](https://https//github.com/wrappid/support-module/commit/d828887b7120ac70c3c0555a5a8413af497d9df0)), closes [#12](https://https//github.com/wrappid/support-module/issues/12) 51 | * **global:** :sparkles: create comment if same isssue exist ([a5c2eda](https://https//github.com/wrappid/support-module/commit/a5c2eda3e55fa492ac1f3e301325671512735b38)), closes [#12](https://https//github.com/wrappid/support-module/issues/12) 52 | * **global:** :sparkles: if issue exist create comment ([7be92ef](https://https//github.com/wrappid/support-module/commit/7be92ef1459eb58aac718ccc11cc43011d67cba5)), closes [#12](https://https//github.com/wrappid/support-module/issues/12) 53 | 54 | 55 | ### Bug Fixes 56 | 57 | * :art: styles related issues fix ([c77a383](https://https//github.com/wrappid/support-module/commit/c77a383e6759bbb81bfd7bf2682d3fdf792af8a6)), closes [#24](https://https//github.com/wrappid/support-module/issues/24) 58 | * :bug: correct the typo in ModuleStyles files ([ee2f71d](https://https//github.com/wrappid/support-module/commit/ee2f71d04a968369d2f8dfd13b61d4c4fdbac57a)), closes [#7](https://https//github.com/wrappid/support-module/issues/7) 59 | * **core:** :art: layout oriented changes ([ca96054](https://https//github.com/wrappid/support-module/commit/ca96054c1488d9a04606f6edd8017c9c026efdfd)), closes [#15](https://https//github.com/wrappid/support-module/issues/15) 60 | * **core:** :zap: merge from template ([8d61dd7](https://https//github.com/wrappid/support-module/commit/8d61dd7d391844a9c67438e451f66d7f4ada97a3)), closes [#15](https://https//github.com/wrappid/support-module/issues/15) 61 | 62 | ### 0.0.4 (2024-03-18) 63 | 64 | ### 0.0.3 (2024-03-16) 65 | 66 | ### 0.0.2 (2024-03-15) 67 | -------------------------------------------------------------------------------- /.eslint/app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef 2 | module.exports = { 3 | "env": { 4 | "browser": true, 5 | "es2021" : true, 6 | "node" : true, 7 | }, 8 | "extends" : ["eslint:recommended", "plugin:react/recommended", "plugin:import/recommended", "plugin:react/jsx-runtime"], 9 | "parserOptions" : { 10 | "ecmaVersion": "latest", 11 | "sourceType" : "module", 12 | }, 13 | "plugins": [ 14 | "etc", 15 | "import", 16 | "react", 17 | "sort-keys-fix", 18 | "unused-imports", 19 | ], 20 | "rules": { 21 | "array-bracket-newline": [ 22 | "error", 23 | { 24 | "minItems" : 5, 25 | "multiline": true, 26 | }, 27 | ], 28 | "array-bracket-spacing" : ["error", "never"], 29 | "array-element-newline" : ["error", { "minItems": 5, "multiline": true }], 30 | "comma-dangle" : ["error", { "arrays": "only-multiline", "objects": "only-multiline" }], 31 | "comma-spacing" : ["error", { "after": true, "before": false }], 32 | "etc/no-commented-out-code": "error", 33 | "id-length" : ["error", { "exceptions": ["i", "j", "id"], "min": 3, "properties": "never" }], 34 | "import/order" : [ 35 | "error", 36 | { 37 | "alphabetize": { 38 | "caseInsensitive": true, 39 | "order" : "asc", 40 | }, 41 | "groups" : ["builtin", "external", "internal"], 42 | "newlines-between": "always", 43 | "pathGroups" : [ 44 | { 45 | "group" : "builtin", 46 | "pattern" : "react", 47 | "position": "before", 48 | }, 49 | ], 50 | "pathGroupsExcludedImportTypes": ["react"], 51 | }, 52 | ], 53 | "indent" : ["error", 2, { "MemberExpression": 1, "SwitchCase": 1 }], 54 | "key-spacing" : ["error", { "align": "colon" }], 55 | "linebreak-style" : ["error", "unix"], 56 | "newline-after-var" : ["error", "always"], 57 | "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 3 }], 58 | "no-console" : "error", 59 | "no-multi-spaces" : ["error", { exceptions: { "VariableDeclarator": true } }], 60 | "no-multiple-empty-lines" : ["error", { "max": 1 }], 61 | "no-unused-vars" : ["error", { "args": "after-used", "vars": "all" }], 62 | "no-var" : "error", 63 | "object-curly-newline" : [ 64 | "error", 65 | { 66 | "ExportDeclaration": { "minProperties": 6, "multiline": true }, 67 | "ImportDeclaration": { "minProperties": 6, "multiline": true }, 68 | "ObjectExpression" : { "minProperties": 6, "multiline": true }, 69 | "ObjectPattern" : { "minProperties": 6, "multiline": true }, 70 | }, 71 | ], 72 | "object-curly-spacing" : ["error", "always"], 73 | "object-property-newline" : ["error", { "allowAllPropertiesOnSameLine": true }], 74 | "padding-line-between-statements": [ 75 | "error", 76 | { 77 | blankLine: "always", 78 | next : "*", 79 | prev : ["const", "let"], 80 | }, 81 | { 82 | blankLine: "any", 83 | next : ["const", "let"], 84 | prev : ["const", "let"], 85 | }, 86 | { 87 | blankLine: "always", 88 | next : "*", 89 | prev : ["case", "default"], 90 | } 91 | ], 92 | "quotes" : ["error", "double"], 93 | "react/jsx-first-prop-new-line" : "error", 94 | "react/jsx-max-props-per-line" : ["error", { "maximum": { "multi": 1, "single": 3 } }], 95 | "react/jsx-newline" : "error", 96 | "react/jsx-props-no-multi-spaces" : "error", 97 | "react/prop-types" : "off", 98 | "semi" : ["error", "always"], 99 | "sort-keys-fix/sort-keys-fix" : "error", 100 | "space-infix-ops" : ["error", { "int32Hint": false }], 101 | "unused-imports/no-unused-imports": "error", 102 | }, 103 | "settings": { "react": { "version": "detect" } }, 104 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `Wrappid` Module Boilerplate 2 | ``` 3 | _ _ 4 | __ ___ __ __ _ _ __ _ __ (_) __| | 5 | \ \ /\ / / '__/ _` | '_ \| '_ \| |/ _` | 6 | \ V V /| | | (_| | |_) | |_) | | (_| | 7 | \_/\_/ |_| \__,_| .__/| .__/|_|\__,_| 8 | |_| |_| 9 | 10 | ``` 11 | 12 | **This is a template documentation, @wrappid/toolkit uses this template to create module boilerplate.** 13 | 14 | - [`Wrappid` Module Boilerplate](#wrappid-module-boilerplate) 15 | - [1. Introduction](#1-introduction) 16 | - [2. Getting Started](#2-getting-started) 17 | - [2.1. What are my Pre-requisites?](#21-what-are-my-pre-requisites) 18 | - [2.2. How to Create?](#22-how-to-create) 19 | - [2.3 How to Use Modules?](#23-how-to-use-modules) 20 | - [2.3.1 Include module in `wrappid-[app|service]`](#231-include-module-in-wrappid-appservice) 21 | - [2.2.2 Exclude module from `wrappid-[app|service]`](#222-exclude-module-from-wrappid-appservice) 22 | - [2.3 Where to Code?](#23-where-to-code) 23 | - [2.3.1 Frontend](#231-frontend) 24 | - [2.3.2 Backend](#232-backend) 25 | - [2.4. How to see code in action?](#24-how-to-see-code-in-action) 26 | 27 | ## 1. Introduction 28 | 29 | This is a **module boilerplate** to build wrappid modules which serves specific technical needs or business specific needs. 30 | 31 | ## 2. Getting Started 32 | This getting started section will help you setup a basic module built using the `Wrappid` framework Wrappid Projects. Follow the below steps to get going. 33 | 34 | [2.1. What are my Pre-requisites?](#21-what-are-my-pre-requisites) 35 | 36 | [2.2. How to Create?](#22-how-to-create) 37 | 38 | [2.3 How to Use Modules?](#23-how-to-use-modules) 39 | 40 | 41 | ### 2.1. What are my Pre-requisites? 42 | 43 | - [Refer here](https://github.com/wrappid/#1-check-pre-requisites) 44 | - install @wrappid/toolkit globally. [Click here](https://github.com/wrappid/#2-install-wrappid-toolkit)for installation guide of @wrappid/toolkit. 45 | 46 | ### 2.2. How to Create? 47 | Run the below command to create Module Wrappid Project 48 | 49 | ```terminal 50 | wrappid init module 51 | ``` 52 | 53 | **Output:** 54 | ![wrappid-module](https://github.com/wrappid/.github/assets/61864488/fc0f4866-43d5-4e3a-92a6-7b3e0aa768ab) 55 | 56 | 57 | Now you have a `` Module Wrappid Project at the directory the command was executed from. 58 | 59 | > **_Note:_** _If you already have a wrappid-module project in your github, you need to clone it in the directory you have your `wrappid-[app|service]`._ 60 | 61 | ### 2.3 How to Use Modules? 62 | 63 | #### 2.3.1 Include module in `wrappid-[app|service]` 64 | 65 | > **_Note:_** _You cannot setup or start a wrappid-module project like wrappid-app and wrappid-service._ 66 | 67 | To use Wrappid module projects 68 | 69 | - You need to `include` the module into your `wrappid-[app|service]`, from inside of the root of `wrappid-[app|service]`. 70 | - Your module must be located in the parent directory of `wrappid-[app|service]` project. 71 | - Your `wrappid-[app|service]` should be setup. 72 | 73 | Run the below command from the root of the `wrappid-[app|service]` project you wish to include your module. 74 | 75 | ```terminal 76 | cd wrappid-[app|service] 77 | wrappid include 78 | ``` 79 | 80 | Wrappid modules are hot swappable, you can `include` and `exclude` a module while `wrappid-[app|service]` is running. 81 | 82 | 83 | 84 | #### 2.2.2 Exclude module from `wrappid-[app|service]` 85 | To exclude a wrappid module 86 | 87 | - You need to be inside at the root of `wrappid-[app|service]`, 88 | - Your module must be located in the parent directory of `wrappid-[app|service]` project. 89 | - Your `wrappid-[app|service]` should be setup. 90 | 91 | Run the below command from the root of the `wrappid-[app|service]` project you wish to exclude your module. 92 | 93 | ```terminal 94 | wrappid exclude 95 | ``` 96 | 97 | Make sure to not write `-module` following your 98 |
99 | Wrappid modules are hot swappable, you can `include` and `exclude` a module while `wrappid-[app|service]` is running. 100 | 101 | ### 2.3 Where to Code? 102 | For frontend, we write code in ./app/components 103 | 104 | For backend, we write code in ./service/components 105 | 106 | 107 | #### 2.3.1 Frontend 108 | We will now see how to write code for frontend in the module you have created. 109 | 110 | For example the file you created is: ./app/components/portfolioPage.js 111 | 112 | 113 | 114 | 115 | Then put an import of your code's function in components.registry.js 116 | ```js 117 | import portfolioPage from "./components/portfolioPage" 118 | 119 | //Add component page object 120 | export default function ComponentRegistry 121 | { 122 | PortfolioPage: {comp: portfolioPage} 123 | } 124 | ``` 125 | 126 | To know more about frontend wrappid app, [click here](https://github.com/wrappid/wrappid-app) 127 | 128 | #### 2.3.2 Backend 129 | 130 | 131 | ### 2.4. How to see code in action? 132 | To see what we wrote in the browser, we will put another entry for our new component 133 | 134 | Go to the routes.registry.js, 135 | ```js 136 | { 137 | portfolioPageRoute:{ 138 | Page: {AppComponent: "PortfolioPage" }, 139 | entityRef: 'uniquePortfolioPage', 140 | URL:'portfolio' 141 | } 142 | } 143 | ``` 144 | 145 | Now change your directory to the root of the project you wish to include this module into 146 | 147 | 148 | Run 149 | 150 | ```terminal 151 | wrappid include 152 | ``` 153 | 154 | 155 | And start your project! 156 | 157 | ```terminal 158 | wrappid start [web|mobile] --env=stage 159 | ``` 160 | 161 | 162 | You should be able to see render of your code at localhost:3000/portfolio 163 | -------------------------------------------------------------------------------- /.github/workflows/pr-guardrails.yml: -------------------------------------------------------------------------------- 1 | name : PR Guardrails 2 | run-name: > 3 | Validating PR #${{ github.event.pull_request.number }}, opened by ${{ github.actor }} 4 | 5 | on: pull_request 6 | 7 | jobs: 8 | branchname: 9 | name: Validate branch name 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Validate source branch name 14 | uses: actions-ecosystem/action-regex-match@v2 15 | id: branch_name_validation 16 | with: 17 | text: ${{ github.event.pull_request.head.ref }} 18 | regex: '^WRPD-(feature|bugfix|release|ci|enhancement|hotfix|refactor|deps|docs|experimental|security)?-[0-9]+$|^main$|^development$' 19 | 20 | - name: Print invalid branch name message 21 | if: ${{ steps.branch_name_validation.outputs.match == '' }} 22 | run: | 23 | echo ❌ ${{ github.event.pull_request.head.ref }} is not a valid branch name. 24 | exit 1 25 | 26 | - name: Print valid branch name message 27 | run: | 28 | echo ✅ ${{ github.event.pull_request.head.ref }} is a valid branch name. 29 | 30 | commitlint: 31 | name: Validate commit messages 32 | runs-on: ubuntu-latest 33 | 34 | steps: 35 | - name: Check out branch 36 | uses: actions/checkout@v3 37 | with: 38 | fetch-depth: 0 39 | 40 | - name: Use Node.js 41 | uses: actions/setup-node@v3 42 | with: 43 | cache: 'npm' 44 | 45 | - name: Setup Wrappid npm registry 46 | run: | 47 | npm config set @wrappid:registry https://npm.pkg.github.com/wrappid 48 | npm config set //npm.pkg.github.com/:_authToken ${{ secrets.WRAPPID_REGISTRY_TOKEN }} 49 | 50 | - name: Install commitlint 51 | run: | 52 | npm ci 53 | npm install conventional-changelog-conventionalcommits@7.0.2 54 | 55 | - name: Print versions 56 | run: | 57 | git --version 58 | node --version 59 | npm --version 60 | npx commitlint --version 61 | 62 | - name: Run commitlint 63 | run: > 64 | npx commitlint 65 | --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} 66 | --to ${{ github.event.pull_request.head.sha }} 67 | --verbose 68 | 69 | codelint-app: 70 | name: Validate app code style 71 | runs-on: ubuntu-latest 72 | 73 | steps: 74 | - name: Check out branch 75 | uses: actions/checkout@v3 76 | with: 77 | fetch-depth: 0 78 | 79 | - name: Use Node.js 80 | uses: actions/setup-node@v3 81 | with: 82 | cache: 'npm' 83 | registry-url: https://npm.pkg.github.com/wrappid 84 | token: ${{secrets.WRAPPID_REGISTRY_TOKEN}} 85 | 86 | - name: Setup Wrappid npm registry 87 | run: | 88 | npm config set @wrappid:registry https://npm.pkg.github.com/wrappid 89 | npm config set //npm.pkg.github.com/:_authToken ${{ secrets.WRAPPID_REGISTRY_TOKEN }} 90 | 91 | - name: Install ESLint 92 | run: | 93 | npm ci 94 | env: 95 | NODE_AUTH_TOKEN: ${{secrets.WRAPPID_REGISTRY_TOKEN}} 96 | 97 | - name: Print versions 98 | run: | 99 | node --version 100 | npm --version 101 | npx eslint --version 102 | 103 | - name: Find added/changed files 104 | id: git_diff 105 | run: | 106 | echo Searching for files added/changed in ${{ github.event.pull_request.head.ref }}, since the last commit in ${{ github.event.pull_request.base.ref }} 107 | echo "FILES_TO_LINT=$(git diff --name-only --diff-filter=AM --recursive ${{ github.event.pull_request.head.sha }}..${{ github.event.pull_request.base.sha }} ./app/*.{js,jsx,ts,tsx} | xargs)" >> $GITHUB_OUTPUT 108 | 109 | - name: Run ESLint for app 110 | run: | 111 | npm run code:lint:app ${{ steps.git_diff.outputs.FILES_TO_LINT }} 112 | 113 | codelint-service: 114 | name: Validate service code style 115 | runs-on: ubuntu-latest 116 | 117 | steps: 118 | - name: Check out branch 119 | uses: actions/checkout@v3 120 | with: 121 | fetch-depth: 0 122 | 123 | - name: Use Node.js 124 | uses: actions/setup-node@v3 125 | with: 126 | cache: 'npm' 127 | registry-url: https://npm.pkg.github.com/wrappid 128 | token: ${{secrets.WRAPPID_REGISTRY_TOKEN}} 129 | 130 | - name: Setup Wrappid npm registry 131 | run: | 132 | npm config set @wrappid:registry https://npm.pkg.github.com/wrappid 133 | npm config set //npm.pkg.github.com/:_authToken ${{ secrets.WRAPPID_REGISTRY_TOKEN }} 134 | 135 | - name: Install ESLint 136 | run: | 137 | npm ci 138 | env: 139 | NODE_AUTH_TOKEN: ${{secrets.WRAPPID_REGISTRY_TOKEN}} 140 | 141 | - name: Print versions 142 | run: | 143 | node --version 144 | npm --version 145 | npx eslint --version 146 | 147 | - name: Find added/changed files 148 | id: git_diff 149 | run: | 150 | echo Searching for files added/changed in ${{ github.event.pull_request.head.ref }}, since the last commit in ${{ github.event.pull_request.base.ref }} 151 | echo "FILES_TO_LINT=$(git diff --name-only --diff-filter=AM --recursive ${{ github.event.pull_request.head.sha }}..${{ github.event.pull_request.base.sha }} ./service/*.{js,jsx,ts,tsx} | xargs)" >> $GITHUB_OUTPUT 152 | 153 | - name: Run ESLint for service 154 | run: | 155 | npm run code:lint:service ${{ steps.git_diff.outputs.FILES_TO_LINT }} 156 | 157 | unit_tests: 158 | name: Run unit test cases 159 | runs-on: ubuntu-latest 160 | needs: [branchname, commitlint, codelint-app, codelint-service] 161 | 162 | steps: 163 | - name: Check out branch 164 | uses: actions/checkout@v3 165 | with: 166 | fetch-depth: 0 167 | 168 | - name: Run unit test cases 169 | run: echo "Ran unit test cases" 170 | 171 | e2e_tests: 172 | name: Run E2E test cases 173 | runs-on: ubuntu-latest 174 | needs: unit_tests 175 | 176 | steps: 177 | - name: Check out branch 178 | uses: actions/checkout@v3 179 | with: 180 | fetch-depth: 0 181 | 182 | - name: Use Node.js 183 | uses: actions/setup-node@v3 184 | with: 185 | cache: 'npm' 186 | 187 | - name: Setup Wrappid npm registry 188 | run: | 189 | npm config set @wrappid:registry https://npm.pkg.github.com/wrappid 190 | npm config set //npm.pkg.github.com/:_authToken ${{ secrets.WRAPPID_REGISTRY_TOKEN }} 191 | 192 | - name: Install node_modules 193 | run: npm ci 194 | 195 | - name: Run test cases 196 | run: | 197 | npm ci 198 | npm test 199 | echo "Ran test cases" 200 | -------------------------------------------------------------------------------- /service/functions/support.helper.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationContext } from "@wrappid/service-core"; 2 | import fetch from "node-fetch-commonjs"; 3 | import { createIssue } from "./support.functions"; 4 | 5 | type UrlsTitlesBodyObj = { 6 | url: string; 7 | title: string; 8 | body: string 9 | } 10 | 11 | export const createReportIssuePost = async (req:any) => { 12 | try { 13 | const { 14 | title, 15 | description, 16 | stepsToCreate, 17 | stackTrace, 18 | devInfo, 19 | reporterInfo, 20 | labels, 21 | } = req?.body || {}; 22 | 23 | const urlAndTitleArray: UrlsTitlesBodyObj[] = await getAllIssueInfo(); 24 | //chcke issue exist or not 25 | if(await matchString(urlAndTitleArray, title)){ 26 | const issueUrl: UrlsTitlesBodyObj = urlAndTitleArray.find((item:UrlsTitlesBodyObj) => item.title === title) as UrlsTitlesBodyObj; 27 | const commentUrl: string = issueUrl.url + "/comments"; 28 | const commentBody: string = await createCommentBody(issueUrl.body, { 29 | currentDescription: description, 30 | currentStepsToCreate: stepsToCreate, 31 | currentStackTrace: stackTrace, 32 | currentDevInfo: devInfo, 33 | currentReporterInfo: reporterInfo}); 34 | const headers = { 35 | "Content-Type": "application/json", 36 | "Authorization": `Bearer ${ApplicationContext.getContext("config").github.token}` 37 | }; 38 | const payload = { 39 | body: commentBody 40 | }; 41 | await fetch(commentUrl, { 42 | method: "POST", 43 | headers, 44 | body: JSON.stringify(payload) 45 | }) 46 | .then(response => { 47 | if (!response.ok) { 48 | throw new Error(`Error creating comment: ${response.status}`); 49 | } 50 | }); 51 | console.log("Comment created successfully!"); 52 | return {status:200, message: "Comment created successfully!" }; 53 | } 54 | 55 | const data = await createIssue( 56 | title, 57 | description, 58 | stepsToCreate, 59 | stackTrace, 60 | JSON.parse(devInfo), 61 | JSON.parse(reporterInfo), 62 | labels.map((label: { label: any; }) => label.label) 63 | ); 64 | 65 | if (data) { 66 | return {status:200, data: data }; 67 | } else { 68 | throw new Error("Something went wrong"); 69 | } 70 | } catch (error:any) { 71 | console.error(error); 72 | throw error; 73 | } 74 | }; 75 | 76 | 77 | async function getAllIssueInfo(): Promise { 78 | try { 79 | const response = await fetch(ApplicationContext.getContext("config").github.createIssueURL, { 80 | method: "GET", 81 | headers: { 82 | "Content-Type": "application/json", 83 | Authorization: "Bearer " + ApplicationContext.getContext("config").github.token, 84 | } 85 | }); 86 | if (!response.ok) { 87 | throw new Error(`Error fetching issues: ${response.statusText}`); 88 | } 89 | const issues:any = await response.json(); 90 | const urlAndTitleArray: UrlsTitlesBodyObj[] = issues.map((item: { url: string; title: string; body: string }) => ({ 91 | url: item.url, 92 | title: item.title, 93 | body: item.body 94 | })); 95 | return urlAndTitleArray; 96 | } catch (error) { 97 | console.log(error); 98 | throw error; 99 | } 100 | } 101 | 102 | async function matchString(urlAndTitleArray: UrlsTitlesBodyObj[], targetString: string): Promise { 103 | try { 104 | const stringArray: string[] = urlAndTitleArray.map((item: {title: string; }) => item.title); 105 | for (const string of stringArray) { 106 | if (string.includes(targetString)) { 107 | return true; 108 | } 109 | } 110 | return false; 111 | } catch (error) { 112 | console.log(error); 113 | throw error; 114 | } 115 | } 116 | 117 | 118 | async function createCommentBody(issueBody: string, { 119 | currentDescription, 120 | currentStepsToCreate, 121 | currentStackTrace, 122 | currentDevInfo, 123 | currentReporterInfo}:any): Promise { 124 | try { 125 | // Regular expression to match the Description section 126 | const descriptionRegex = /## Description:\n(.*?)(?=##|\n$)/s; 127 | const stepsToCreateRegex = /## Steps To Create:\n(.*?)\n##/s; 128 | const stackTraceRegex = /
([\s\S]*?)<\/pre>/;
129 |     // const developerInfoRegex = /## Developer Information:(.*?)## Reporter Information:/s;
130 |     // const reporterInformationRegex = /## Reporter Information:(.*?)\|(.*)/s;
131 | 
132 |     // Extract the description using match()
133 |     const descriptionMatch = issueBody.match(descriptionRegex);
134 |     const description = descriptionMatch ? descriptionMatch[1].trim() : "";
135 | 
136 |     // Extracting steps to create
137 |     const stepsToCreateMatch = issueBody.match(stepsToCreateRegex);
138 |     const stepsToCreate = stepsToCreateMatch ? stepsToCreateMatch[1].trim() : "";
139 | 
140 |     // Extracting stack trace
141 |     // const stackTracematch = stackTraceRegex.exec(issueBody);
142 |     const stackTracematch = issueBody.match(stackTraceRegex);
143 |     const stackTrace = stackTracematch ? stackTracematch[1].trim(): "";
144 |   
145 |     /*
146 |    // Extracting developer Info
147 |    const developerInfoMatch = issueBody.match(developerInfoRegex);
148 |    const developerInformation = developerInfoMatch ? developerInfoMatch[1].trim(): "";
149 | 
150 |    //Extracting Reporter Information
151 |    const reporterInformatinMatch = issueBody.match(reporterInformationRegex);
152 |    const reporterInformaion = reporterInformatinMatch ? reporterInformatinMatch[1].trim(): "";
153 |     */
154 | 
155 |     let commentBody = "## Description:\n";
156 |     if(currentDescription.trim() != description.trim() ){
157 |       if(currentDescription.trim() === ""){
158 |         commentBody += "No description provided.";
159 |       }else{
160 |         commentBody += currentDescription;
161 |       }
162 |     }else{
163 |       commentBody += "Same as above";
164 |     }
165 | 
166 |     commentBody += "\n## Steps To Create:\n";
167 |     if(currentStepsToCreate.trim() != stepsToCreate.trim()){
168 |       if(currentStepsToCreate.trim() === ""){
169 |         commentBody += "No steps provided.";
170 |       }else{
171 |         commentBody += currentStepsToCreate;
172 |       }
173 |     }else{
174 |       commentBody += "Same as above";
175 |     }
176 | 
177 |     commentBody += "\n## Stack trace:\n";
178 |     if(currentStackTrace.trim() != stackTrace.trim()){
179 |       if(currentStackTrace.trim() === ""){
180 |         issueBody += "
No stack trace available.
"; 181 | }else{ 182 | commentBody += "
" + stackTrace + "
"; 183 | } 184 | }else{ 185 | commentBody += "Same as above"; 186 | } 187 | 188 | /* 189 | commentBody += "\n## Developer Information:\n"; 190 | if(currentDevInfo.trim() != developerInformation.trim()){ 191 | if(currentDevInfo.trim() === ""){ 192 | commentBody += "No developer information provided."; 193 | }else{ 194 | currentDevInfo = JSON.parse(currentDevInfo); 195 | commentBody += "| Key | Value |"; 196 | commentBody += "\n|---|---|"; 197 | commentBody += "\n| Frontend URL | " + currentDevInfo?.frontend?.url + " |"; 198 | commentBody += "\n| Frontend Version | " + currentDevInfo?.frontend?.version + " |"; 199 | commentBody += "\n| Backend URL | " + currentDevInfo?.backend?.url + " |"; 200 | commentBody += "\n| Backend Version | " + currentDevInfo?.backend?.version + " |"; 201 | commentBody += "\n| User Agent | " + currentDevInfo?.client?.userAgent + " |"; 202 | commentBody += "\n| Device | " + currentDevInfo?.client?.device + " |"; 203 | commentBody += "\n| Browser | " + currentDevInfo?.client?.browser + " |"; 204 | commentBody += "\n| OS | " + currentDevInfo?.client?.os + " |"; 205 | } 206 | }else{ 207 | commentBody += "Same as above"; 208 | } 209 | */ 210 | 211 | /* 212 | commentBody += "\n## Reporter Information:\n"; 213 | if(currentReporterInfo.trim() != reporterInformaion.trim()){ 214 | if(currentReporterInfo.trim() === ""){ 215 | commentBody += "No reporter information provided."; 216 | }else{ 217 | currentReporterInfo = JSON.parse(currentReporterInfo); 218 | commentBody += "| Key | Value |"; 219 | commentBody += "\n|---|---|"; 220 | commentBody += "\n| Name | " + currentReporterInfo?.name + " |"; 221 | commentBody += "\n| Email | " + currentReporterInfo?.email + " |"; 222 | commentBody += "\n| Phone | " + currentReporterInfo?.phone + " |"; 223 | commentBody += "\n| Role | " + currentReporterInfo?.role + " |"; 224 | commentBody += "\n| Creation Time | " + currentReporterInfo?.creationTime + " |"; 225 | } 226 | }else{ 227 | commentBody += "Same as above"; 228 | } 229 | */ 230 | 231 | // Developer Information 232 | commentBody += "\n## Developer Information:\n"; 233 | if (currentDevInfo) { 234 | const devInfo = JSON.parse(currentDevInfo); 235 | commentBody += "| Key | Value |"; 236 | commentBody += "\n|---|---|"; 237 | commentBody += "\n| Frontend URL | " + devInfo?.frontend?.url + " |"; 238 | commentBody += "\n| Frontend Version | " + devInfo?.frontend?.version + " |"; 239 | commentBody += "\n| Backend URL | " + devInfo?.backend?.url + " |"; 240 | commentBody += "\n| Backend Version | " + devInfo?.backend?.version + " |"; 241 | commentBody += "\n| User Agent | " + devInfo?.client?.userAgent + " |"; 242 | commentBody += "\n| Device | " + devInfo?.client?.device + " |"; 243 | commentBody += "\n| Browser | " + devInfo?.client?.browser + " |"; 244 | commentBody += "\n| OS | " + devInfo?.client?.os + " |"; 245 | } else { 246 | commentBody += "No developer information provided."; 247 | } 248 | 249 | // Reporter Information 250 | commentBody += "\n## Reporter Information:\n"; 251 | if (currentReporterInfo) { 252 | const reporterInfo = JSON.parse(currentReporterInfo); 253 | commentBody += "| Key | Value |"; 254 | commentBody += "\n|---|---|"; 255 | commentBody += "\n| Name | " + reporterInfo?.name + " |"; 256 | commentBody += "\n| Email | " + reporterInfo?.email + " |"; 257 | commentBody += "\n| Phone | " + reporterInfo?.phone + " |"; 258 | commentBody += "\n| Role | " + reporterInfo?.role + " |"; 259 | commentBody += "\n| Creation Time | " + reporterInfo?.creationTime + " |"; 260 | } else { 261 | commentBody += "No reporter information provided."; 262 | } 263 | return commentBody; 264 | } catch (error) { 265 | console.log(error); 266 | throw error; 267 | } 268 | } --------------------------------------------------------------------------------