diff --git a/.git-hooks/pre-commit b/.git-hooks/pre-commit deleted file mode 100755 index 4c6c91173..000000000 --- a/.git-hooks/pre-commit +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh - -TOP_DIR="$(pwd)" -export TOP_DIR - -if git diff --cached --name-only | grep "^client/" >/dev/null; then - cd client || exit - yarn install - yarn format && yarn syntax -else - printf "No changes in the client directory. Skipping pre-commit hook.\n\n" -fi - -cd "$TOP_DIR" || exit -if git diff --cached --name-only | grep "^servers/execution/runner/" >/dev/null; then - cd "servers/execution/runner" || exit - yarn install - yarn format && yarn syntax -else - printf "No changes in the servers/execution/runner directory. Skipping pre-commit hook.\n\n" -fi diff --git a/.git-hooks/pre-push b/.git-hooks/pre-push deleted file mode 100755 index cdf518ae5..000000000 --- a/.git-hooks/pre-push +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env sh - -BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) -TOP_DIR="$(pwd)" -export TOP_DIR - -if git diff --name-only origin/"$BRANCH_NAME"...HEAD | grep "^client/" >/dev/null; then - cd client || exit - yarn install - yarn jest . --coverage=false -else - printf "No changes in the client directory. Skipping pre-push hook.\n\n" -fi - -cd "$TOP_DIR" || exit -if git diff --name-only origin/"$BRANCH_NAME"...HEAD | grep "^servers/execution/runner/" >/dev/null; then - cd "servers/execution/runner" || exit - yarn install - yarn test:nocov -else - printf "No changes in the servers/execution/runner/ directory. Skipping pre-push hook.\n\n" -fi diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000..ec30352a1 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,7 @@ +default: true +MD033: false +MD013: + code_blocks: false + tables: false +MD046: + style: "fenced" \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..b9d4dfd6f --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,88 @@ +default_install_hook_types: [pre-commit, pre-push] + +repos: + - repo: local + hooks: + - id: yarn-install-client + name: yarn install client + entry: bash + language: system + files: "^client/.*" + args: ["-c", "cd client && yarn install"] + - id: yarn-install-runner + name: yarn install runner + entry: bash + language: system + files: "^servers/execution/runner/.*" + args: ["-c", "cd servers/execution/runner && yarn install"] + - id: yarn-install-lib + name: yarn install lib + entry: bash + language: system + files: "^servers/lib/.*" + args: ["-c", "cd servers/lib && yarn install"] + + - id: yarn-jest-client + name: yarn jest client + entry: bash + language: system + files: "^client/.*" + args: ["-c", "cd client && yarn jest . --coverage=false"] + stages: [pre-push] + - id: yarn-test-runner + name: yarn test runner + entry: bash + language: system + files: "^servers/execution/runner/.*" + args: ["-c", "cd servers/execution/runner && yarn test:nocov"] + stages: [pre-push] + # - id: yarn-test-lib + # name: yarn test lib + # entry: bash + # language: system + # files: "^servers/lib/.*" + # args: ["-c", "cd servers/lib && yarn jest . --coverage=false"] + # stages: [pre-push] + + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + args: ["--ignore-path", "../.gitignore", "--write"] + files: '^(client|servers/execution/runner|servers/lib)/.*\.(ts|tsx|css|scss)$' + stages: [pre-commit] + + - repo: https://github.com/pre-commit/mirrors-eslint + rev: v8.54.0 + hooks: + - id: eslint + args: ["--fix"] + files: "^(client|servers/execution/runner|servers/lib)/.*" + stages: [pre-commit] + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.37.0 + hooks: + - id: markdownlint + files: '.*\.md$' + entry: ./script/markdownlint-hook.sh + verbose: true + stages: [pre-commit] + + - repo: https://github.com/syntaqx/git-hooks + rev: v0.0.18 + hooks: + - id: shellcheck + files: '.*' + stages: [pre-commit] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-json + files: '^(docs|deploy|script|ssl)/.*' + stages: [pre-commit] + - id: check-yaml + files: '^(docs|deploy|script|ssl)/.*' + stages: [pre-commit] + \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index c0ad1333c..c23748f41 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -20,10 +20,10 @@ * The INTO-CPS tool suite software and the INTO-CPS Association * Public License (ICAPL) are obtained from the INTO-CPS Association, either -* from the above address, from the URLs: http://www.into-cps.org or +* from the above address, from the URLs: or * in the INTO-CPS tool suite distribution. * GNU version 3 is obtained from: -* http://www.gnu.org/copyleft/gpl.html. +* . * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS @@ -291,11 +291,11 @@ This Agreement is governed by the laws of Denmark. The place of jurisdiction for all disagreements related to this Agreement, is Aarhus, Denmark. The EPL 1.0 license definition has been obtained from: -http://www.eclipse.org/legal/epl-v10.html. +. It is also reproduced in the INTO-CPS distribution. The GPL Version 3 license definition has been obtained from -http://www.gnu.org/copyleft/gpl.html. +. It is also reproduced in the INTO-CPS distribution. --- End of Definition of INTO-CPS Association Public License --- diff --git a/README.md b/README.md index 6bb1efd2a..ab65eed89 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,19 @@ to install and use the DTaaS software platform. You are welcome to open an [issue](https://github.com/INTO-CPS-Association/DTaaS/issues/new/choose) if there is a suggestion to improve the software. +If you find this repo useful for your research, please consider citing our paper: + +```bibtex +@misc{talasila2023digital, + title={Digital Twin as a Service (DTaaS): A Platform for Digital Twin Developers and Users}, + author={Prasad Talasila and Cláudio Gomes and Peter Høgh Mikkelsen and Santiago Gil Arboleda and Eduard Kamburjan and Peter Gorm Larsen}, + year={2023}, + eprint={2305.07244}, + archivePrefix={arXiv}, + primaryClass={cs.SE} +} +``` + ## :hammer_and_wrench: Development Setup This is a mono repo containing code for diff --git a/client/.prettierrc b/client/.prettierrc new file mode 100644 index 000000000..a20502b7f --- /dev/null +++ b/client/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} diff --git a/client/LICENSE.md b/client/LICENSE.md index c0ad1333c..c23748f41 100644 --- a/client/LICENSE.md +++ b/client/LICENSE.md @@ -20,10 +20,10 @@ * The INTO-CPS tool suite software and the INTO-CPS Association * Public License (ICAPL) are obtained from the INTO-CPS Association, either -* from the above address, from the URLs: http://www.into-cps.org or +* from the above address, from the URLs: or * in the INTO-CPS tool suite distribution. * GNU version 3 is obtained from: -* http://www.gnu.org/copyleft/gpl.html. +* . * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS @@ -291,11 +291,11 @@ This Agreement is governed by the laws of Denmark. The place of jurisdiction for all disagreements related to this Agreement, is Aarhus, Denmark. The EPL 1.0 license definition has been obtained from: -http://www.eclipse.org/legal/epl-v10.html. +. It is also reproduced in the INTO-CPS distribution. The GPL Version 3 license definition has been obtained from -http://www.gnu.org/copyleft/gpl.html. +. It is also reproduced in the INTO-CPS distribution. --- End of Definition of INTO-CPS Association Public License --- diff --git a/client/public/static/css/MaterialIcon.css b/client/public/static/css/MaterialIcon.css index 5d7418a3f..6700ea0f1 100644 --- a/client/public/static/css/MaterialIcon.css +++ b/client/public/static/css/MaterialIcon.css @@ -4,7 +4,9 @@ font-family: 'Material Icons'; font-style: normal; font-weight: 400; - src: local('Material Icons'), local('MaterialIcons-Regular'), + src: + local('Material Icons'), + local('MaterialIcons-Regular'), url(/static/font/MaterialIcons-Regular.woff2) format('woff2'), url(/static/font/MaterialIcons-Regular.woff) format('woff'), url(/static/font/MaterialIcons-Regular.ttf) format('truetype'); diff --git a/client/public/static/font/README.md b/client/public/static/font/README.md deleted file mode 100644 index 7fa35e599..000000000 --- a/client/public/static/font/README.md +++ /dev/null @@ -1,22 +0,0 @@ -The recommended way to use the Material Icons font is by linking to the web font hosted on Google Fonts: - -```html - - - - - - - - - - - - -``` - - diff --git a/client/src/components/tab/TabComponent.tsx b/client/src/components/tab/TabComponent.tsx index bbcec27c2..6ce250893 100644 --- a/client/src/components/tab/TabComponent.tsx +++ b/client/src/components/tab/TabComponent.tsx @@ -24,7 +24,7 @@ function renderScopeTabList(scope: TabData[][], subIndex: number): JSX.Element { function renderScopeTabPanels( scope: TabData[][], - subIndex: number + subIndex: number, ): JSX.Element { return ( <> diff --git a/client/src/index.tsx b/client/src/index.tsx index 40b8c7369..7db8206ed 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -57,7 +57,7 @@ const router = createBrowserRouter( ], { basename: `/${useURLbasename()}`, - } + }, ); const root = document.getElementById('root'); @@ -68,7 +68,7 @@ if (root) { - + , ); } else { throw Error("Couldn't find root element"); diff --git a/client/src/route/library/Library.tsx b/client/src/route/library/Library.tsx index fd13c6b5e..75356056d 100644 --- a/client/src/route/library/Library.tsx +++ b/client/src/route/library/Library.tsx @@ -32,7 +32,7 @@ export function createCombinedTabs() { /> ), - })) + })), ); } diff --git a/client/test/README.md b/client/test/README.md index dd62cfd60..757a98621 100644 --- a/client/test/README.md +++ b/client/test/README.md @@ -182,4 +182,3 @@ yarn test -e This command launches the test runner and executes all end-to-end tests. Make sure you have an active internet connection while running these tests, as they simulate real user interactions with your GitLab account. - diff --git a/client/test/e2e/playwright/Auth.test.ts b/client/test/e2e/playwright/Auth.test.ts index fef1af43e..b7d555967 100644 --- a/client/test/e2e/playwright/Auth.test.ts +++ b/client/test/e2e/playwright/Auth.test.ts @@ -13,7 +13,7 @@ test.describe('Tests on Authentication Flow', () => { .getByRole('button', { name: 'GitLab logo Sign In with GitLab' }) .click(); await expect( - page.getByRole('button', { name: 'Open settings' }) + page.getByRole('button', { name: 'Open settings' }), ).toBeVisible(); await expect(page).toHaveURL(/.*Library/); }); @@ -23,7 +23,7 @@ test.describe('Tests on Authentication Flow', () => { .getByRole('button', { name: 'GitLab logo Sign In with GitLab' }) .click(); await expect( - page.getByRole('button', { name: 'Open settings' }) + page.getByRole('button', { name: 'Open settings' }), ).toBeVisible(); await expect(page).toHaveURL(/.*Library/); diff --git a/client/test/e2e/playwright/Menu.test.ts b/client/test/e2e/playwright/Menu.test.ts index 8f2cdc6a2..97ff3e193 100644 --- a/client/test/e2e/playwright/Menu.test.ts +++ b/client/test/e2e/playwright/Menu.test.ts @@ -10,7 +10,7 @@ test.describe('Menu Links from first page (Layout)', () => { .getByRole('button', { name: 'GitLab logo Sign In with GitLab' }) .click(); await expect( - page.getByRole('button', { name: 'Open settings' }) + page.getByRole('button', { name: 'Open settings' }), ).toBeVisible(); await expect(page).toHaveURL(/.*Library/); }); @@ -19,7 +19,7 @@ test.describe('Menu Links from first page (Layout)', () => { await links.reduce(async (previousPromise, link) => { await previousPromise; const linkElement = await page.locator( - `div[role="button"]:has-text("${link.text}")` + `div[role="button"]:has-text("${link.text}")`, ); await expect(linkElement).toBeVisible(); }, Promise.resolve()); diff --git a/client/test/e2e/playwright/auth.setup.ts b/client/test/e2e/playwright/auth.setup.ts index 723a16f73..a97468ae9 100644 --- a/client/test/e2e/playwright/auth.setup.ts +++ b/client/test/e2e/playwright/auth.setup.ts @@ -42,7 +42,7 @@ setup('authenticate', async ({ page }) => { // 'Authorize' button did not appear within 4 seconds, so just ignore and continue. } await expect( - page.getByRole('button', { name: 'Open settings' }) + page.getByRole('button', { name: 'Open settings' }), ).toBeVisible(); const storage = await page.context().storageState(); diff --git a/client/test/integration/authRedux.test.tsx b/client/test/integration/authRedux.test.tsx index 5eda40ab4..bd59bb3e6 100644 --- a/client/test/integration/authRedux.test.tsx +++ b/client/test/integration/authRedux.test.tsx @@ -49,7 +49,7 @@ const setupTest = (authState: AuthState) => { , - { route: '/private', store } + { route: '/private', store }, ); }; @@ -75,7 +75,7 @@ describe('Redux and Authentication integration test', () => { expect(screen.getByText('Signin')).toBeInTheDocument(); expect(authReducer(undefined, { type: 'unknown' })).toEqual( - initialState.auth + initialState.auth, ); expect(store.getState().userName).toBe(undefined); }); diff --git a/client/test/unitTests/Components/Linkbuttons.test.tsx b/client/test/unitTests/Components/Linkbuttons.test.tsx index 6a467b681..27952ee2c 100644 --- a/client/test/unitTests/Components/Linkbuttons.test.tsx +++ b/client/test/unitTests/Components/Linkbuttons.test.tsx @@ -24,7 +24,7 @@ const getButtonIcon = (key: string) => const evaluateButtonSize = (expectedSize: number) => { buttons.forEach((button) => { expect( - getComputedStyle(getButtonIcon(button.key)).getPropertyValue('font-size') + getComputedStyle(getButtonIcon(button.key)).getPropertyValue('font-size'), ).toBe(`${expectedSize}rem`); }); }; @@ -38,7 +38,7 @@ describe('LinkButtons component default size', () => { buttons.forEach((button) => { expect(getButton(button.key).parentElement).toHaveAttribute( 'aria-label', - button.link + button.link, ); expect(getLabel(button.key).tagName).toBe('H6'); }); @@ -66,7 +66,7 @@ describe('LinkButtons component default size', () => { it('should use name from iconLib as label when avaiable', () => { expect(getLabel(buttons[0].key).textContent).toBe( - LinkIcons[buttons[0].key].name + LinkIcons[buttons[0].key].name, ); }); }); diff --git a/client/test/unitTests/Components/PrivateRoute.test.tsx b/client/test/unitTests/Components/PrivateRoute.test.tsx index 962204e6a..25ae748d8 100644 --- a/client/test/unitTests/Components/PrivateRoute.test.tsx +++ b/client/test/unitTests/Components/PrivateRoute.test.tsx @@ -30,7 +30,7 @@ const setupTest = (authState: AuthState) => { , - { route: '/private' } + { route: '/private' }, ); }; diff --git a/client/test/unitTests/Components/TabComponent.test.tsx b/client/test/unitTests/Components/TabComponent.test.tsx index 0c1751da4..881c1683d 100644 --- a/client/test/unitTests/Components/TabComponent.test.tsx +++ b/client/test/unitTests/Components/TabComponent.test.tsx @@ -11,7 +11,7 @@ describe('TabComponent', () => { test('renders an empty tab', () => { const { getByText } = render( - + , ); const emptyTab = getByText('Functions'); expect(emptyTab).toBeInTheDocument(); @@ -60,10 +60,10 @@ describe('TabComponent', () => { } expect( - screen.queryByText(assetTypeTabs[0].body.props.children) + screen.queryByText(assetTypeTabs[0].body.props.children), ).not.toBeInTheDocument(); expect( - screen.queryByText(assetTypeTabs[1].body.props.children) + screen.queryByText(assetTypeTabs[1].body.props.children), ).not.toBeInTheDocument(); }); diff --git a/client/test/unitTests/Page/LayoutPublic.test.tsx b/client/test/unitTests/Page/LayoutPublic.test.tsx index 08e8e9e58..0af0b5e1e 100644 --- a/client/test/unitTests/Page/LayoutPublic.test.tsx +++ b/client/test/unitTests/Page/LayoutPublic.test.tsx @@ -11,7 +11,7 @@ const PublicTestComponentId = 'public-component'; describe('LayoutPublic component with one element', () => { beforeEach(() => - renderLayoutWithRouter(LayoutPublic, [PublicTestComponentId]) + renderLayoutWithRouter(LayoutPublic, [PublicTestComponentId]), ); basicLayoutTestsWithSingleComponent(); diff --git a/client/test/unitTests/Page/page.testUtils.tsx b/client/test/unitTests/Page/page.testUtils.tsx index 631a5a555..2cca112b3 100644 --- a/client/test/unitTests/Page/page.testUtils.tsx +++ b/client/test/unitTests/Page/page.testUtils.tsx @@ -7,7 +7,7 @@ export const TestComponentIdList = ['component1', 'component2', 'component3']; export function renderLayoutWithRouter( Layout: (props: { children: React.ReactElement[] }) => React.ReactElement, - Children: string[] + Children: string[], ) { render({generateTestDivs(Children)}, { wrapper: BrowserRouter, diff --git a/client/test/unitTests/Routes/Library.test.tsx b/client/test/unitTests/Routes/Library.test.tsx index 1aaf87268..81fea8a8c 100644 --- a/client/test/unitTests/Routes/Library.test.tsx +++ b/client/test/unitTests/Routes/Library.test.tsx @@ -19,7 +19,7 @@ describe('Library with no props', () => { InitRouteTests( - + , ); itDisplaysContentOfTabs(assetType); diff --git a/client/test/unitTests/Routes/SignIn.test.tsx b/client/test/unitTests/Routes/SignIn.test.tsx index 5a097ef7d..e53d8f66d 100644 --- a/client/test/unitTests/Routes/SignIn.test.tsx +++ b/client/test/unitTests/Routes/SignIn.test.tsx @@ -23,11 +23,11 @@ describe('SignIn', () => { render( - + , ); expect( - screen.getByRole('button', { name: /Sign In With GitLab/i }) + screen.getByRole('button', { name: /Sign In With GitLab/i }), ).toBeInTheDocument(); }); @@ -35,7 +35,7 @@ describe('SignIn', () => { render( - + , ); const signInButton = screen.getByRole('button', { diff --git a/client/test/unitTests/Util/Store.test.ts b/client/test/unitTests/Util/Store.test.ts index b17c981f6..dd638a44c 100644 --- a/client/test/unitTests/Util/Store.test.ts +++ b/client/test/unitTests/Util/Store.test.ts @@ -25,7 +25,7 @@ describe('reducers', () => { describe('menu reducer', () => { const itShouldHandleMenuActions = ( actionCreator: () => { type: string }, - expectedValue: boolean + expectedValue: boolean, ) => { const newState = menuReducer(initialState.menu, actionCreator()); expect(newState.isOpen).toBe(expectedValue); @@ -33,7 +33,7 @@ describe('reducers', () => { it('menuReducer should return the initial menu state when an unknown action type is passed with an undefined state', () => { expect(menuReducer(undefined, { type: 'unknown' })).toEqual( - initialState.menu + initialState.menu, ); }); @@ -50,7 +50,7 @@ describe('reducers', () => { describe('auth reducer', () => { it('authReducer should return the initial menu state when an unknown action type is passed with an undefined state', () => { expect(authReducer(undefined, { type: 'unknown' })).toEqual( - initialState.auth + initialState.auth, ); }); diff --git a/client/test/unitTests/Util/envUtil.test.ts b/client/test/unitTests/Util/envUtil.test.ts index 75f937147..1c0edf925 100644 --- a/client/test/unitTests/Util/envUtil.test.ts +++ b/client/test/unitTests/Util/envUtil.test.ts @@ -53,10 +53,10 @@ describe('envUtil', () => { test('GetURL should return the correct enviroment variables', () => { expect(useURLforDT()).toBe( - `${testAppURL}/${testBasename}/${testUsername}/${testDT}` + `${testAppURL}/${testBasename}/${testUsername}/${testDT}`, ); expect(useURLforLIB()).toBe( - `${testAppURL}/${testBasename}/${testUsername}/${testLIB}` + `${testAppURL}/${testBasename}/${testUsername}/${testLIB}`, ); expect(useURLbasename()).toBe(testBasename); }); @@ -71,8 +71,8 @@ describe('envUtil', () => { const result = getWorkbenchLinkValues(); expect( result.every( - (el) => typeof el.key === 'string' && typeof el.link === 'string' - ) + (el) => typeof el.key === 'string' && typeof el.link === 'string', + ), ).toBe(true); }); @@ -83,8 +83,8 @@ describe('envUtil', () => { result.forEach((el, i) => { expect(el.link).toEqual( `${testAppURL}/${testBasename}/${testUsername}/${cleanURL( - testWorkbenchEndpoints[i] - )}` + testWorkbenchEndpoints[i], + )}`, ); }); }); diff --git a/client/test/unitTests/auth/AuthProvider.test.tsx b/client/test/unitTests/auth/AuthProvider.test.tsx index 14ca5e93b..87d7803c6 100644 --- a/client/test/unitTests/auth/AuthProvider.test.tsx +++ b/client/test/unitTests/auth/AuthProvider.test.tsx @@ -38,7 +38,7 @@ describe('AuthProvider', () => { const { getByText } = renderAuthProvider(); expect( - getByText('Authentication service unavailable...try again later') + getByText('Authentication service unavailable...try again later'), ).toBeInTheDocument(); }); diff --git a/client/test/unitTests/testUtils.tsx b/client/test/unitTests/testUtils.tsx index 295a654ea..c4a95534b 100644 --- a/client/test/unitTests/testUtils.tsx +++ b/client/test/unitTests/testUtils.tsx @@ -18,7 +18,7 @@ type RouterOptions = { export const renderWithRouter = ( ui: React.ReactElement, - { route = '/', store }: RouterOptions = {} + { route = '/', store }: RouterOptions = {}, ) => { window.history.pushState({}, 'Test page', route); @@ -26,7 +26,7 @@ export const renderWithRouter = ( ? render( - + , ) : render(); }; @@ -65,7 +65,7 @@ export function InitRouteTests(component: React.ReactElement) { } export function itDisplaysContentOfTabs( - tabs: { label: string; body: string }[] + tabs: { label: string; body: string }[], ) { it('should render labels of all tabs', () => { tabs.forEach((tab) => { @@ -117,7 +117,7 @@ export interface TabLabelURLPair { } export function itHasCorrectURLOfTabsWithIframe( - tablabelsURLpair: TabLabelURLPair[] + tablabelsURLpair: TabLabelURLPair[], ) { it('should render the Iframe component for the first tab with the correct title and URL', () => { tablabelsURLpair.forEach((tablabelURLpair) => { diff --git a/deploy/README.md b/deploy/README.md index 129cf30dd..f66e21561 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -105,9 +105,9 @@ registered on Gitlab: | Gitlab Variable Name | Variable name in Client env.js | Default Value | |:---|:---|:---| -| OAuth Provider | REACT_APP_AUTH_AUTHORITY | https://gitlab.foo.com/ | +| OAuth Provider | REACT_APP_AUTH_AUTHORITY | | | Application ID | REACT_APP_CLIENT_ID | -| Callback URL | REACT_APP_REDIRECT_URI | https://foo.com/Library | +| Callback URL | REACT_APP_REDIRECT_URI | | | Scopes | REACT_APP_GITLAB_SCOPES | openid, profile, read_user, read_repository, api | You can also see @@ -158,7 +158,7 @@ You can run this script multiple times until the installation is successful. ## Access the application -Now you should be able to access the DTaaS application at: _https://foo.com_ +Now you should be able to access the DTaaS application at: ## References diff --git a/deploy/services/README.md b/deploy/services/README.md index 62ce64329..26981eba4 100644 --- a/deploy/services/README.md +++ b/deploy/services/README.md @@ -13,8 +13,8 @@ The installation scripts in this directory install: ## Configure and Install The first step in installation is to specify the config of the services. -There are two configuration files. The __services.yml__ contains most -of configuration settings. The __mqtt-default.conf__ file contains +There are two configuration files. The **services.yml** contains most +of configuration settings. The **mqtt-default.conf** file contains the MQTT listening port. Update these two config files before proceeding with the installation of the services. diff --git a/deploy/vagrant/two-machine/README.md b/deploy/vagrant/two-machine/README.md index 393189e04..dbd641a53 100644 --- a/deploy/vagrant/two-machine/README.md +++ b/deploy/vagrant/two-machine/README.md @@ -41,8 +41,8 @@ Please change these to your unique website URLs. The first step is to define the network identity of the two VMs. For that, you need _server name_, _hostname_ and _MAC address_. The hostname is the network -URL at which the server can be accessed on the WWW. Please follow these steps -to make this work in your local environment. +URL at which the server can be accessed on the world wide web. Please follow +these steps to make this work in your local environment. Update the **boxes.json**. There are entries one for each server. The fields to update are: diff --git a/docs/LICENSE.md b/docs/LICENSE.md index 00cda86b7..c23748f41 100644 --- a/docs/LICENSE.md +++ b/docs/LICENSE.md @@ -20,9 +20,10 @@ * The INTO-CPS tool suite software and the INTO-CPS Association * Public License (ICAPL) are obtained from the INTO-CPS Association, either -* from the above address, from the URLs: http://www.into-cps.org or +* from the above address, from the URLs: or * in the INTO-CPS tool suite distribution. -* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. +* GNU version 3 is obtained from: +* . * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS @@ -36,16 +37,16 @@ --- End of INTO-CPS Association Public License Header --- -The ICAPL is a public license for the INTO-CPS tool suite with three -modes/alternatives +The ICAPL is a public license for the INTO-CPS tool +suite with three modes/alternatives (GPL, ICA-Internal-EPL, ICA-External-EPL) for use and redistribution, in source and/or binary/object-code form: -* GPL. Any party (member or non-member of the INTO-CPS Association) may use - and redistribute INTO-CPS tool suite under GPL version 3. +* GPL. Any party (member or non-member of the INTO-CPS Association) may use and + redistribute INTO-CPS tool suite under GPL version 3. -* Silver Level members of the INTO-CPS Association may also use and - redistribute the INTO-CPS tool suite under ICA-Internal-EPL conditions. +* Silver Level members of the INTO-CPS Association may also use and redistribute + the INTO-CPS tool suite under ICA-Internal-EPL conditions. * Gold Level members of the INTO-CPS Association may also use and redistribute The INTO-CPS tool suite under ICA-Internal-EPL or ICA-External-EPL conditions. @@ -54,34 +55,32 @@ Definitions of the INTO-CPS Association Public license modes: * GPL = GPL version 3. -* ICA-Internal-EPL = These INTO-CPA Association Public license conditions - together with +* ICA-Internal-EPL = These INTO-CPA Association Public + license conditions together with Internally restricted EPL, i.e., EPL version 1.0 with the Additional Condition - that use and redistribution by a member of the INTO-CPS Association is only - allowed within the INTO-CPS Association member's own organization - (i.e., its own legal entity), - or for a member of the INTO-CPS Association paying a membership fee - corresponding to - the size of the organization including all its affiliates, - use and redistribution + that use and redistribution by a member of the INTO-CPS Association is only allowed + within the INTO-CPS Association member's own + organization (i.e., its own legal entity), + or for a member of the INTO-CPS Association + paying a membership fee corresponding to + the size of the organization including all its affiliates, use and redistribution is allowed within/between its affiliates. -* ICA-External-EPL = These INTO-CPA Association Public license conditions - together with - Externally restricted EPL, i.e., EPL version 1.0 with the Additional - Condition - that use and redistribution by a member of the INTO-CPS Association, or - by a Licensed +* ICA-External-EPL = These INTO-CPA Association Public + license conditions together with + Externally restricted EPL, i.e., EPL version 1.0 with the Additional Condition + that use and redistribution by a member of the INTO-CPS Association, or by a Licensed Third Party Distributor having a redistribution agreement with that member, - to parties external to the INTO-CPS Association member’s own organization - (i.e., its own + to parties external to the INTO-CPS Association + member’s own organization (i.e., its own legal entity) is only allowed in binary/object-code form, except the case of - redistribution to other members the INTO-CPS Association to which source is - also allowed to be distributed. + redistribution to other members the INTO-CPS Association to which source is also + allowed to be distributed. [This has the consequence that an external party who wishes to use -the INTO-CPS Association in source form together with its own proprietary -software in all cases must be a member of the INTO-CPS Association]. +the INTO-CPS Association in source form together with +its own proprietary software in all +cases must be a member of the INTO-CPS Association]. In all cases of usage and redistribution by recipients, the following conditions also apply: @@ -102,8 +101,8 @@ c) A recipient must clearly indicate its chosen usage mode of ICAPL, in accompanying documentation and in a text file ICA-USAGE-MODE.txt, provided with the distribution. -d) Contributor(s) making a Contribution to the INTO-CPS Association thereby - also makes a +d) Contributor(s) making a Contribution to the + INTO-CPS Association thereby also makes a Transfer of Contribution Copyright. In return, upon the effective date of the transfer, ICA grants the Contributor(s) a Contribution License of the Contribution. ICA has the right to accept or refuse Contributions. @@ -121,68 +120,69 @@ ICA-Internal-EPL and ICA-External-EPL. INTO-CPS Association Public License version 1.0, i.e., the license defined here (the text between "--- Start of Definition of INTO-CPS Association Public License ---" and -"--- End of Definition of INTO-CPS Association Public License ---", or later -versions thereof. +"--- End of Definition of INTO-CPS Association +Public License ---", or later versions thereof. "ICAPL Header" means: INTO-CPS Association Public License Header version 1.2, i.e., the -text between "--- Start of Definition of INTO-CPS Association Public License ----" and -"--- End of INTO-CPS Association Public License Header ---, or later versions -thereof. +text between "--- Start of Definition +of INTO-CPS Association Public License ---" and +"--- End of INTO-CPS Association Public License Header ---, or later versions thereof. "Contribution" means: -a) in the case of the initial Contributor, the initial code and documentation +a) in the case of the initial Contributor, + the initial code and documentation distributed under ICAPL, and b) in the case of each subsequent Contributor: i) changes to the INTO-CPS tool suite, and ii) additions to the INTO-CPS tool suite; -where such changes and/or additions to the INTO-CPS tool suite originate from -and are -distributed by that particular Contributor. A Contribution 'originates' from -a Contributor if it was added to the INTO-CPS tool suite by such Contributor -itself or +where such changes and/or additions +to the INTO-CPS tool suite originate from and are +distributed by that particular Contributor. +A Contribution 'originates' from +a Contributor if it was added to the INTO-CPS +tool suite by such Contributor itself or anyone acting on such Contributor's behalf. For Contributors licensing the INTO-CPS tool suite under ICA-Internal-EPL or ICA-External-EPL conditions, the following conditions also hold: Contributions do not include additions to the distributed Program which: (i) -are separate modules of software distributed in conjunction with the INTO-CPS -tool suite +are separate modules of software distributed +in conjunction with the INTO-CPS tool suite under their own license agreement, (ii) are separate modules which are not -derivative works of the INTO-CPS tool suite, and (iii) are separate modules of -software distributed in conjunction with the INTO-CPS tool suite under their -own license agreement +derivative works of the INTO-CPS tool suite, and (iii) are separate modules of software +distributed in conjunction with the INTO-CPS tool suite under their own license agreement where these separate modules are merged with (weaved together with) modules of -The INTO-CPS tool suite to form new modules that are distributed as object code -or source code under their own license agreement, as allowed under the Additional +The INTO-CPS tool suite to form new modules +that are distributed as object code or source +code under their own license agreement, as allowed under the Additional Condition of internal distribution according to ICA-Internal-EPL and/or Additional Condition for external distribution according to ICA-External-EPL. "Transfer of Contribution Copyright" means that the Contributors of a Contribution transfer the ownership and the copyright of the Contribution to the INTO-CPS Association, the INTO-CPS Association Copyright owner, for -inclusion in the INTO-CPS tool suite. The transfer takes place upon the -effective date -when the Contribution is made available on the INTO-CPS Association web -site under ICAPL, by +inclusion in the INTO-CPS tool suite. +The transfer takes place upon the effective date +when the Contribution is made available on the +INTO-CPS Association web site under ICAPL, by such Contributors themselves or anyone acting on such Contributors' behalf. -The transfer is free of charge. If the Contributors or the -INTO-CPS Association so wish, -an optional Copyright transfer agreement can be signed between the INTO-CPS -Association and the Contributors. - -"Contribution License" means a license from the INTO-CPS Association to the -Contributors of the Contribution, effective on the date of the Transfer of -Contribution Copyright, -where the INTO-CPS Association grants the Contributors a non-exclusive, -world-wide, transferable, free of charge, perpetual license, including -sublicensing rights, to use, +The transfer is free of charge. If the +Contributors or the INTO-CPS Association so wish, +an optional Copyright transfer agreement can be signed +between the INTO-CPS Association and the Contributors. + +"Contribution License" means a license from the INTO-CPS +Association to the Contributors of the Contribution, effective +on the date of the Transfer of Contribution Copyright, +where the INTO-CPS Association grants the Contributors a +non-exclusive, world-wide, transferable, free of charge, +perpetual license, including sublicensing rights, to use, have used, modify, have modified, reproduce and or have reproduced the contributed material, for business and other purposes, including but not limited to evaluation, development, testing, integration and merging with @@ -194,8 +194,8 @@ the INTO-CPS tool chain. "The Program" means the Contributions distributed in accordance with ICAPL. -"The INTO-CPS tool chain" means the Contributions distributed in accordance -with ICAPL. +"The INTO-CPS tool chain" means the Contributions +distributed in accordance with ICAPL. "Recipient" means anyone who receives the INTO-CPS tool chain under ICAPL, including all Contributors. @@ -221,14 +221,13 @@ voting securities, by contract or otherwise. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY -LICENSE CONDITIONS OF ICAPL, THE INTO-CPS ASSOCIATION IS PROVIDED ON AN -"AS IS" +LICENSE CONDITIONS OF ICAPL, THE INTO-CPS ASSOCIATION IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the -appropriateness of using and distributing the INTO-CPS tool suite and assumes -all risks +appropriateness of using and distributing the +INTO-CPS tool suite and assumes all risks associated with its exercise of rights under ICAPL , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability @@ -251,8 +250,8 @@ ICA-External-EPL may choose to distribute (parts of) the INTO-CPS tool suite in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of ICAPL; or for the case of -redistribution of the INTO-CPS tool suite together with proprietary code it -is a dual +redistribution of the INTO-CPS tool suite +together with proprietary code it is a dual license where the INTO-CPS tool suite parts are distributed under ICAPL compatible conditions and the proprietary code is distributed under proprietary license conditions; and @@ -265,10 +264,11 @@ and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - iii) states that any provisions which differ from ICAPL are offered by that + iii) states that any provisions which differ + from ICAPL are offered by that Contributor alone and not by any other party; and - iv) states from where the source code for the INTO-CPS tool suite is - available, and + iv) states from where the source code + for the INTO-CPS tool suite is available, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. @@ -291,13 +291,11 @@ This Agreement is governed by the laws of Denmark. The place of jurisdiction for all disagreements related to this Agreement, is Aarhus, Denmark. The EPL 1.0 license definition has been obtained from: -http://www.eclipse.org/legal/epl-v10.html. -It is also reproduced in the INTO-CPS -distribution. +. +It is also reproduced in the INTO-CPS distribution. The GPL Version 3 license definition has been obtained from -http://www.gnu.org/copyleft/gpl.html. -It is also reproduced in the INTO-CPS -distribution. +. +It is also reproduced in the INTO-CPS distribution. --- End of Definition of INTO-CPS Association Public License --- diff --git a/docs/admin/client/auth.md b/docs/admin/client/auth.md index 0dabcfb13..e1ecb1aee 100644 --- a/docs/admin/client/auth.md +++ b/docs/admin/client/auth.md @@ -42,7 +42,8 @@ Here are the steps to get started: **6. Required Information from OAuth Application:** -- You will need the following information from the OAuth application registered on GitLab: +- You will need the following information from the OAuth application + registered on GitLab: |GitLab Variable Name|Variable Name in Client env.js|Default Value| |---|---|---| @@ -91,9 +92,9 @@ All of these instances can use the same gitlab instance for authentication. | DTaaS application URL | Gitlab Instance URL | Callback URL | Logout URL | Application ID | |:----|:----|:----|:----|:----| -| https://foo.com/au | https://foo.gitlab.com | https://foo.com/au/Library | https://foo.com/au | autogenerated by gitlab | -| https://foo.com/acme | https://foo.gitlab.com | https://foo.com/au/Library | https://foo.com/au | autogenerated by gitlab | -| https://foo.com/bar | https://foo.gitlab.com | https://foo.com/au/Library | https://foo.com/au | autogenerated by gitlab | +| | | | | autogenerated by gitlab | +| | | | | autogenerated by gitlab | +| | | | | autogenerated by gitlab | || If you are hosting multiple DTaaS instances on the same server, @@ -109,4 +110,4 @@ DTaaS application URL: https://foo.com/bar Gitlab instance URL: https://foo.gitlab.com Callback URL: https://foo.com/bar/Library Logout URL: https://foo.com/bar -``` \ No newline at end of file +``` diff --git a/docs/admin/guides/add_user.md b/docs/admin/guides/add_user.md index b0e37ce7d..c1907dd7c 100644 --- a/docs/admin/guides/add_user.md +++ b/docs/admin/guides/add_user.md @@ -7,11 +7,11 @@ This page will guide you on, how to add more users to the DTaas. Please do the f Make sure to replace **** and **** Select a port that is not already being used by the system. -__1. Add user:__ +**1. Add user:** Add the new user on the Gitlab instance. -__2. Setup a new workspace:__ +**2. Setup a new workspace:** The above code creates a new workspace for the new user based on _user2_. @@ -31,7 +31,7 @@ docker run -d \ mltooling/ml-workspace-minimal:0.13.2 ``` -__3. Add username and password:__ +**3. Add username and password:** The following code adds basic authentication for the new user. @@ -40,7 +40,7 @@ cd DTaaS/servers/config/gateway htpasswd auth ``` -__4. Add 'route' for new user:__ +**4. Add 'route' for new user:** We need to add a new route to the servers ingress. @@ -76,6 +76,6 @@ http: - url: 'http://localhost:' ``` -__5. Access the new user:__ +**5. Access the new user:** Log into the DTaaS application as new user. diff --git a/docs/admin/host.md b/docs/admin/host.md index d6d5e8560..f6209081d 100644 --- a/docs/admin/host.md +++ b/docs/admin/host.md @@ -118,9 +118,9 @@ You need the following information from the OAuth application registered on Gitl | Gitlab Variable Name | Variable name in Client env.js | Default Value | | :------------------- | :----------------------------- | :----------------------------------------------- | -| OAuth Provider | REACT_APP_AUTH_AUTHORITY | https://gitlab.foo.com/ | +| OAuth Provider | REACT_APP_AUTH_AUTHORITY | | | Application ID | REACT_APP_CLIENT_ID | -| Callback URL | REACT_APP_REDIRECT_URI | https://foo.com/Library | +| Callback URL | REACT_APP_REDIRECT_URI | | | Scopes | REACT_APP_GITLAB_SCOPES | openid, profile, read_user, read_repository, api | You can also see @@ -176,7 +176,7 @@ You can run this script multiple times until the installation is successful. ## Post-install Check -Now you should be able to access the DTaaS application at: _https://foo.com_. +Now you should be able to access the DTaaS application at: If you can following all the screenshots from [user website](../user/website/index.md). Everything is correctly setup. diff --git a/docs/admin/overview.md b/docs/admin/overview.md index a9f8cf35b..a182711cf 100644 --- a/docs/admin/overview.md +++ b/docs/admin/overview.md @@ -24,8 +24,8 @@ like _foo.com_. The installation setup assumes that the foo.com server is behind a reverse proxy / load balancer that provides https termination. You can still use the DTaaS software even if you do not have this reverse proxy. If you do -not have a reverse proxy, please replace _https://foo.com_ -with _http://foo.com_ in +not have a reverse proxy, please replace +with in [client env.js file](./client/CLIENT.md) and in [OAuth registration](./client/auth.md). Other installation configuration remains the same. diff --git a/docs/admin/servers/lib/LIB-MS.md b/docs/admin/servers/lib/LIB-MS.md index edb42c122..9bf20e36f 100644 --- a/docs/admin/servers/lib/LIB-MS.md +++ b/docs/admin/servers/lib/LIB-MS.md @@ -103,16 +103,16 @@ Display help. libms -h ``` -The config is saved `.env` file by convention. The __libms__ looks for +The config is saved `.env` file by convention. The **libms** looks for `.env` file in the working directory from which it is run. -If you want to run __libms__ without explicitly specifying the configuration +If you want to run **libms** without explicitly specifying the configuration file, run ```bash libms ``` -To run __libms__ with a custom config file, +To run **libms** with a custom config file, ```bash libms -c FILE-PATH diff --git a/docs/admin/trial.md b/docs/admin/trial.md index 485a2a4c1..0df8a1117 100644 --- a/docs/admin/trial.md +++ b/docs/admin/trial.md @@ -31,9 +31,9 @@ You need the following information from the OAuth application registered on Gitl | Gitlab Variable Name | Variable name in Client env.js | Default Value | | :------------------- | :----------------------------- | :----------------------------------------------- | -| OAuth Provider | REACT_APP_AUTH_AUTHORITY | https://gitlab.foo.com/ | +| OAuth Provider | REACT_APP_AUTH_AUTHORITY | | | Application ID | REACT_APP_CLIENT_ID | -| Callback URL | REACT_APP_REDIRECT_URI | https://foo.com/Library | +| Callback URL | REACT_APP_REDIRECT_URI | | | Scopes | REACT_APP_GITLAB_SCOPES | openid, profile, read_user, read_repository, api | You can also see diff --git a/docs/admin/vagrant/base-box.md b/docs/admin/vagrant/base-box.md index 3d3902b38..1cf32e90e 100644 --- a/docs/admin/vagrant/base-box.md +++ b/docs/admin/vagrant/base-box.md @@ -103,4 +103,4 @@ vagrant box add --name dtaas ./dtaas.vagrant ## References -Image sources: [Ubuntu logo](https://logodix.com/linux-ubuntu) \ No newline at end of file +Image sources: [Ubuntu logo](https://logodix.com/linux-ubuntu) diff --git a/docs/developer/index.md b/docs/developer/index.md index 4db623d3d..ba888b565 100644 --- a/docs/developer/index.md +++ b/docs/developer/index.md @@ -22,6 +22,16 @@ The git-hooks will ensure that your commits are formatted correctly and that the tests pass before you push the commits to remote repositories. +You can also run the git-hooks manually before committing or pushing +by using the run commands below. The autoupdate command will set the +revisions of the git repos used in the .pre-commit-config.yaml up to date. + +```bash +pre-commit run --hook-stage pre-commit # runs format and syntax checks +pre-commit run --hook-stage pre-push # runs test +pre-commit autoupdate # update hooks to latests versions +``` + Be aware that the tests may take a long time to run. If you want to skip the tests or formatting, you can use the `--no-verify` flag @@ -77,11 +87,11 @@ the code quality. The project code qualities are measured based on: -* Linting issues identified by +- Linting issues identified by [Code Climate](https://codeclimate.com/github/INTO-CPS-Association/DTaaS) -* Test coverage report collected by +- Test coverage report collected by [Codecov](https://codecov.io/gh/INTO-CPS-Association/DTaaS) -* Successful [github actions](https://github.com/INTO-CPS-Association/DTaaS/actions) +- Successful [github actions](https://github.com/INTO-CPS-Association/DTaaS/actions) ### Code Climate diff --git a/docs/user/servers/lib/LIB-MS.md b/docs/user/servers/lib/LIB-MS.md index 044db5f00..14149bd0a 100644 --- a/docs/user/servers/lib/LIB-MS.md +++ b/docs/user/servers/lib/LIB-MS.md @@ -38,7 +38,7 @@ To retrieve a list of files in a directory, use the following GraphQL query. Replace `path` with the desired directory path. -send requests to: https://foo.com/lib +send requests to: === "GraphQL Query" diff --git a/script/configure-git-hooks.sh b/script/configure-git-hooks.sh index 723d05bb5..67e2e860c 100755 --- a/script/configure-git-hooks.sh +++ b/script/configure-git-hooks.sh @@ -1,4 +1,6 @@ #!/bin/sh -git config --local core.hooksPath .git-hooks -printf "Git hooks configured successfully. See .git-hooks for more information." +pip install pre-commit +pre-commit install + +printf "Git hooks setup successfully. See .git/hooks/ for more information." diff --git a/script/docs.sh b/script/docs.sh index 252ec3ec3..4978519a6 100755 --- a/script/docs.sh +++ b/script/docs.sh @@ -13,7 +13,7 @@ COMMIT_HASH=$(git rev-parse --short HEAD) export COMMIT_HASH export MKDOCS_ENABLE_PDF_EXPORT=1 -echo ${VERSION} +echo "${VERSION}" if [ -d site ] then rm -rf site diff --git a/script/env.sh b/script/env.sh index e875e1c3c..2c1e71b16 100755 --- a/script/env.sh +++ b/script/env.sh @@ -22,6 +22,10 @@ sudo -H pip3 install qrcode sudo apt-get install -y rubygems sudo gem install mdl +# Install shellcheck +sudo apt-get install -y shellcheck + # Install madge for generating dependency graphs of typescript projects sudo apt-get install -y graphviz -sudo npm install -g madge \ No newline at end of file +sudo npm install -g madge + diff --git a/script/markdownlint-hook.sh b/script/markdownlint-hook.sh new file mode 100755 index 000000000..7c63ed5e8 --- /dev/null +++ b/script/markdownlint-hook.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# This script is used by the pre-commit hook to check the markdown files without exiting the commit process. +output=$(markdownlint "$@") +echo "$output" +exit 0 \ No newline at end of file diff --git a/servers/execution/runner/LICENSE.md b/servers/execution/runner/LICENSE.md index 5e134141b..c23748f41 100644 --- a/servers/execution/runner/LICENSE.md +++ b/servers/execution/runner/LICENSE.md @@ -20,11 +20,10 @@ * The INTO-CPS tool suite software and the INTO-CPS Association * Public License (ICAPL) are obtained from the INTO-CPS Association, either -* from the above address, from the URLs: -* http://www.into-cps.org or +* from the above address, from the URLs: or * in the INTO-CPS tool suite distribution. * GNU version 3 is obtained from: -* http://www.gnu.org/copyleft/gpl.html. +* . * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS @@ -38,15 +37,15 @@ --- End of INTO-CPS Association Public License Header --- -The ICAPL is a public license for the INTO-CPS tool suite with three modes/alternatives +The ICAPL is a public license for the INTO-CPS tool +suite with three modes/alternatives (GPL, ICA-Internal-EPL, ICA-External-EPL) for use and redistribution, in source and/or binary/object-code form: * GPL. Any party (member or non-member of the INTO-CPS Association) may use and redistribute INTO-CPS tool suite under GPL version 3. -* Silver Level members of the INTO-CPS Association - may also use and redistribute +* Silver Level members of the INTO-CPS Association may also use and redistribute the INTO-CPS tool suite under ICA-Internal-EPL conditions. * Gold Level members of the INTO-CPS Association may also use and redistribute @@ -60,29 +59,27 @@ Definitions of the INTO-CPS Association Public license modes: license conditions together with Internally restricted EPL, i.e., EPL version 1.0 with the Additional Condition that use and redistribution by a member of the INTO-CPS Association is only allowed - within the INTO-CPS Association member's own organization - (i.e., its own legal entity), - or for a member of the INTO-CPS Association paying a - membership fee corresponding to + within the INTO-CPS Association member's own + organization (i.e., its own legal entity), + or for a member of the INTO-CPS Association + paying a membership fee corresponding to the size of the organization including all its affiliates, use and redistribution is allowed within/between its affiliates. -* ICA-External-EPL = These INTO-CPA Association Public license - conditions together with - Externally restricted EPL, i.e., EPL version 1.0 with the - Additional Condition +* ICA-External-EPL = These INTO-CPA Association Public + license conditions together with + Externally restricted EPL, i.e., EPL version 1.0 with the Additional Condition that use and redistribution by a member of the INTO-CPS Association, or by a Licensed Third Party Distributor having a redistribution agreement with that member, - to parties external to the INTO-CPS Association member’s - own organization (i.e., its own + to parties external to the INTO-CPS Association + member’s own organization (i.e., its own legal entity) is only allowed in binary/object-code form, except the case of - redistribution to other members the - INTO-CPS Association to which source is also + redistribution to other members the INTO-CPS Association to which source is also allowed to be distributed. [This has the consequence that an external party who wishes to use -the INTO-CPS Association in source form together -with its own proprietary software in all +the INTO-CPS Association in source form together with +its own proprietary software in all cases must be a member of the INTO-CPS Association]. In all cases of usage and redistribution by recipients, the following @@ -106,8 +103,7 @@ c) A recipient must clearly indicate its chosen usage mode of ICAPL, d) Contributor(s) making a Contribution to the INTO-CPS Association thereby also makes a - Transfer of Contribution Copyright. In return, - upon the effective date of + Transfer of Contribution Copyright. In return, upon the effective date of the transfer, ICA grants the Contributor(s) a Contribution License of the Contribution. ICA has the right to accept or refuse Contributions. @@ -124,46 +120,46 @@ ICA-Internal-EPL and ICA-External-EPL. INTO-CPS Association Public License version 1.0, i.e., the license defined here (the text between "--- Start of Definition of INTO-CPS Association Public License ---" and -"--- End of Definition of INTO-CPS Association Public License ---", -or later versions thereof. +"--- End of Definition of INTO-CPS Association +Public License ---", or later versions thereof. "ICAPL Header" means: INTO-CPS Association Public License Header version 1.2, i.e., the -text between "--- Start of Definition of -INTO-CPS Association Public License ---" and -"--- End of INTO-CPS Association Public License Header ---, -or later versions thereof. +text between "--- Start of Definition +of INTO-CPS Association Public License ---" and +"--- End of INTO-CPS Association Public License Header ---, or later versions thereof. "Contribution" means: -a) in the case of the initial Contributor, the initial code and documentation +a) in the case of the initial Contributor, + the initial code and documentation distributed under ICAPL, and b) in the case of each subsequent Contributor: i) changes to the INTO-CPS tool suite, and ii) additions to the INTO-CPS tool suite; -where such changes and/or additions to the -INTO-CPS tool suite originate from and are -distributed by that particular Contributor. A Contribution 'originates' from -a Contributor if it was added to the INTO-CPS tool -suite by such Contributor itself or +where such changes and/or additions +to the INTO-CPS tool suite originate from and are +distributed by that particular Contributor. +A Contribution 'originates' from +a Contributor if it was added to the INTO-CPS +tool suite by such Contributor itself or anyone acting on such Contributor's behalf. For Contributors licensing the INTO-CPS tool suite under ICA-Internal-EPL or ICA-External-EPL conditions, the following conditions also hold: Contributions do not include additions to the distributed Program which: (i) -are separate modules of software distributed in -conjunction with the INTO-CPS tool suite +are separate modules of software distributed +in conjunction with the INTO-CPS tool suite under their own license agreement, (ii) are separate modules which are not derivative works of the INTO-CPS tool suite, and (iii) are separate modules of software distributed in conjunction with the INTO-CPS tool suite under their own license agreement -where these separate modules are merged with -(weaved together with) modules of -The INTO-CPS tool suite to form new modules that -are distributed as object code or source +where these separate modules are merged with (weaved together with) modules of +The INTO-CPS tool suite to form new modules +that are distributed as object code or source code under their own license agreement, as allowed under the Additional Condition of internal distribution according to ICA-Internal-EPL and/or Additional Condition for external distribution according to ICA-External-EPL. @@ -173,19 +169,19 @@ Contribution transfer the ownership and the copyright of the Contribution to the INTO-CPS Association, the INTO-CPS Association Copyright owner, for inclusion in the INTO-CPS tool suite. The transfer takes place upon the effective date -when the Contribution is made available on the INTO-CPS -Association web site under ICAPL, by +when the Contribution is made available on the +INTO-CPS Association web site under ICAPL, by such Contributors themselves or anyone acting on such Contributors' behalf. -The transfer is free of charge. If the Contributors or -the INTO-CPS Association so wish, +The transfer is free of charge. If the +Contributors or the INTO-CPS Association so wish, an optional Copyright transfer agreement can be signed between the INTO-CPS Association and the Contributors. -"Contribution License" means a license from the -INTO-CPS Association to the Contributors of the Contribution, -effective on the date of the Transfer of Contribution Copyright, -where the INTO-CPS Association grants the Contributors -a non-exclusive, world-wide, transferable, free of charge, +"Contribution License" means a license from the INTO-CPS +Association to the Contributors of the Contribution, effective +on the date of the Transfer of Contribution Copyright, +where the INTO-CPS Association grants the Contributors a +non-exclusive, world-wide, transferable, free of charge, perpetual license, including sublicensing rights, to use, have used, modify, have modified, reproduce and or have reproduced the contributed material, for business and other purposes, including but not @@ -198,8 +194,8 @@ the INTO-CPS tool chain. "The Program" means the Contributions distributed in accordance with ICAPL. -"The INTO-CPS tool chain" means the Contributions distributed -in accordance with ICAPL. +"The INTO-CPS tool chain" means the Contributions +distributed in accordance with ICAPL. "Recipient" means anyone who receives the INTO-CPS tool chain under ICAPL, including all Contributors. @@ -253,14 +249,11 @@ A Contributor licensing the INTO-CPS tool suite under ICA-Internal-EPL or ICA-External-EPL may choose to distribute (parts of) the INTO-CPS tool suite in object code form under its own license agreement, provided that: -a) it complies with the terms and conditions of ICAPL; -or for the case of -redistribution of the INTO-CPS tool suite together -with proprietary code it is a dual -license where the INTO-CPS tool suite parts are distributed -under ICAPL compatible -conditions and the proprietary code is distributed under -proprietary license +a) it complies with the terms and conditions of ICAPL; or for the case of +redistribution of the INTO-CPS tool suite +together with proprietary code it is a dual +license where the INTO-CPS tool suite parts are distributed under ICAPL compatible +conditions and the proprietary code is distributed under proprietary license conditions; and b) its license agreement: @@ -271,12 +264,12 @@ and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - iii) states that any provisions which differ from ICAPL are offered by that + iii) states that any provisions which differ + from ICAPL are offered by that Contributor alone and not by any other party; and - iv) states from where the source code for the -INTO-CPS tool suite is available, and -informs licensees how to obtain it in a -reasonable manner on or through a + iv) states from where the source code + for the INTO-CPS tool suite is available, and +informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the INTO-CPS tool suite is made available in source code form: @@ -298,11 +291,11 @@ This Agreement is governed by the laws of Denmark. The place of jurisdiction for all disagreements related to this Agreement, is Aarhus, Denmark. The EPL 1.0 license definition has been obtained from: -http://www.eclipse.org/legal/epl-v10.html. +. It is also reproduced in the INTO-CPS distribution. The GPL Version 3 license definition has been obtained from -http://www.gnu.org/copyleft/gpl.html. +. It is also reproduced in the INTO-CPS distribution. --- End of Definition of INTO-CPS Association Public License --- diff --git a/servers/execution/runner/README.md b/servers/execution/runner/README.md index 959270e5f..c0cb8434a 100644 --- a/servers/execution/runner/README.md +++ b/servers/execution/runner/README.md @@ -22,14 +22,14 @@ One digital twin runner is responsible for execution of a digital twin. ```bash yarn install # Install dependencies for the microservice -yarn syntax # analyzes source code for potential errors, style violations, and other issues, -yarn graph # generate dependency graphs in the code -yarn build # compile ES6 files into ES5 javascript files and copy all JS files into build/ directory -yarn test # run tests -yarn test:nocov # run the tests but do not report coverage -yarn test:watchAll #Watch changes in test/ and run the tests -yarn start # start the application -yarn clean # deletes directories "build", "coverage", and "dist" +yarn syntax # Analyze code for errors and style issues +yarn graph # Generate dependency graphs in the code +yarn build # Compile ES6 to ES5 and copy JS files to build/ directory +yarn test # Run tests +yarn test:nocov # Run the tests but do not report coverage +yarn test:watchAll # Watch changes in test/ and run the tests +yarn start # Start the application +yarn clean # Deletes directories "build", "coverage", and "dist" ``` ## :package: :ship: NPM package @@ -37,16 +37,16 @@ yarn clean # deletes directories "build", "coverage", and "dist" ### Github Package Registry The Github actions workflow of -[lib microservice](../../../.github/workflows/runner.yml) publishes the __runner__ +[lib microservice](../../../.github/workflows/runner.yml) publishes the **runner** into [public packages](https://github.com/orgs/INTO-CPS-Association/packages). ### Verdaccio - Local Package Registry Use the instructions in [publish npm package](../../../docs/developer/npm-packages.md) for help -with publishing __runner npm package__. +with publishing **runner npm package**. -Application of the advice given on that page for __runner__ will require +Application of the advice given on that page for **runner** will require running the following commands. ### Publish @@ -54,8 +54,8 @@ running the following commands. ```bash yarn install yarn build #the dist/ directory is needed for publishing step -yarn publish --no-git-tag-version #increments version in package.json, publishes to registry -yarn publish #increments version in package.json, publishes to registry and adds a git tag +yarn publish --no-git-tag-version #increments version and publishes to registry +yarn publish #increments version, publishes to registry and adds a git tag ``` ### Unpublish @@ -81,11 +81,11 @@ Access to the service on network is available at `http://:3000/` Two REST API routes are active. The route paths and the responses given for these two sources are: -| REST API Route | Return Value | Comment | -|:---|:---|:---| -| localhost:3000/phase | [ hello ] | The array get appended with each invocation. All the elements of are _array_. | -| localhost:3000/lifecycle/phase | _true_ | Always returns _true_ | -||| +| REST API Route | Return Value | Comment | +| :----------------------------- | :----------- | :------ | +| localhost:3000/phase | [ hello ] | Each invocation appends to _array_. | +| localhost:3000/lifecycle/phase | _true_ | Always returns _true_ | +| localhost:3000/phase | [ hello ] | array. | ## :balance_scale: License diff --git a/servers/lib/.prettierrc b/servers/lib/.prettierrc new file mode 100644 index 000000000..a20502b7f --- /dev/null +++ b/servers/lib/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} diff --git a/servers/lib/DEVELOPER.md b/servers/lib/DEVELOPER.md index 05b195732..186e72dbb 100644 --- a/servers/lib/DEVELOPER.md +++ b/servers/lib/DEVELOPER.md @@ -9,16 +9,17 @@ file. Please see [README](./README.md) for this information. ```bash yarn install # Install dependencies for the microservice -yarn syntax # analyzes source code for potential errors, style violations, and other issues, -yarn graph # generate dependency graphs in the code -yarn build # compile ES6 files into ES5 javascript files and copy them into dist/ directory -yarn test -a # run all tests -yarn test -e # run end-to-end tests -yarn test -i # run integration tests -yarn test -u # run unit tests -yarn start # start the application -yarn start -h # list of all the CLI commands -yarn clean # deletes directories "build", "coverage", and "dist" +yarn syntax # Analyze code for errors and style issues +yarn graph # Generate dependency graphs in the code +yarn build # Compile ES6 to ES5 and copy JS files to build/ directory +yarn test -a # Run all tests +yarn test -e # Run end-to-end tests +yarn test -i # Run integration tests +yarn test -u # Run unit tests +yarn start # Start the application +yarn start -h # List of all the CLI commands +yarn start # Start the application +yarn clean # Deletes directories "build", "coverage", and "dist" ``` ## :package: :ship: NPM package @@ -43,8 +44,8 @@ running the following commands. ```bash yarn install yarn build #the dist/ directory is needed for publishing step -yarn publish --no-git-tag-version #increments version in package.json, publishes to registry -yarn publish #increments version in package.json, publishes to registry and adds a git tag +yarn publish --no-git-tag-version #increments version and publishes to registry +yarn publish #increments version, publishes to registry and adds a git tag ``` ### Unpublish diff --git a/servers/lib/LICENSE.md b/servers/lib/LICENSE.md index a5273233f..c23748f41 100644 --- a/servers/lib/LICENSE.md +++ b/servers/lib/LICENSE.md @@ -20,11 +20,10 @@ * The INTO-CPS tool suite software and the INTO-CPS Association * Public License (ICAPL) are obtained from the INTO-CPS Association, either -* from the above address, from the URLs: -* http://www.into-cps.org or +* from the above address, from the URLs: or * in the INTO-CPS tool suite distribution. * GNU version 3 is obtained from: -* http://www.gnu.org/copyleft/gpl.html. +* . * This program is distributed WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS @@ -38,15 +37,15 @@ --- End of INTO-CPS Association Public License Header --- -The ICAPL is a public license for the INTO-CPS tool suite with three modes/alternatives +The ICAPL is a public license for the INTO-CPS tool +suite with three modes/alternatives (GPL, ICA-Internal-EPL, ICA-External-EPL) for use and redistribution, in source and/or binary/object-code form: * GPL. Any party (member or non-member of the INTO-CPS Association) may use and redistribute INTO-CPS tool suite under GPL version 3. -* Silver Level members of the INTO-CPS Association may also - use and redistribute +* Silver Level members of the INTO-CPS Association may also use and redistribute the INTO-CPS tool suite under ICA-Internal-EPL conditions. * Gold Level members of the INTO-CPS Association may also use and redistribute @@ -56,10 +55,9 @@ Definitions of the INTO-CPS Association Public license modes: * GPL = GPL version 3. -* ICA-Internal-EPL = These INTO-CPA Association - Public license conditions together with - Internally restricted EPL, i.e., EPL - version 1.0 with the Additional Condition +* ICA-Internal-EPL = These INTO-CPA Association Public + license conditions together with + Internally restricted EPL, i.e., EPL version 1.0 with the Additional Condition that use and redistribution by a member of the INTO-CPS Association is only allowed within the INTO-CPS Association member's own organization (i.e., its own legal entity), @@ -68,22 +66,20 @@ Definitions of the INTO-CPS Association Public license modes: the size of the organization including all its affiliates, use and redistribution is allowed within/between its affiliates. -* ICA-External-EPL = These INTO-CPA Association - Public license conditions together with - Externally restricted EPL, i.e., EPL - version 1.0 with the Additional Condition +* ICA-External-EPL = These INTO-CPA Association Public + license conditions together with + Externally restricted EPL, i.e., EPL version 1.0 with the Additional Condition that use and redistribution by a member of the INTO-CPS Association, or by a Licensed Third Party Distributor having a redistribution agreement with that member, - to parties external to the INTO-CPS - Association member’s own organization (i.e., its own + to parties external to the INTO-CPS Association + member’s own organization (i.e., its own legal entity) is only allowed in binary/object-code form, except the case of - redistribution to other members the - INTO-CPS Association to which source is also + redistribution to other members the INTO-CPS Association to which source is also allowed to be distributed. [This has the consequence that an external party who wishes to use -the INTO-CPS Association in source form -together with its own proprietary software in all +the INTO-CPS Association in source form together with +its own proprietary software in all cases must be a member of the INTO-CPS Association]. In all cases of usage and redistribution by recipients, the following @@ -105,8 +101,8 @@ c) A recipient must clearly indicate its chosen usage mode of ICAPL, in accompanying documentation and in a text file ICA-USAGE-MODE.txt, provided with the distribution. -d) Contributor(s) making a Contribution - to the INTO-CPS Association thereby also makes a +d) Contributor(s) making a Contribution to the + INTO-CPS Association thereby also makes a Transfer of Contribution Copyright. In return, upon the effective date of the transfer, ICA grants the Contributor(s) a Contribution License of the Contribution. ICA has the right to accept or refuse Contributions. @@ -124,44 +120,46 @@ ICA-Internal-EPL and ICA-External-EPL. INTO-CPS Association Public License version 1.0, i.e., the license defined here (the text between "--- Start of Definition of INTO-CPS Association Public License ---" and -"--- End of Definition of INTO-CPS -Association Public License ---", or later versions thereof. +"--- End of Definition of INTO-CPS Association +Public License ---", or later versions thereof. "ICAPL Header" means: INTO-CPS Association Public License Header version 1.2, i.e., the -text between "--- Start of Definition of -INTO-CPS Association Public License ---" and +text between "--- Start of Definition +of INTO-CPS Association Public License ---" and "--- End of INTO-CPS Association Public License Header ---, or later versions thereof. "Contribution" means: -a) in the case of the initial Contributor, the initial code and documentation +a) in the case of the initial Contributor, + the initial code and documentation distributed under ICAPL, and b) in the case of each subsequent Contributor: i) changes to the INTO-CPS tool suite, and ii) additions to the INTO-CPS tool suite; -where such changes and/or additions to the -INTO-CPS tool suite originate from and are -distributed by that particular Contributor. A Contribution 'originates' from -a Contributor if it was added to the INTO-CPS tool suite -by such Contributor itself or +where such changes and/or additions +to the INTO-CPS tool suite originate from and are +distributed by that particular Contributor. +A Contribution 'originates' from +a Contributor if it was added to the INTO-CPS +tool suite by such Contributor itself or anyone acting on such Contributor's behalf. For Contributors licensing the INTO-CPS tool suite under ICA-Internal-EPL or ICA-External-EPL conditions, the following conditions also hold: Contributions do not include additions to the distributed Program which: (i) -are separate modules of software distributed in -conjunction with the INTO-CPS tool suite +are separate modules of software distributed +in conjunction with the INTO-CPS tool suite under their own license agreement, (ii) are separate modules which are not derivative works of the INTO-CPS tool suite, and (iii) are separate modules of software distributed in conjunction with the INTO-CPS tool suite under their own license agreement where these separate modules are merged with (weaved together with) modules of -The INTO-CPS tool suite to form new modules that -are distributed as object code or source +The INTO-CPS tool suite to form new modules +that are distributed as object code or source code under their own license agreement, as allowed under the Additional Condition of internal distribution according to ICA-Internal-EPL and/or Additional Condition for external distribution according to ICA-External-EPL. @@ -171,19 +169,19 @@ Contribution transfer the ownership and the copyright of the Contribution to the INTO-CPS Association, the INTO-CPS Association Copyright owner, for inclusion in the INTO-CPS tool suite. The transfer takes place upon the effective date -when the Contribution is made available on the INTO-CPS -Association web site under ICAPL, by +when the Contribution is made available on the +INTO-CPS Association web site under ICAPL, by such Contributors themselves or anyone acting on such Contributors' behalf. -The transfer is free of charge. If the Contributors or -the INTO-CPS Association so wish, +The transfer is free of charge. If the +Contributors or the INTO-CPS Association so wish, an optional Copyright transfer agreement can be signed between the INTO-CPS Association and the Contributors. "Contribution License" means a license from the INTO-CPS -Association to the Contributors of the Contribution, -effective on the date of the Transfer of Contribution Copyright, -where the INTO-CPS Association grants the Contributors -a non-exclusive, world-wide, transferable, free of charge, +Association to the Contributors of the Contribution, effective +on the date of the Transfer of Contribution Copyright, +where the INTO-CPS Association grants the Contributors a +non-exclusive, world-wide, transferable, free of charge, perpetual license, including sublicensing rights, to use, have used, modify, have modified, reproduce and or have reproduced the contributed material, for business and other purposes, including but not @@ -252,8 +250,8 @@ ICA-External-EPL may choose to distribute (parts of) the INTO-CPS tool suite in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of ICAPL; or for the case of -redistribution of the INTO-CPS tool suite together -with proprietary code it is a dual +redistribution of the INTO-CPS tool suite +together with proprietary code it is a dual license where the INTO-CPS tool suite parts are distributed under ICAPL compatible conditions and the proprietary code is distributed under proprietary license conditions; and @@ -266,12 +264,12 @@ and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; - iii) states that any provisions which differ from ICAPL are offered by that + iii) states that any provisions which differ + from ICAPL are offered by that Contributor alone and not by any other party; and - iv) states from where the source code for the INTO-CPS -tool suite is available, and -informs licensees how to obtain it in a -reasonable manner on or through a + iv) states from where the source code + for the INTO-CPS tool suite is available, and +informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the INTO-CPS tool suite is made available in source code form: @@ -293,11 +291,11 @@ This Agreement is governed by the laws of Denmark. The place of jurisdiction for all disagreements related to this Agreement, is Aarhus, Denmark. The EPL 1.0 license definition has been obtained from: -http://www.eclipse.org/legal/epl-v10.html. +. It is also reproduced in the INTO-CPS distribution. The GPL Version 3 license definition has been obtained from -http://www.gnu.org/copyleft/gpl.html. +. It is also reproduced in the INTO-CPS distribution. --- End of Definition of INTO-CPS Association Public License --- diff --git a/servers/lib/README.md b/servers/lib/README.md index 1e9bab981..bc86b8e3a 100644 --- a/servers/lib/README.md +++ b/servers/lib/README.md @@ -88,16 +88,16 @@ Display help. libms -h ``` -The config is saved `.env` file by convention. The __libms__ looks for +The config is saved `.env` file by convention. The **libms** looks for `.env` file in the working directory from which it is run. -If you want to run __libms__ without explicitly specifying the configuration +If you want to run **libms** without explicitly specifying the configuration file, run ```bash libms ``` -To run __libms__ with a custom config file, +To run **libms** with a custom config file, ```bash libms -c FILE-PATH @@ -113,6 +113,7 @@ libms -c ".env.development" You can press `Ctl+C` to halt the application. -The microservice is available at: http://localhost:PORT/lib +The microservice is available at: 'localhost:PORT/lib' + The [API](https://into-cps-association.github.io/DTaaS/development/user/servers/lib/LIB-MS.html) page shows sample queries and responses. diff --git a/servers/lib/package.json b/servers/lib/package.json index 53a0477f2..6c856f270 100644 --- a/servers/lib/package.json +++ b/servers/lib/package.json @@ -13,6 +13,7 @@ "scripts": { "build": "script/build.bash", "clean": "script/clean.bash", + "format": "prettier --ignore-path ../.gitignore --write \"**/*.{ts,tsx,css,scss}\"", "start": "script/start.bash", "syntax": "script/syntax.bash", "test": "script/test.bash", diff --git a/servers/lib/src/app.module.ts b/servers/lib/src/app.module.ts index 851febdf4..4a6893e3f 100644 --- a/servers/lib/src/app.module.ts +++ b/servers/lib/src/app.module.ts @@ -1,25 +1,24 @@ -import { ConfigModule, ConfigService } from "@nestjs/config"; -import { Module } from "@nestjs/common"; -import { GraphQLModule } from "@nestjs/graphql"; -import { ApolloDriver } from "@nestjs/apollo"; -import { join } from "path"; -import FilesModule from "./files/files.module"; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { Module } from '@nestjs/common'; +import { GraphQLModule } from '@nestjs/graphql'; +import { ApolloDriver } from '@nestjs/apollo'; +import { join } from 'path'; +import FilesModule from './files/files.module'; @Module({ imports: [ ConfigModule.forRoot({ - isGlobal: true + isGlobal: true, }), GraphQLModule.forRootAsync({ driver: ApolloDriver, useFactory: (configService: ConfigService) => ({ autoSchemaFile: join(process.cwd(), 'src/schema.gql'), - path: configService.get("APOLLO_PATH") + path: configService.get('APOLLO_PATH'), }), - inject: [ConfigService] + inject: [ConfigService], }), FilesModule, - ] + ], }) - export default class AppModule {} diff --git a/servers/lib/src/bootstrap.ts b/servers/lib/src/bootstrap.ts index 217c088bf..3924622be 100644 --- a/servers/lib/src/bootstrap.ts +++ b/servers/lib/src/bootstrap.ts @@ -1,26 +1,29 @@ -import { NestFactory } from "@nestjs/core"; -import { ConfigService } from "@nestjs/config"; -import * as dotenv from "dotenv" -import AppModule from "./app.module"; +import { NestFactory } from '@nestjs/core'; +import { ConfigService } from '@nestjs/config'; +import * as dotenv from 'dotenv'; +import AppModule from './app.module'; type BootstrapOptions = { - config?: string - runHelp?: CallableFunction -} + config?: string; + runHelp?: CallableFunction; +}; export default async function bootstrap(options?: BootstrapOptions) { - const configFile = dotenv.config({path: options?.config ?? ".env", override: true}) + const configFile = dotenv.config({ + path: options?.config ?? '.env', + override: true, + }); if (configFile.error) { // eslint-disable-next-line no-console console.error(configFile.error); if (options.runHelp) { - options.runHelp() + options.runHelp(); } else { - process.exit(1) + process.exit(1); } - }; + } const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); - const port = configService.get("PORT"); + const port = configService.get('PORT'); await app.listen(port); } diff --git a/servers/lib/src/files/files.module.ts b/servers/lib/src/files/files.module.ts index d1463d83d..f051c9dd1 100644 --- a/servers/lib/src/files/files.module.ts +++ b/servers/lib/src/files/files.module.ts @@ -1,8 +1,8 @@ -import { Module } from "@nestjs/common"; -import FilesResolver from "./resolvers/files.resolver"; -import GitlabFilesService from "./services/gitlab-files.service"; -import FilesServiceFactory from "./services/files-service.factory"; -import LocalFilesService from "./services/local-files.service"; +import { Module } from '@nestjs/common'; +import FilesResolver from './resolvers/files.resolver'; +import GitlabFilesService from './services/gitlab-files.service'; +import FilesServiceFactory from './services/files-service.factory'; +import LocalFilesService from './services/local-files.service'; @Module({ providers: [ diff --git a/servers/lib/src/files/interfaces/files.service.interface.ts b/servers/lib/src/files/interfaces/files.service.interface.ts index 19d280850..c2aa56fe3 100644 --- a/servers/lib/src/files/interfaces/files.service.interface.ts +++ b/servers/lib/src/files/interfaces/files.service.interface.ts @@ -1,4 +1,4 @@ -import { Project } from "src/types"; +import { Project } from 'src/types'; // FileService interface export interface IFilesService { diff --git a/servers/lib/src/files/resolvers/files.resolver.ts b/servers/lib/src/files/resolvers/files.resolver.ts index bfd7a7471..bf323d05e 100644 --- a/servers/lib/src/files/resolvers/files.resolver.ts +++ b/servers/lib/src/files/resolvers/files.resolver.ts @@ -1,7 +1,7 @@ -import { Resolver, Query, Args } from "@nestjs/graphql"; -import { IFilesService } from "../interfaces/files.service.interface"; -import FilesServiceFactory from "../services/files-service.factory"; -import { Project } from "../../types"; +import { Resolver, Query, Args } from '@nestjs/graphql'; +import { IFilesService } from '../interfaces/files.service.interface'; +import FilesServiceFactory from '../services/files-service.factory'; +import { Project } from '../../types'; @Resolver() export default class FilesResolver { @@ -12,12 +12,12 @@ export default class FilesResolver { } @Query(() => Project) - async listDirectory(@Args("path") path: string): Promise { + async listDirectory(@Args('path') path: string): Promise { return this.filesService.listDirectory(path); } @Query(() => Project) - async readFile(@Args("path") path: string): Promise { + async readFile(@Args('path') path: string): Promise { return this.filesService.readFile(path); } } diff --git a/servers/lib/src/files/services/files-service.factory.ts b/servers/lib/src/files/services/files-service.factory.ts index 80d2f96f9..72147e8e6 100644 --- a/servers/lib/src/files/services/files-service.factory.ts +++ b/servers/lib/src/files/services/files-service.factory.ts @@ -1,8 +1,8 @@ -import { Injectable, Inject } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import { IFilesService } from "../interfaces/files.service.interface"; -import GitlabFilesService from "./gitlab-files.service"; -import LocalFilesService from "./local-files.service"; +import { Injectable, Inject } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { IFilesService } from '../interfaces/files.service.interface'; +import GitlabFilesService from './gitlab-files.service'; +import LocalFilesService from './local-files.service'; @Injectable() export default class FilesServiceFactory { @@ -10,18 +10,18 @@ export default class FilesServiceFactory { constructor( private configService: ConfigService, @Inject(GitlabFilesService) private gitlabFilesService: GitlabFilesService, - @Inject(LocalFilesService) private localFilesService: LocalFilesService + @Inject(LocalFilesService) private localFilesService: LocalFilesService, ) {} /* eslint-enable no-useless-constructor, no-empty-function */ - + create(): IFilesService { - const mode = this.configService.get("MODE"); - if (mode === "local") { + const mode = this.configService.get('MODE'); + if (mode === 'local') { return this.localFilesService; - } if (mode === "gitlab") { + } + if (mode === 'gitlab') { return this.gitlabFilesService; - } - throw new Error(`Invalid MODE: ${mode}`); - + } + throw new Error(`Invalid MODE: ${mode}`); } } diff --git a/servers/lib/src/files/services/gitlab-files.service.ts b/servers/lib/src/files/services/gitlab-files.service.ts index f0d81a63f..590889aa8 100644 --- a/servers/lib/src/files/services/gitlab-files.service.ts +++ b/servers/lib/src/files/services/gitlab-files.service.ts @@ -1,9 +1,9 @@ -import { Injectable } from "@nestjs/common"; -import { ConfigService } from "@nestjs/config"; -import axios from "axios"; -import { Project } from "src/types"; -import { IFilesService } from "../interfaces/files.service.interface"; -import { getDirectoryQuery, getReadFileQuery } from "../queries"; +import { Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import axios from 'axios'; +import { Project } from 'src/types'; +import { IFilesService } from '../interfaces/files.service.interface'; +import { getDirectoryQuery, getReadFileQuery } from '../queries'; type QueryFunction = (domain: string, parsedPath: string) => string; @@ -21,28 +21,28 @@ export default class GitlabFilesService implements IFilesService { } private async parseArguments( - path: string + path: string, ): Promise<{ domain: string; parsedPath: string }> { - const gitlabGroup = this.configService.get("GITLAB_GROUP"); - const pathParts: string[] = path.split("/"); + const gitlabGroup = this.configService.get('GITLAB_GROUP'); + const pathParts: string[] = path.split('/'); const project: string = pathParts[0]; // Only prepend the gitlabGroup if it's not already part of the path const domain: string = - project === gitlabGroup ? project : `${gitlabGroup }/${ project}`; + project === gitlabGroup ? project : `${gitlabGroup}/${project}`; - const parsedPath = pathParts.slice(1).join("/"); + const parsedPath = pathParts.slice(1).join('/'); return { domain, parsedPath }; } private async sendRequest(query: string): Promise { try { const response = await axios({ - url: "https://gitlab.com/api/graphql", - method: "post", + url: 'https://gitlab.com/api/graphql', + method: 'post', headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${this.configService.get("GITLAB_TOKEN")}`, + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.configService.get('GITLAB_TOKEN')}`, }, data: { query, @@ -50,13 +50,13 @@ export default class GitlabFilesService implements IFilesService { }); return response.data.data.project; } catch (error) { - throw new Error("Invalid query"); // Throw error instead of returning string + throw new Error('Invalid query'); // Throw error instead of returning string } } private async executeQuery( path: string, - getQuery: QueryFunction + getQuery: QueryFunction, ): Promise { const { domain, parsedPath } = await this.parseArguments(path); const query = getQuery(domain, parsedPath); diff --git a/servers/lib/src/files/services/local-files.service.ts b/servers/lib/src/files/services/local-files.service.ts index dac1f2433..cda4e7744 100644 --- a/servers/lib/src/files/services/local-files.service.ts +++ b/servers/lib/src/files/services/local-files.service.ts @@ -1,31 +1,31 @@ -import { Injectable, InternalServerErrorException } from "@nestjs/common"; -import * as fs from "fs"; -import { join } from "path"; -import { ConfigService } from "@nestjs/config"; -import { Project } from "src/types"; -import { IFilesService } from "../interfaces/files.service.interface"; +import { Injectable, InternalServerErrorException } from '@nestjs/common'; +import * as fs from 'fs'; +import { join } from 'path'; +import { ConfigService } from '@nestjs/config'; +import { Project } from 'src/types'; +import { IFilesService } from '../interfaces/files.service.interface'; @Injectable() export default class LocalFilesService implements IFilesService { - // eslint-disable-next-line no-useless-constructor, no-empty-function + // eslint-disable-next-line no-useless-constructor, no-empty-function constructor(private configService: ConfigService) {} async listDirectory(path: string): Promise { - const dataPath = this.configService.get("LOCAL_PATH"); + const dataPath = this.configService.get('LOCAL_PATH'); const fullPath = join(dataPath, path); const files = await fs.promises.readdir(fullPath); const edges = await Promise.all( - files.map((file) => LocalFilesService.getFileStats(fullPath, file)) + files.map((file) => LocalFilesService.getFileStats(fullPath, file)), ); const tree = { trees: { - edges: edges.filter((edge) => edge.node.type === "tree"), + edges: edges.filter((edge) => edge.node.type === 'tree'), }, blobs: { - edges: edges.filter((edge) => edge.node.type === "blob"), + edges: edges.filter((edge) => edge.node.type === 'blob'), }, }; @@ -33,29 +33,28 @@ export default class LocalFilesService implements IFilesService { } async readFile(path: string): Promise { - const dataPath = this.configService.get("LOCAL_PATH"); + const dataPath = this.configService.get('LOCAL_PATH'); const fullpath = join(dataPath, path); try { const content = await ( - await fs.promises.readFile(fullpath, "utf8") + await fs.promises.readFile(fullpath, 'utf8') ).trim(); - const name = path.split("/").pop(); // extract file name from the path + const name = path.split('/').pop(); // extract file name from the path return LocalFilesService.formatResponse(name, content); } catch (error) { - throw new InternalServerErrorException("Error reading file"); + throw new InternalServerErrorException('Error reading file'); } } private static async getFileStats(fullPath: string, file: string) { const stats = await fs.promises.lstat(join(fullPath, file)); if (stats.isDirectory()) { - return { node: { name: file, type: "tree" } }; - } - return { node: { name: file, type: "blob" } }; - + return { node: { name: file, type: 'tree' } }; + } + return { node: { name: file, type: 'blob' } }; } private static formatResponse(name: string, content: string): Project { diff --git a/servers/lib/src/main.ts b/servers/lib/src/main.ts index b33395ab6..2c98d334d 100644 --- a/servers/lib/src/main.ts +++ b/servers/lib/src/main.ts @@ -1,25 +1,27 @@ #!/usr/bin/env node -import { Command } from "commander"; -import bootstrap from "./bootstrap"; +import { Command } from 'commander'; +import bootstrap from './bootstrap'; type ProgramOptions = { - config?: string -} + config?: string; +}; const program = new Command(); program - .description("The lib microservice is responsible for handling and serving the contents of library assets of the DTaaS platform. It provides API endpoints for clients to query, and fetch these assets.") - .option('-c, --config ', "set the config path (default .env)") - .helpOption('-h, --help', 'display help for libms') - .showHelpAfterError(); - + .description( + 'The lib microservice is responsible for handling and serving the contents of library assets of the DTaaS platform. It provides API endpoints for clients to query, and fetch these assets.', + ) + .option('-c, --config ', 'set the config path (default .env)') + .helpOption('-h, --help', 'display help for libms') + .showHelpAfterError(); + program.parse(process.argv); const options: ProgramOptions = program.opts(); -if (options.config) { - bootstrap({config: options.config, runHelp: () => program.help()}) +if (options.config) { + bootstrap({ config: options.config, runHelp: () => program.help() }); } else { - bootstrap({runHelp: () => program.help()}); + bootstrap({ runHelp: () => program.help() }); } diff --git a/servers/lib/src/types.ts b/servers/lib/src/types.ts index 7fc2111ae..afc5ddf43 100644 --- a/servers/lib/src/types.ts +++ b/servers/lib/src/types.ts @@ -1,4 +1,4 @@ -import { Field, ObjectType } from "@nestjs/graphql"; +import { Field, ObjectType } from '@nestjs/graphql'; @ObjectType() export class Blob { diff --git a/servers/lib/test/e2e/app.e2e.spec.ts b/servers/lib/test/e2e/app.e2e.spec.ts index ce9c7c40e..75517c93f 100644 --- a/servers/lib/test/e2e/app.e2e.spec.ts +++ b/servers/lib/test/e2e/app.e2e.spec.ts @@ -1,16 +1,16 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { INestApplication } from "@nestjs/common"; -import * as request from "supertest"; +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; // import { execSync } from "child_process"; -import AppModule from "../../src/app.module"; +import AppModule from '../../src/app.module'; import { e2eReadFile, e2elistDirectory, expectedFileContentResponse, expectedListDirectoryResponse, -} from "../testUtil"; +} from '../testUtil'; -describe("End to End test for the application", () => { +describe('End to End test for the application', () => { let app: INestApplication; beforeAll(async () => { @@ -32,19 +32,19 @@ describe("End to End test for the application", () => { await app.close(); }, 10000); - it("should return the filename corresponding to the directory given in the query", async () => { + it('should return the filename corresponding to the directory given in the query', async () => { const query = e2elistDirectory; - const response = await request("http://localhost:4001") + const response = await request('http://localhost:4001') .post(process.env.APOLLO_PATH) .send({ query }); expect(response.body).toEqual(expectedListDirectoryResponse); }, 10000); - it("should return the content of a file given in the query ", async () => { + it('should return the content of a file given in the query ', async () => { const query = e2eReadFile; - const response = await request("http://localhost:4001") + const response = await request('http://localhost:4001') .post(process.env.APOLLO_PATH) .send({ query }); expect(response.body).toEqual(expectedFileContentResponse); diff --git a/servers/lib/test/integration/files.service.integration.spec.ts b/servers/lib/test/integration/files.service.integration.spec.ts index 780e529c1..d174eea19 100644 --- a/servers/lib/test/integration/files.service.integration.spec.ts +++ b/servers/lib/test/integration/files.service.integration.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { ConfigService } from "@nestjs/config"; -import FilesResolver from "../../src/files/resolvers/files.resolver"; -import FilesServiceFactory from "../../src/files/services/files-service.factory"; -import LocalFilesService from "../../src/files/services/local-files.service"; -import GitlabFilesService from "../../src/files/services/gitlab-files.service"; +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigService } from '@nestjs/config'; +import FilesResolver from '../../src/files/resolvers/files.resolver'; +import FilesServiceFactory from '../../src/files/services/files-service.factory'; +import LocalFilesService from '../../src/files/services/local-files.service'; +import GitlabFilesService from '../../src/files/services/gitlab-files.service'; import { pathToTestDirectory, pathToTestFileContent, testDirectory, testFileContent, MockConfigService, -} from "../testUtil"; +} from '../testUtil'; -describe("Integration tests for FilesResolver", () => { +describe('Integration tests for FilesResolver', () => { let filesResolver: FilesResolver; let mockConfigService: MockConfigService; @@ -35,29 +35,29 @@ describe("Integration tests for FilesResolver", () => { jest.clearAllMocks(); }); - const modes = ["local", "gitlab"]; + const modes = ['local', 'gitlab']; // eslint-disable-next-line no-restricted-syntax for (const mode of modes) { - // eslint-disable-next-line no-loop-func - describe(`when MODE is ${mode}`, () => { + // eslint-disable-next-line no-loop-func + describe(`when MODE is ${mode}`, () => { beforeEach(() => { - jest.spyOn(mockConfigService, "get").mockReturnValue(mode); + jest.spyOn(mockConfigService, 'get').mockReturnValue(mode); }); - it("should be defined", () => { + it('should be defined', () => { expect(filesResolver).toBeDefined(); }); - describe("listDirectory", () => { - it("should list files", async () => { + describe('listDirectory', () => { + it('should list files', async () => { const files = await filesResolver.listDirectory(pathToTestDirectory); expect(files).toEqual(testDirectory); }); }); - describe("readFile", () => { - it("should read file", async () => { + describe('readFile', () => { + it('should read file', async () => { const content = await filesResolver.readFile(pathToTestFileContent); expect(content).toEqual(testFileContent); }); diff --git a/servers/lib/test/testUtil.ts b/servers/lib/test/testUtil.ts index 2c9f2bb0f..4376f2aec 100644 --- a/servers/lib/test/testUtil.ts +++ b/servers/lib/test/testUtil.ts @@ -1,12 +1,12 @@ -import * as dotenv from "dotenv"; -import { setTimeout } from "timers/promises"; +import * as dotenv from 'dotenv'; +import { setTimeout } from 'timers/promises'; -dotenv.config({ path: ".env" }); +dotenv.config({ path: '.env' }); // actual data for integration and e2e tests -export const readFileActualContent = ["content123"]; +export const readFileActualContent = ['content123']; -export const pathToTestDirectory = "user2"; +export const pathToTestDirectory = 'user2'; export const testDirectory = { repository: { @@ -14,34 +14,34 @@ export const testDirectory = { blobs: { edges: [] }, trees: { edges: [ - { node: { name: "data", type: "tree" } }, - { node: { name: "digital_twins", type: "tree" } }, - { node: { name: "functions", type: "tree" } }, - { node: { name: "models", type: "tree" } }, - { node: { name: "tools", type: "tree" } }, + { node: { name: 'data', type: 'tree' } }, + { node: { name: 'digital_twins', type: 'tree' } }, + { node: { name: 'functions', type: 'tree' } }, + { node: { name: 'models', type: 'tree' } }, + { node: { name: 'tools', type: 'tree' } }, ], }, }, }, }; -export const testFileName = "README.md"; -export const fstestFileContent = "content123"; -export const pathToTestFileContent = "user2/tools/README.md"; +export const testFileName = 'README.md'; +export const fstestFileContent = 'content123'; +export const pathToTestFileContent = 'user2/tools/README.md'; export const testFileArray = [ - "data", - "digital_twins", - "functions", - "models", - "tools", + 'data', + 'digital_twins', + 'functions', + 'models', + 'tools', ]; export const testFileContent = { repository: { blobs: { nodes: [ { - name: "README.md", - rawBlob: "content123", - rawTextBlob: "content123", + name: 'README.md', + rawBlob: 'content123', + rawTextBlob: 'content123', }, ], }, @@ -57,22 +57,23 @@ export class MockConfigService { // eslint-disable-next-line class-methods-use-this get(key: string): string { switch (key) { - case "TOKEN": + case 'TOKEN': return process.env.TOKEN; - case "LOCAL_PATH": + case 'LOCAL_PATH': return process.env.TEST_PATH; - case "GITLAB_URL": + case 'GITLAB_URL': return process.env.GITLAB_URL; - case "GITLAB_GROUP": - return "dtaas"; - case "MODE": - if (process.env.MODE === "gitlab") { - return "gitlab"; - } if (process.env.MODE === "local") { - return "local"; - } - return "unknown"; - + case 'GITLAB_GROUP': + return 'dtaas'; + case 'MODE': + if (process.env.MODE === 'gitlab') { + return 'gitlab'; + } + if (process.env.MODE === 'local') { + return 'local'; + } + return 'unknown'; + default: return undefined; } @@ -81,16 +82,16 @@ export class MockConfigService { export const mockReadFileResponseData = { project: { - __typename: "Project", + __typename: 'Project', repository: { - __typename: "Repository", + __typename: 'Repository', blobs: { nodes: [ { - __typename: "Blob", - name: "README.md", - rawBlob: "content123", - rawTextBlob: "content123", + __typename: 'Blob', + name: 'README.md', + rawBlob: 'content123', + rawTextBlob: 'content123', }, ], }, @@ -107,27 +108,27 @@ export const expectedListDirectoryResponse = { edges: [ { node: { - name: "data", + name: 'data', }, }, { node: { - name: "digital_twins", + name: 'digital_twins', }, }, { node: { - name: "functions", + name: 'functions', }, }, { node: { - name: "models", + name: 'models', }, }, { node: { - name: "tools", + name: 'tools', }, }, ], @@ -145,9 +146,9 @@ export const expectedFileContentResponse = { blobs: { nodes: [ { - name: "README.md", - rawBlob: "content123", - rawTextBlob: "content123", + name: 'README.md', + rawBlob: 'content123', + rawTextBlob: 'content123', }, ], }, diff --git a/servers/lib/test/unit/files-service.factory.unit.spec.ts b/servers/lib/test/unit/files-service.factory.unit.spec.ts index a5751fdb7..7759f9818 100644 --- a/servers/lib/test/unit/files-service.factory.unit.spec.ts +++ b/servers/lib/test/unit/files-service.factory.unit.spec.ts @@ -1,12 +1,12 @@ // files-service.factory.spec.ts -import { Test, TestingModule } from "@nestjs/testing"; -import { ConfigService } from "@nestjs/config"; -import FilesServiceFactory from "../../src/files/services/files-service.factory"; -import LocalFilesService from "../../src/files/services/local-files.service"; -import GitlabFilesService from "../../src/files/services/gitlab-files.service"; -import { IFilesService } from "../../src/files/interfaces/files.service.interface"; +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigService } from '@nestjs/config'; +import FilesServiceFactory from '../../src/files/services/files-service.factory'; +import LocalFilesService from '../../src/files/services/local-files.service'; +import GitlabFilesService from '../../src/files/services/gitlab-files.service'; +import { IFilesService } from '../../src/files/interfaces/files.service.interface'; -describe("FilesServiceFactory", () => { +describe('FilesServiceFactory', () => { let serviceFactory: FilesServiceFactory; let configService: ConfigService; let localFilesService: IFilesService; @@ -29,18 +29,18 @@ describe("FilesServiceFactory", () => { configService = module.get(ConfigService); }); - it("should create a local files service when MODE is local", () => { - jest.spyOn(configService, "get").mockReturnValue("local"); + it('should create a local files service when MODE is local', () => { + jest.spyOn(configService, 'get').mockReturnValue('local'); expect(serviceFactory.create()).toBe(localFilesService); }); - it("should create a gitlab files service when MODE is gitlab", () => { - jest.spyOn(configService, "get").mockReturnValue("gitlab"); + it('should create a gitlab files service when MODE is gitlab', () => { + jest.spyOn(configService, 'get').mockReturnValue('gitlab'); expect(serviceFactory.create()).toBe(gitlabFilesService); }); - it("should throw an error when MODE is invalid", () => { - jest.spyOn(configService, "get").mockReturnValue("invalid"); + it('should throw an error when MODE is invalid', () => { + jest.spyOn(configService, 'get').mockReturnValue('invalid'); expect(() => serviceFactory.create()).toThrowError(`Invalid MODE: invalid`); }); }); diff --git a/servers/lib/test/unit/files.resolver.unit.spec.ts b/servers/lib/test/unit/files.resolver.unit.spec.ts index 62dcaab6d..850e50212 100644 --- a/servers/lib/test/unit/files.resolver.unit.spec.ts +++ b/servers/lib/test/unit/files.resolver.unit.spec.ts @@ -1,15 +1,15 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import FilesResolver from "../../src/files/resolvers/files.resolver"; +import { Test, TestingModule } from '@nestjs/testing'; +import FilesResolver from '../../src/files/resolvers/files.resolver'; import { testDirectory, pathToTestDirectory, pathToTestFileContent, testFileContent, -} from "../testUtil"; -import { IFilesService } from "../../src/files/interfaces/files.service.interface"; -import FilesServiceFactory from "../../src/files/services/files-service.factory"; +} from '../testUtil'; +import { IFilesService } from '../../src/files/interfaces/files.service.interface'; +import FilesServiceFactory from '../../src/files/services/files-service.factory'; -describe("Unit tests for FilesResolver", () => { +describe('Unit tests for FilesResolver', () => { let filesResolver: FilesResolver; let filesService: IFilesService; @@ -38,30 +38,30 @@ describe("Unit tests for FilesResolver", () => { .create(); }); - it("should be defined", () => { + it('should be defined', () => { expect(filesResolver).toBeDefined(); }); - describe("listDirectory", () => { - it("should be defined", () => { + describe('listDirectory', () => { + it('should be defined', () => { expect(filesResolver.listDirectory).toBeDefined(); }); - it("should list files in directory", async () => { + it('should list files in directory', async () => { const result = await filesResolver.listDirectory(pathToTestDirectory); expect(result).toEqual(testDirectory); expect(filesService.listDirectory).toHaveBeenCalledWith( - pathToTestDirectory + pathToTestDirectory, ); }); }); - describe("readFile", () => { - it("should be defined", () => { + describe('readFile', () => { + it('should be defined', () => { expect(filesResolver.readFile).toBeDefined(); }); - it("should read file", async () => { + it('should read file', async () => { const result = await filesResolver.readFile(pathToTestFileContent); expect(result).toEqual(testFileContent); expect(filesService.readFile).toHaveBeenCalledWith(pathToTestFileContent); diff --git a/servers/lib/test/unit/gitlab-files.service.unit.spec.ts b/servers/lib/test/unit/gitlab-files.service.unit.spec.ts index 46b237ba1..f26a9712a 100644 --- a/servers/lib/test/unit/gitlab-files.service.unit.spec.ts +++ b/servers/lib/test/unit/gitlab-files.service.unit.spec.ts @@ -1,13 +1,18 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { ConfigService } from "@nestjs/config"; -import axios from "axios"; -import GitlabFilesService from "../../src/files/services/gitlab-files.service"; -import { pathToTestFileContent, testFileContent , MockConfigService, testDirectory } from "../testUtil"; +import { Test, TestingModule } from '@nestjs/testing'; +import { ConfigService } from '@nestjs/config'; +import axios from 'axios'; +import GitlabFilesService from '../../src/files/services/gitlab-files.service'; +import { + pathToTestFileContent, + testFileContent, + MockConfigService, + testDirectory, +} from '../testUtil'; -describe("GitlabFilesService", () => { +describe('GitlabFilesService', () => { let filesService: GitlabFilesService; const mockConfigService = new MockConfigService(); - jest.mock("axios"); + jest.mock('axios'); beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -23,16 +28,16 @@ describe("GitlabFilesService", () => { filesService = module.get(GitlabFilesService); }); - it("should list directory", async () => { - jest.spyOn(axios, "post").mockResolvedValue({ data: testDirectory }); + it('should list directory', async () => { + jest.spyOn(axios, 'post').mockResolvedValue({ data: testDirectory }); - const result = await filesService.listDirectory("user2"); + const result = await filesService.listDirectory('user2'); expect(result).toEqual(testDirectory); }); - it("should read file", async () => { + it('should read file', async () => { jest - .spyOn(axios, "post") + .spyOn(axios, 'post') .mockResolvedValue({ data: { data: testFileContent } }); const result = await filesService.readFile(pathToTestFileContent); diff --git a/servers/lib/test/unit/local-files.service.unit.spec.ts b/servers/lib/test/unit/local-files.service.unit.spec.ts index 3c5f175b1..72e4835be 100644 --- a/servers/lib/test/unit/local-files.service.unit.spec.ts +++ b/servers/lib/test/unit/local-files.service.unit.spec.ts @@ -46,7 +46,7 @@ describe('LocalFilesService', () => { it('should list directory', async () => { const fullPath = join( mockConfigService.get('LOCAL_PATH'), - pathToTestDirectory + pathToTestDirectory, ); // Mock Stats value for lstat @@ -58,14 +58,12 @@ describe('LocalFilesService', () => { .spyOn(fs.promises, 'readdir') .mockResolvedValue(testFileArray as unknown as Promise<[]>); - jest - .spyOn(fs.promises, 'lstat') - .mockImplementation((pathToDirectory) => { - if (typeof pathToDirectory === 'string') { - return Promise.resolve(statsMock as fs.Stats); - } - throw new Error(`Invalid argument: ${pathToDirectory}`); - }); + jest.spyOn(fs.promises, 'lstat').mockImplementation((pathToDirectory) => { + if (typeof pathToDirectory === 'string') { + return Promise.resolve(statsMock as fs.Stats); + } + throw new Error(`Invalid argument: ${pathToDirectory}`); + }); const result = await service.listDirectory(pathToTestDirectory); expect(result).toEqual({ repository: { @@ -86,7 +84,7 @@ describe('LocalFilesService', () => { it('should read file', async () => { const fullPath = join( mockConfigService.get('LOCAL_PATH'), - pathToTestFileContent + pathToTestFileContent, ); jest.spyOn(fs.promises, 'readFile').mockResolvedValue(fstestFileContent);