diff --git a/client/.madgerc b/client/.madgerc new file mode 100644 index 000000000..4425cb8ef --- /dev/null +++ b/client/.madgerc @@ -0,0 +1,18 @@ +{ + "fontSize": "10px", + "tsconfig": "tsconfig.json", + "fileExtensions": ["ts", "tsx", "js", "jsx"], + "backgroundColor": "#FFFFFF", + "textColor": "#FFFFFF", + "nodeColor": "black", + "noDependencyColor": "green", + "cyclicNodeColor": "red", + "edgeColor": "green", + "graphVizOptions": { + "G": { + "rankdir": "TB", + "layout": "neato", + "splines": "curved" + } + } +} \ No newline at end of file diff --git a/client/package.json b/client/package.json index e007508f9..7e715d2d8 100644 --- a/client/package.json +++ b/client/package.json @@ -20,7 +20,8 @@ "configapp": "script/config.bash", "start": "script/start.bash", "clean": "script/clean.bash", - "format": "prettier --ignore-path ../.gitignore --write \"**/*.{ts,tsx,css,scss}\"" + "format": "prettier --ignore-path ../.gitignore --write \"**/*.{ts,tsx,css,scss}\"", + "graph": "script/graph.bash" }, "eslintConfig": { "extends": [ diff --git a/client/script/clean.bash b/client/script/clean.bash index 04e7279ef..222a856e8 100755 --- a/client/script/clean.bash +++ b/client/script/clean.bash @@ -1,2 +1,3 @@ #!/bin/bash -rm -rf build/ node_modules/ coverage/ playwright-report/ \ No newline at end of file +rm -rf build/ node_modules/ coverage/ playwright-report/ +rm src.svg test.svg \ No newline at end of file diff --git a/client/script/graph.bash b/client/script/graph.bash new file mode 100755 index 000000000..01ac33756 --- /dev/null +++ b/client/script/graph.bash @@ -0,0 +1,9 @@ +#!/bin/bash +PATH="$(yarn bin):$PATH" +export PATH +printf "Generate dependency graph for code" + +madge --image src.svg src +madge --image test.svg test +#eval madge --image src.svg "$TS_CONFIG" "$EXTENSIONS" src +#madge --image test.svg --ts-config tsconfig.json --extensions ts,tsx test \ No newline at end of file diff --git a/docs/developer/client/client.md b/docs/developer/client/client.md index 5c961606e..b2993bc27 100644 --- a/docs/developer/client/client.md +++ b/docs/developer/client/client.md @@ -3,3 +3,7 @@ The [Website](https://github.com/INTO-CPS-Association/DTaaS/tree/feature/distributed-demo/client#readme) is how the end-users interact with the software platform. The website is being developed as a React single page web application. + +A dependency graph for the entire codebase of the react application is: + +![React website dependency graph](client-dep-graph.svg) diff --git a/docs/developer/client/src.svg b/docs/developer/client/src.svg new file mode 100644 index 000000000..f7bbcfa16 --- /dev/null +++ b/docs/developer/client/src.svg @@ -0,0 +1,565 @@ + + + + + + +G + + + +AppProvider.tsx + +AppProvider.tsx + + + +route/auth/AuthProvider.tsx + +route/auth/AuthProvider.tsx + + + +AppProvider.tsx->route/auth/AuthProvider.tsx + + + + + +store/store.ts + +store/store.ts + + + +AppProvider.tsx->store/store.ts + + + + + +util/auth/useOidcConfig.ts + +util/auth/useOidcConfig.ts + + + +route/auth/AuthProvider.tsx->util/auth/useOidcConfig.ts + + + + + +store/menu.slice.ts + +store/menu.slice.ts + + + +store/store.ts->store/menu.slice.ts + + + + + +store/auth.slice.ts + +store/auth.slice.ts + + + +store/store.ts->store/auth.slice.ts + + + + + +components/Iframe.tsx + +components/Iframe.tsx + + + +components/LinkButtons.tsx + +components/LinkButtons.tsx + + + +components/LinkIconsLib.tsx + +components/LinkIconsLib.tsx + + + +components/LinkButtons.tsx->components/LinkIconsLib.tsx + + + + + +util/envUtil.ts + +util/envUtil.ts + + + +components/LinkButtons.tsx->util/envUtil.ts + + + + + +util/envUtil.ts->store/store.ts + + + + + +components/tab/TabComponent.tsx + +components/tab/TabComponent.tsx + + + +components/tab/subcomponents/TabRender.tsx + +components/tab/subcomponents/TabRender.tsx + + + +components/tab/TabComponent.tsx->components/tab/subcomponents/TabRender.tsx + + + + + +components/tab/subcomponents/TabStyles.ts + +components/tab/subcomponents/TabStyles.ts + + + +components/tab/TabComponent.tsx->components/tab/subcomponents/TabStyles.ts + + + + + +index.tsx + +index.tsx + + + +index.tsx->AppProvider.tsx + + + + + +index.tsx->util/envUtil.ts + + + + + +page/LayoutPublic.tsx + +page/LayoutPublic.tsx + + + +index.tsx->page/LayoutPublic.tsx + + + + + +route/auth/Account.tsx + +route/auth/Account.tsx + + + +index.tsx->route/auth/Account.tsx + + + + + +route/auth/PrivateRoute.tsx + +route/auth/PrivateRoute.tsx + + + +index.tsx->route/auth/PrivateRoute.tsx + + + + + +route/auth/Signin.tsx + +route/auth/Signin.tsx + + + +index.tsx->route/auth/Signin.tsx + + + + + +route/digitaltwins/DigitalTwins.tsx + +route/digitaltwins/DigitalTwins.tsx + + + +index.tsx->route/digitaltwins/DigitalTwins.tsx + + + + + +route/library/Library.tsx + +route/library/Library.tsx + + + +index.tsx->route/library/Library.tsx + + + + + +route/workbench/Workbench.tsx + +route/workbench/Workbench.tsx + + + +index.tsx->route/workbench/Workbench.tsx + + + + + +page/Footer.tsx + +page/Footer.tsx + + + +page/LayoutPublic.tsx->page/Footer.tsx + + + + + +page/Layout.tsx + +page/Layout.tsx + + + +route/auth/Account.tsx->page/Layout.tsx + + + + + +route/auth/AccountTabs.tsx + +route/auth/AccountTabs.tsx + + + +route/auth/Account.tsx->route/auth/AccountTabs.tsx + + + + + +route/auth/WaitAndNavigate.tsx + +route/auth/WaitAndNavigate.tsx + + + +route/auth/PrivateRoute.tsx->route/auth/WaitAndNavigate.tsx + + + + + +route/digitaltwins/DigitalTwins.tsx->components/Iframe.tsx + + + + + +route/digitaltwins/DigitalTwins.tsx->util/envUtil.ts + + + + + +route/digitaltwins/DigitalTwins.tsx->components/tab/TabComponent.tsx + + + + + +route/digitaltwins/DigitalTwins.tsx->components/tab/subcomponents/TabRender.tsx + + + + + +route/digitaltwins/DigitalTwins.tsx->page/Layout.tsx + + + + + +route/digitaltwins/DigitalTwinTabData.ts + +route/digitaltwins/DigitalTwinTabData.ts + + + +route/digitaltwins/DigitalTwins.tsx->route/digitaltwins/DigitalTwinTabData.ts + + + + + +route/library/Library.tsx->components/Iframe.tsx + + + + + +route/library/Library.tsx->util/envUtil.ts + + + + + +route/library/Library.tsx->components/tab/TabComponent.tsx + + + + + +route/library/Library.tsx->components/tab/subcomponents/TabRender.tsx + + + + + +route/library/Library.tsx->page/Layout.tsx + + + + + +util/auth/Authentication.ts + +util/auth/Authentication.ts + + + +route/library/Library.tsx->util/auth/Authentication.ts + + + + + +route/library/LibraryTabData.ts + +route/library/LibraryTabData.ts + + + +route/library/Library.tsx->route/library/LibraryTabData.ts + + + + + +route/workbench/Workbench.tsx->components/LinkButtons.tsx + + + + + +route/workbench/Workbench.tsx->util/envUtil.ts + + + + + +route/workbench/Workbench.tsx->page/Layout.tsx + + + + + +page/DrawerComponent.tsx + +page/DrawerComponent.tsx + + + +page/DrawerHeaderComponent.tsx + +page/DrawerHeaderComponent.tsx + + + +page/DrawerComponent.tsx->page/DrawerHeaderComponent.tsx + + + + + +page/MenuItems.tsx + +page/MenuItems.tsx + + + +page/DrawerComponent.tsx->page/MenuItems.tsx + + + + + +page/MenuToolbar.tsx + +page/MenuToolbar.tsx + + + +page/DrawerComponent.tsx->page/MenuToolbar.tsx + + + + + +page/MenuToolbar.tsx->util/auth/Authentication.ts + + + + + +page/Layout.tsx->page/Footer.tsx + + + + + +page/Menu.tsx + +page/Menu.tsx + + + +page/Layout.tsx->page/Menu.tsx + + + + + +page/Menu.tsx->store/store.ts + + + + + +page/Menu.tsx->page/DrawerComponent.tsx + + + + + +page/Menu.tsx->page/MenuToolbar.tsx + + + + + +page/Menu.tsx->store/menu.slice.ts + + + + + +util/auth/Authentication.ts->util/envUtil.ts + + + + + +util/auth/Authentication.ts->store/auth.slice.ts + + + + + +page/Title.tsx + +page/Title.tsx + + + +route/IData.ts + +route/IData.ts + + + +route/auth/AccountTabs.tsx->components/tab/TabComponent.tsx + + + + + +route/auth/AccountTabs.tsx->components/tab/subcomponents/TabRender.tsx + + + + + +util/auth/useOidcConfig.ts->util/envUtil.ts + + + + + +route/auth/WaitAndNavigate.tsx->util/auth/Authentication.ts + + + + + +route/digitaltwins/DigitalTwinTabData.ts->route/IData.ts + + + + + +route/library/LibraryTabData.ts->route/IData.ts + + + + + diff --git a/docs/developer/client/test.svg b/docs/developer/client/test.svg new file mode 100644 index 000000000..e651b2c84 --- /dev/null +++ b/docs/developer/client/test.svg @@ -0,0 +1,607 @@ + + + + + + +G + + + +../src/components/Iframe.tsx + +../src/components/Iframe.tsx + + + +../src/components/tab/TabComponent.tsx + +../src/components/tab/TabComponent.tsx + + + +../src/components/tab/subcomponents/TabRender.tsx + +../src/components/tab/subcomponents/TabRender.tsx + + + +../src/components/tab/TabComponent.tsx->../src/components/tab/subcomponents/TabRender.tsx + + + + + +../src/components/tab/subcomponents/TabStyles.ts + +../src/components/tab/subcomponents/TabStyles.ts + + + +../src/components/tab/TabComponent.tsx->../src/components/tab/subcomponents/TabStyles.ts + + + + + +../src/page/DrawerComponent.tsx + +../src/page/DrawerComponent.tsx + + + +../src/page/DrawerHeaderComponent.tsx + +../src/page/DrawerHeaderComponent.tsx + + + +../src/page/DrawerComponent.tsx->../src/page/DrawerHeaderComponent.tsx + + + + + +../src/page/MenuItems.tsx + +../src/page/MenuItems.tsx + + + +../src/page/DrawerComponent.tsx->../src/page/MenuItems.tsx + + + + + +../src/page/MenuToolbar.tsx + +../src/page/MenuToolbar.tsx + + + +../src/page/DrawerComponent.tsx->../src/page/MenuToolbar.tsx + + + + + +../src/util/auth/Authentication.ts + +../src/util/auth/Authentication.ts + + + +../src/page/MenuToolbar.tsx->../src/util/auth/Authentication.ts + + + + + +../src/page/Footer.tsx + +../src/page/Footer.tsx + + + +../src/page/Layout.tsx + +../src/page/Layout.tsx + + + +../src/page/Layout.tsx->../src/page/Footer.tsx + + + + + +../src/page/Menu.tsx + +../src/page/Menu.tsx + + + +../src/page/Layout.tsx->../src/page/Menu.tsx + + + + + +../src/page/Menu.tsx->../src/page/DrawerComponent.tsx + + + + + +../src/page/Menu.tsx->../src/page/MenuToolbar.tsx + + + + + +../src/store/menu.slice.ts + +../src/store/menu.slice.ts + + + +../src/page/Menu.tsx->../src/store/menu.slice.ts + + + + + +../src/store/store.ts + +../src/store/store.ts + + + +../src/page/Menu.tsx->../src/store/store.ts + + + + + +../src/store/store.ts->../src/store/menu.slice.ts + + + + + +../src/store/auth.slice.ts + +../src/store/auth.slice.ts + + + +../src/store/store.ts->../src/store/auth.slice.ts + + + + + +../src/util/envUtil.ts + +../src/util/envUtil.ts + + + +../src/util/auth/Authentication.ts->../src/util/envUtil.ts + + + + + +../src/util/auth/Authentication.ts->../src/store/auth.slice.ts + + + + + +../src/route/IData.ts + +../src/route/IData.ts + + + +../src/route/auth/AuthProvider.tsx + +../src/route/auth/AuthProvider.tsx + + + +../src/util/auth/useOidcConfig.ts + +../src/util/auth/useOidcConfig.ts + + + +../src/route/auth/AuthProvider.tsx->../src/util/auth/useOidcConfig.ts + + + + + +../src/util/auth/useOidcConfig.ts->../src/util/envUtil.ts + + + + + +../src/route/auth/PrivateRoute.tsx + +../src/route/auth/PrivateRoute.tsx + + + +../src/route/auth/WaitAndNavigate.tsx + +../src/route/auth/WaitAndNavigate.tsx + + + +../src/route/auth/PrivateRoute.tsx->../src/route/auth/WaitAndNavigate.tsx + + + + + +../src/route/auth/WaitAndNavigate.tsx->../src/util/auth/Authentication.ts + + + + + +../src/route/library/Library.tsx + +../src/route/library/Library.tsx + + + +../src/route/library/Library.tsx->../src/components/Iframe.tsx + + + + + +../src/route/library/Library.tsx->../src/components/tab/TabComponent.tsx + + + + + +../src/route/library/Library.tsx->../src/components/tab/subcomponents/TabRender.tsx + + + + + +../src/route/library/Library.tsx->../src/page/Layout.tsx + + + + + +../src/route/library/Library.tsx->../src/util/auth/Authentication.ts + + + + + +../src/route/library/LibraryTabData.ts + +../src/route/library/LibraryTabData.ts + + + +../src/route/library/Library.tsx->../src/route/library/LibraryTabData.ts + + + + + +../src/route/library/Library.tsx->../src/util/envUtil.ts + + + + + +../src/route/library/LibraryTabData.ts->../src/route/IData.ts + + + + + +../src/util/envUtil.ts->../src/store/store.ts + + + + + +e2e/playwright/Auth.test.ts + +e2e/playwright/Auth.test.ts + + + +e2e/playwright/Links.ts + +e2e/playwright/Links.ts + + + +e2e/playwright/Auth.test.ts->e2e/playwright/Links.ts + + + + + +e2e/playwright/Menu.test.ts + +e2e/playwright/Menu.test.ts + + + +e2e/playwright/Menu.test.ts->e2e/playwright/Links.ts + + + + + +e2e/playwright/auth.setup.ts + +e2e/playwright/auth.setup.ts + + + +integration/authRedux.test.tsx + +integration/authRedux.test.tsx + + + +integration/authRedux.test.tsx->../src/route/auth/PrivateRoute.tsx + + + + + +integration/authRedux.test.tsx->../src/route/library/Library.tsx + + + + + +integration/authRedux.test.tsx->../src/store/auth.slice.ts + + + + + +unitTests/testUtils.tsx + +unitTests/testUtils.tsx + + + +integration/authRedux.test.tsx->unitTests/testUtils.tsx + + + + + +testUtil.ts + +testUtil.ts + + + +unitTests/Components/Iframe.test.tsx + +unitTests/Components/Iframe.test.tsx + + + +unitTests/Components/Linkbuttons.test.tsx + +unitTests/Components/Linkbuttons.test.tsx + + + +unitTests/Components/PrivateRoute.test.tsx + +unitTests/Components/PrivateRoute.test.tsx + + + +unitTests/Components/PrivateRoute.test.tsx->../src/route/auth/PrivateRoute.tsx + + + + + +unitTests/Components/PrivateRoute.test.tsx->unitTests/testUtils.tsx + + + + + +unitTests/Components/TabComponent.test.tsx + +unitTests/Components/TabComponent.test.tsx + + + +unitTests/Page/Layout.test.tsx + +unitTests/Page/Layout.test.tsx + + + +unitTests/Page/page.testUtils.tsx + +unitTests/Page/page.testUtils.tsx + + + +unitTests/Page/Layout.test.tsx->unitTests/Page/page.testUtils.tsx + + + + + +unitTests/Page/page.testUtils.tsx->unitTests/testUtils.tsx + + + + + +unitTests/Page/LayoutPublic.test.tsx + +unitTests/Page/LayoutPublic.test.tsx + + + +unitTests/Page/LayoutPublic.test.tsx->unitTests/Page/page.testUtils.tsx + + + + + +unitTests/Routes/DigitalTwins.test.tsx + +unitTests/Routes/DigitalTwins.test.tsx + + + +unitTests/Routes/DigitalTwins.test.tsx->unitTests/testUtils.tsx + + + + + +unitTests/__mocks__/global_mocks.ts + +unitTests/__mocks__/global_mocks.ts + + + +unitTests/Routes/DigitalTwins.test.tsx->unitTests/__mocks__/global_mocks.ts + + + + + +unitTests/Routes/Library.test.tsx + +unitTests/Routes/Library.test.tsx + + + +unitTests/Routes/Library.test.tsx->../src/route/auth/AuthProvider.tsx + + + + + +unitTests/Routes/Library.test.tsx->unitTests/testUtils.tsx + + + + + +unitTests/Routes/Library.test.tsx->unitTests/__mocks__/global_mocks.ts + + + + + +unitTests/Routes/SignIn.test.tsx + +unitTests/Routes/SignIn.test.tsx + + + +unitTests/Routes/Workbench.test.tsx + +unitTests/Routes/Workbench.test.tsx + + + +unitTests/Routes/Workbench.test.tsx->unitTests/testUtils.tsx + + + + + +unitTests/Util/Store.test.ts + +unitTests/Util/Store.test.ts + + + +unitTests/Util/envUtil.test.ts + +unitTests/Util/envUtil.test.ts + + + +unitTests/__mocks__/component_mocks.tsx + +unitTests/__mocks__/component_mocks.tsx + + + +unitTests/__mocks__/page_mocks.tsx + +unitTests/__mocks__/page_mocks.tsx + + + +unitTests/auth/AuthProvider.test.tsx + +unitTests/auth/AuthProvider.test.tsx + + + +unitTests/auth/AuthProvider.test.tsx->../src/route/auth/AuthProvider.tsx + + + + + +unitTests/auth/AuthProvider.test.tsx->../src/util/auth/useOidcConfig.ts + + + + + +unitTests/jest.setup.ts + +unitTests/jest.setup.ts + + + +unitTests/jest.setup.ts->unitTests/__mocks__/global_mocks.ts + + + + + +unitTests/jest.setup.ts->unitTests/__mocks__/component_mocks.tsx + + + + + +unitTests/jest.setup.ts->unitTests/__mocks__/page_mocks.tsx + + + + + diff --git a/docs/developer/servers/lib/src-dep-graph.svg b/docs/developer/servers/lib/src-dep-graph.svg new file mode 100644 index 000000000..546c00137 --- /dev/null +++ b/docs/developer/servers/lib/src-dep-graph.svg @@ -0,0 +1,193 @@ + + + + + + +G + + + +../util.ts + +../util.ts + + + +app.module.ts + +app.module.ts + + + +app.module.ts->../util.ts + + + + + +files/files.module.ts + +files/files.module.ts + + + +app.module.ts->files/files.module.ts + + + + + +files/resolvers/files.resolver.ts + +files/resolvers/files.resolver.ts + + + +files/files.module.ts->files/resolvers/files.resolver.ts + + + + + +files/services/files-service.factory.ts + +files/services/files-service.factory.ts + + + +files/files.module.ts->files/services/files-service.factory.ts + + + + + +files/services/gitlab-files.service.ts + +files/services/gitlab-files.service.ts + + + +files/files.module.ts->files/services/gitlab-files.service.ts + + + + + +files/services/local-files.service.ts + +files/services/local-files.service.ts + + + +files/files.module.ts->files/services/local-files.service.ts + + + + + +files/resolvers/files.resolver.ts->files/services/files-service.factory.ts + + + + + +files/interfaces/files.service.interface.ts + +files/interfaces/files.service.interface.ts + + + +files/resolvers/files.resolver.ts->files/interfaces/files.service.interface.ts + + + + + +types.ts + +types.ts + + + +files/resolvers/files.resolver.ts->types.ts + + + + + +files/services/files-service.factory.ts->files/services/gitlab-files.service.ts + + + + + +files/services/files-service.factory.ts->files/services/local-files.service.ts + + + + + +files/services/files-service.factory.ts->files/interfaces/files.service.interface.ts + + + + + +files/services/gitlab-files.service.ts->files/interfaces/files.service.interface.ts + + + + + +files/services/gitlab-files.service.ts->types.ts + + + + + +files/queries.ts + +files/queries.ts + + + +files/services/gitlab-files.service.ts->files/queries.ts + + + + + +files/services/local-files.service.ts->files/interfaces/files.service.interface.ts + + + + + +files/services/local-files.service.ts->types.ts + + + + + +files/interfaces/files.service.interface.ts->types.ts + + + + + +main.ts + +main.ts + + + +main.ts->app.module.ts + + + + + diff --git a/script/env.sh b/script/env.sh index 12185469e..8c853701a 100755 --- a/script/env.sh +++ b/script/env.sh @@ -84,4 +84,8 @@ sudo -H pip3 install mkdocs-with-pdf sudo -H pip3 install qrcode # Install markdownlint -sudo gem install mdl \ No newline at end of file +sudo gem install mdl + +# Install madge for generating dependency graphs of typescript projects +sudo apt-get install graphviz +sudo npm install -g madge \ No newline at end of file diff --git a/servers/execution/runner/package.json b/servers/execution/runner/package.json index df040d334..d753356d1 100644 --- a/servers/execution/runner/package.json +++ b/servers/execution/runner/package.json @@ -16,7 +16,8 @@ "syntax": "script/syntax.bash", "test": "script/test.bash", "test:nocov": "script/test.bash nocoverage", - "test:watchAll": "script/test.bash watchAll" + "test:watchAll": "script/test.bash watchAll", + "graph": "script/graph.bash" }, "bin": { "runner": "./dist/src/main.js" diff --git a/servers/execution/runner/script/clean.bash b/servers/execution/runner/script/clean.bash index d5c466b7d..e2b62928a 100755 --- a/servers/execution/runner/script/clean.bash +++ b/servers/execution/runner/script/clean.bash @@ -1,2 +1,3 @@ #!/bin/bash -rm -rf build node_modules coverage dist \ No newline at end of file +rm -rf build node_modules coverage dist +rm src.svg test.svg \ No newline at end of file diff --git a/servers/execution/runner/script/graph.bash b/servers/execution/runner/script/graph.bash new file mode 100755 index 000000000..af6695dc1 --- /dev/null +++ b/servers/execution/runner/script/graph.bash @@ -0,0 +1,6 @@ +#!/bin/bash +PATH="$(yarn bin):$PATH" +export PATH +printf "Generate graph for source code" +madge --image src.svg --ts-config tsconfig.json --extensions ts,tsx src +madge --image test.svg --ts-config tsconfig.json --extensions ts,tsx test \ No newline at end of file diff --git a/servers/lib/package.json b/servers/lib/package.json index 1d1d70972..2592e3e41 100644 --- a/servers/lib/package.json +++ b/servers/lib/package.json @@ -13,7 +13,8 @@ "clean": "script/clean.bash", "start": "script/start.bash", "syntax": "script/syntax.bash", - "test": "script/test.bash" + "test": "script/test.bash", + "graph": "script/graph.bash" }, "dependencies": { "@apollo/client": "^3.7.10", diff --git a/servers/lib/script/clean.bash b/servers/lib/script/clean.bash index d5c466b7d..e2b62928a 100755 --- a/servers/lib/script/clean.bash +++ b/servers/lib/script/clean.bash @@ -1,2 +1,3 @@ #!/bin/bash -rm -rf build node_modules coverage dist \ No newline at end of file +rm -rf build node_modules coverage dist +rm src.svg test.svg \ No newline at end of file diff --git a/servers/lib/script/graph.bash b/servers/lib/script/graph.bash new file mode 100755 index 000000000..af6695dc1 --- /dev/null +++ b/servers/lib/script/graph.bash @@ -0,0 +1,6 @@ +#!/bin/bash +PATH="$(yarn bin):$PATH" +export PATH +printf "Generate graph for source code" +madge --image src.svg --ts-config tsconfig.json --extensions ts,tsx src +madge --image test.svg --ts-config tsconfig.json --extensions ts,tsx test \ No newline at end of file