From fa94c072f38c7bd250ac85e1bb8815c9eb08b0b3 Mon Sep 17 00:00:00 2001 From: Mozafar Haider Date: Mon, 2 Dec 2024 17:26:00 +0000 Subject: [PATCH 1/2] chore: run prettier format on all codebase --- .github/workflows/docker-test.yml | 2 +- .huskyrc.js | 2 +- client/config/configResolver.js | 12 ++--- client/cypress/plugins/index.js | 2 +- client/package.json | 4 +- client/src/actions/actionCreators.js | 2 +- client/src/actions/epics.js | 6 +-- client/src/api/index.js | 6 +-- client/src/api/utils.js | 8 ++-- .../AlertsProvider/AlertsProvider.js | 8 ++-- .../Header/DropdownButton/DropdownButton.js | 2 - .../DropdownMenuItemLink.js | 4 +- client/src/components/Header/Header.js | 2 +- .../components/Versions/Filters/Filters.js | 4 +- client/src/components/auth/AuthProvider.js | 8 +--- client/src/components/auth/ProtectedRoute.js | 2 +- .../form-validators/name-length-validator.js | 2 +- .../lib/form-validators/semver-validator.js | 2 +- client/src/lib/use-alert.js | 6 +-- client/src/pages/AppView/AppView.js | 7 +-- client/src/pages/Apps/AppCards/AppCards.js | 2 +- client/src/pages/Apps/Apps.js | 10 ++-- client/src/pages/Apps/Filters/Filters.js | 2 +- .../OrganisationInvitationCallback.js | 2 +- .../pages/UserApp/DetailsCard/DetailsCard.js | 4 +- .../ScreenshotsCard/DeleteScreenshotModal.js | 4 +- .../ScreenshotsCard/ScreenshotsCard.js | 4 +- .../ScreenshotsCard/UploadScreenshot.js | 6 +-- client/src/pages/UserApp/UserApp.js | 6 ++- .../CreateOrganisationModal.js | 2 +- .../UserAppVersionNew/UserAppVersionNew.js | 4 +- client/src/pages/UserApps/AppCard/AppCard.js | 8 ++-- client/src/pages/UserApps/UserApps.js | 45 ++++++++--------- .../UserOrganisation/UserOrganisation.js | 18 +++---- .../UserOrganisations/UserOrganisations.js | 4 +- client/src/pages/UserView/UserView.js | 25 +++++----- client/src/selectors/userSelectors.js | 8 ++-- client/test/config/configResolver.spec.js | 6 +-- onboarding.md | 28 +++++------ package.json | 4 +- server/migrations/20190130113004_user.js | 13 ++--- .../migrations/20190130121634_organisation.js | 11 ++--- .../20190130121824_user-organisation.js | 11 ++--- server/migrations/20190130140037_app.js | 21 +++----- .../migrations/20190130140038_app_version.js | 16 ++----- .../20190130140039_app_version_localised.js | 16 ++----- .../migrations/20190130140040_app_status.js | 11 ++--- server/migrations/20190130161337_review.js | 6 +-- .../migrations/20190130170039_appchannel.js | 48 +++++-------------- server/migrations/20190320113801_mediatype.js | 6 +-- .../20190320113929_appversionmedia.js | 11 ++--- .../20190430133756_media_add_caption_desc.js | 6 +-- server/migrations/20190430133758_app_view.js | 4 +- ...0430134957_apps_view_media_caption_desc.js | 4 +- server/migrations/20191217103142_auto-uuid.js | 8 ++-- ...82043_fix_view_users_with_organisations.js | 4 +- .../20200310134835_refactor-media.js | 25 ++++------ ...200924140557_version-replace-underscore.js | 4 +- .../20201006112837_add_organisation_email.js | 8 ++-- server/migrations/20210209171106_api-key.js | 16 ++----- .../20210223140633_rename_channels.js | 12 +++-- ...10420135804_user-allow-duplicate-emails.js | 26 ++++------ server/migrations/20210705145813_core-app.js | 4 +- .../20220407123044_download_count.js | 8 ++-- server/seeds/01_organisation-developers.js | 6 +-- server/seeds/02_app.js | 2 +- server/seeds/03_review.js | 2 +- server/seeds/04_appchannel.js | 2 +- server/seeds/05_media.js | 2 +- server/seeds/mock/appversions.js | 2 - server/src/data/addUserToOrganisation.js | 10 +--- server/src/data/appExists.js | 4 +- server/src/data/deleteApp.js | 4 +- server/src/data/deleteAppMedia.js | 4 +- server/src/data/deleteAppVersion.js | 4 +- server/src/data/deleteChannel.js | 4 +- server/src/data/deleteMedia.js | 4 +- server/src/data/deleteOrganisation.js | 4 +- server/src/data/getApps.js | 12 ++--- .../src/data/getOrganisationAppsByUserId.js | 4 +- server/src/data/getOrganisationById.js | 5 +- server/src/data/getUserByEmail.js | 5 +- server/src/data/renameChannel.js | 5 +- server/src/data/updateApp.js | 2 +- server/src/data/updateAppVersion.js | 36 +++----------- server/src/data/updateImageMeta.js | 10 ++-- server/src/main.js | 16 +++---- server/src/models/v1/App.js | 33 ++++--------- server/src/models/v1/in/CreateAppModel.js | 2 +- .../src/models/v1/in/CreateAppVersionModel.js | 10 ++-- server/src/models/v1/in/EditAppModel.js | 2 +- .../src/models/v1/in/EditAppVersionModel.js | 17 ++----- server/src/models/v1/out/Version.js | 12 ++--- server/src/models/v2/Default.js | 5 +- server/src/models/v2/Organisation.js | 7 +-- server/src/models/v2/helpers.js | 6 +-- server/src/models/v2/in/CreateAppModel.js | 2 +- server/src/models/v2/in/EditChannelModel.js | 2 +- server/src/models/v2/out/App.js | 4 +- server/src/plugins/errorMapper.js | 14 +++--- server/src/plugins/pagination.js | 8 ++-- server/src/plugins/queryFilter.js | 4 +- server/src/plugins/staticFrontendRoutes.js | 2 +- server/src/query/Pager.js | 6 +-- .../v1/apps/handlers/createAppVersion.js | 17 ++++--- .../v1/apps/handlers/deleteAppVersion.js | 2 +- .../routes/v1/apps/handlers/deleteImage.js | 2 +- server/src/routes/v1/apps/handlers/editApp.js | 2 +- .../routes/v1/apps/handlers/editAppVersion.js | 2 +- .../src/routes/v1/apps/handlers/editImage.js | 2 +- .../src/routes/v1/apps/handlers/getAppFile.js | 4 +- .../v1/apps/handlers/uploadImageToApp.js | 2 +- server/src/routes/v2/apps.js | 4 +- server/src/routes/v2/channels.js | 8 ++-- server/src/routes/v2/me.js | 2 +- server/src/routes/v2/organisations.js | 14 +++--- server/src/security/apiKeyScheme.js | 9 ++-- .../security/createApiKeyValidationFunc.js | 11 ++--- .../src/security/createUserValidationFunc.js | 4 +- server/src/security/index.js | 16 +++---- server/src/security/verifyBundle.js | 4 +- server/src/server/Auth0ManagementClient.js | 13 +++-- server/src/server/create-api-user.js | 2 +- server/src/server/migrate-database.js | 2 +- server/src/services/apiKey.js | 7 +-- server/src/services/app.js | 2 +- server/src/services/organisation.js | 2 +- server/src/utils/AWSFileHandler.js | 2 +- server/src/utils/CustomJoi.js | 8 ++-- server/src/utils/Filter.js | 6 +-- server/src/utils/LocalFileSystemHandler.js | 6 +-- server/src/utils/filterUtils.js | 2 +- server/src/utils/index.js | 2 +- server/src/utils/slugify.js | 2 +- server/src/utils/validateMime.js | 6 ++- server/test/data/index.js | 14 +++--- server/test/plugins/errorMapper.js | 8 ++-- server/test/plugins/pagination.js | 22 +++------ server/test/plugins/queryFilter.js | 5 +- server/test/query/executeQuery.js | 20 ++++---- server/test/routes/createApp.js | 11 ++--- server/test/routes/deleteApp.js | 2 +- server/test/routes/index.js | 33 +++++++------ server/test/routes/v2/apiKey.js | 9 +--- server/test/routes/v2/apps.js | 22 ++++----- server/test/routes/v2/channels.js | 8 +--- server/test/routes/v2/organisations.js | 9 +--- server/test/security/apiKeyScheme.js | 9 +--- server/test/services/organisation.js | 38 ++++++++------- tools/.eslintrc.js | 2 +- tools/clean.js | 2 +- tools/clone.js | 4 +- tools/helpers/downloadImages.js | 4 +- tools/helpers/downloadVersions.js | 4 +- tools/helpers/generateAppVersion.js | 2 +- 155 files changed, 527 insertions(+), 735 deletions(-) diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index e901f9d16..702a82478 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -52,4 +52,4 @@ jobs: AUTH0_JWKS_URI: https://dhis2.eu.auth0.com/.well-known/jwks.json AUTH0_MANAGEMENT_AUDIENCE: https://dhis2.eu.auth0.com/api/v2/ AUTH0_MANAGEMENT_SECRET: ${{ secrets.AUTH0_MANAGEMENT_SECRET }} - AUTH0_MANAGEMENT_CLIENT_ID: K4fVnj443Sqid3Xl9yBVTYw9BEjPx3gl \ No newline at end of file + AUTH0_MANAGEMENT_CLIENT_ID: K4fVnj443Sqid3Xl9yBVTYw9BEjPx3gl diff --git a/.huskyrc.js b/.huskyrc.js index 1406b0981..07192bfd0 100644 --- a/.huskyrc.js +++ b/.huskyrc.js @@ -1,7 +1,7 @@ const { config } = require('@dhis2/cli-style') const husky = require(config.husky) -const tasks = arr => arr.join(' && ') +const tasks = (arr) => arr.join(' && ') module.exports = { hooks: { diff --git a/client/config/configResolver.js b/client/config/configResolver.js index db3e8f5fa..a22b4edf4 100644 --- a/client/config/configResolver.js +++ b/client/config/configResolver.js @@ -29,16 +29,16 @@ function getConfig() { //Get default config const configs = defaultConfigs - .map(filename => loadFile(filename)) - .filter(config => !!config) - configs.forEach(cfg => merge(config, cfg)) + .map((filename) => loadFile(filename)) + .filter((config) => !!config) + configs.forEach((cfg) => merge(config, cfg)) //Get environment specific config if (envConfigNames[nodeEnv]) { const configs = envConfigNames[nodeEnv] - .map(filename => loadFile(filename)) - .filter(config => !!config) - configs.forEach(cfg => merge(config, cfg)) + .map((filename) => loadFile(filename)) + .filter((config) => !!config) + configs.forEach((cfg) => merge(config, cfg)) } getConfig.config = config diff --git a/client/cypress/plugins/index.js b/client/cypress/plugins/index.js index 22fe92a10..03898f147 100644 --- a/client/cypress/plugins/index.js +++ b/client/cypress/plugins/index.js @@ -13,6 +13,6 @@ const cucumber = require('cypress-cucumber-preprocessor').default -module.exports = on => { +module.exports = (on) => { on('file:preprocessor', cucumber()) } diff --git a/client/package.json b/client/package.json index 57fc3bbac..e814687e0 100644 --- a/client/package.json +++ b/client/package.json @@ -12,8 +12,8 @@ "test": "cross-env NODE_ENV=test mocha --config test/.mocharc.js", "format": "yarn format:js && yarn format:text", "format:staged": "yarn format:js --staged && yarn format:text --staged", - "format:js": "d2-style js apply", - "format:text": "d2-style text apply" + "format:js": "d2-style apply js", + "format:text": "d2-style apply text" }, "dependencies": { "@auth0/auth0-react": "^1.6.0", diff --git a/client/src/actions/actionCreators.js b/client/src/actions/actionCreators.js index 530ac5713..5f31ab29e 100644 --- a/client/src/actions/actionCreators.js +++ b/client/src/actions/actionCreators.js @@ -2,7 +2,7 @@ import * as actions from '../constants/actionTypes' export const loadUser = actionCreator(actions.USER_LOAD) -export const userLoaded = profile => +export const userLoaded = (profile) => actionCreator(actions.USER_LOAD_SUCCESS)({ profile, }) diff --git a/client/src/actions/epics.js b/client/src/actions/epics.js index 48bd9d7e6..5825c1f62 100644 --- a/client/src/actions/epics.js +++ b/client/src/actions/epics.js @@ -3,17 +3,17 @@ import { concatMap } from 'rxjs/operators' import * as api from '../api' import * as actions from '../constants/actionTypes' -const user = action$ => +const user = (action$) => action$.pipe( ofType(actions.USER_LOAD), concatMap(() => api .getMe() - .then(response => ({ + .then((response) => ({ type: actions.ME_LOAD_SUCCESS, payload: response, })) - .catch(e => ({ + .catch((e) => ({ type: actions.ME_LOAD_ERROR, payload: e, })) diff --git a/client/src/api/index.js b/client/src/api/index.js index 282e7aecc..8fc99ccf0 100644 --- a/client/src/api/index.js +++ b/client/src/api/index.js @@ -82,7 +82,7 @@ export const usePagination = ( const isEmpty = data?.[0].pager.total === 0 // useSWRInfinite gathers all responses with an array entry per request - flatten it - const resultData = data?.flatMap(d => d?.result) + const resultData = data?.flatMap((d) => d?.result) const isAtEnd = isEmpty || data?.[0].pager.total === resultData?.length const isLoadingInitial = !data && !error @@ -196,7 +196,7 @@ export async function fromApi(url, auth = false, extraOpts) { } return fetch(baseURL + url, opts) - .then(async response => { + .then(async (response) => { if (!response.ok) { const contentType = response.headers.get('content-type') const isJson = contentType.includes('application/json') @@ -208,7 +208,7 @@ export async function fromApi(url, auth = false, extraOpts) { } return response }) - .then(response => response.json()) + .then((response) => response.json()) } export async function getAuthHeaders() { diff --git a/client/src/api/utils.js b/client/src/api/utils.js index 6d51aaaea..ae6eb33f5 100644 --- a/client/src/api/utils.js +++ b/client/src/api/utils.js @@ -1,6 +1,6 @@ import { useRef, useEffect, useCallback } from 'react' -const encodeQueryParameter = param => { +const encodeQueryParameter = (param) => { if (Array.isArray(param)) { return param.map(encodeQueryParameter).join(',') } @@ -20,7 +20,7 @@ const encodeQueryParameter = param => { } export const joinUrlPath = (...paths) => { - const truePaths = paths.filter(path => !!path) + const truePaths = paths.filter((path) => !!path) return truePaths .map((path, i) => { path = typeof path === 'string' ? path : String(path) @@ -35,7 +35,7 @@ export const joinUrlPath = (...paths) => { .join('/') } -export const queryParametersToQueryString = params => +export const queryParametersToQueryString = (params) => Object.entries(params) .filter(([, value]) => value) .map( @@ -46,7 +46,7 @@ export const queryParametersToQueryString = params => // This is a SWR middleware for keeping the data even if key changes. // See https://swr.vercel.app/docs/middleware#keep-previous-result -export const laggySWRMiddleware = useSWRNext => { +export const laggySWRMiddleware = (useSWRNext) => { return (key, fetcher, config) => { // Use a ref to store previous returned data const laggyDataRef = useRef() diff --git a/client/src/components/AlertsProvider/AlertsProvider.js b/client/src/components/AlertsProvider/AlertsProvider.js index b901fb9ad..e32939fe4 100644 --- a/client/src/components/AlertsProvider/AlertsProvider.js +++ b/client/src/components/AlertsProvider/AlertsProvider.js @@ -7,12 +7,12 @@ let alertId = 0 const AlertsProvider = ({ children }) => { const [alerts, setAlerts] = useState([]) - const removeAlert = id => { - setAlerts(alerts => alerts.filter(alert => alert.id !== id)) + const removeAlert = (id) => { + setAlerts((alerts) => alerts.filter((alert) => alert.id !== id)) } - const addAlert = alert => { + const addAlert = (alert) => { const id = alertId++ - setAlerts(alerts => [ + setAlerts((alerts) => [ ...alerts, { ...alert, diff --git a/client/src/components/Header/DropdownButton/DropdownButton.js b/client/src/components/Header/DropdownButton/DropdownButton.js index 3b732c510..8779ff5c1 100644 --- a/client/src/components/Header/DropdownButton/DropdownButton.js +++ b/client/src/components/Header/DropdownButton/DropdownButton.js @@ -4,8 +4,6 @@ import PropTypes from 'prop-types' import { useState, useRef } from 'react' import styles from './DropdownButton.module.css' - - const DropdownButton = ({ icon, menu }) => { const [isOpen, setIsOpen] = useState(false) const handleToggle = () => setIsOpen(!isOpen) diff --git a/client/src/components/Header/DropdownMenuItemLink/DropdownMenuItemLink.js b/client/src/components/Header/DropdownMenuItemLink/DropdownMenuItemLink.js index 9b4187a68..7647111fc 100644 --- a/client/src/components/Header/DropdownMenuItemLink/DropdownMenuItemLink.js +++ b/client/src/components/Header/DropdownMenuItemLink/DropdownMenuItemLink.js @@ -3,12 +3,12 @@ import { useRef, useEffect } from 'react' import { useHistory } from 'react-router-dom' import styles from '../DropdownMenuItem/DropdownMenuItem.module.css' -const isModifiedEvent = event => +const isModifiedEvent = (event) => event.metaKey || event.altKey || event.ctrlKey || event.shiftKey const DropdownMenuItemLink = ({ to, children, initialFocus }) => { const history = useHistory() - const handleClick = event => { + const handleClick = (event) => { if (!isModifiedEvent(event)) { event.preventDefault() history.push(to) diff --git a/client/src/components/Header/Header.js b/client/src/components/Header/Header.js index 579b99bc5..21f98db4d 100644 --- a/client/src/components/Header/Header.js +++ b/client/src/components/Header/Header.js @@ -80,7 +80,7 @@ const ProfileButton = () => { return } -const NavLink = props => ( +const NavLink = (props) => ( ) diff --git a/client/src/components/Versions/Filters/Filters.js b/client/src/components/Versions/Filters/Filters.js index 36250b30e..d78b7bf0b 100644 --- a/client/src/components/Versions/Filters/Filters.js +++ b/client/src/components/Versions/Filters/Filters.js @@ -18,7 +18,7 @@ const Filters = ({ {availableChannels.length > 1 && (

Channel

- {availableChannels.map(channel => ( + {availableChannels.map((channel) => ( setDhisVersionFilter(selected)} > - {dhisVersions.map(dhisVersion => ( + {dhisVersions.map((dhisVersion) => ( ( ) const InitializeAuth = ({ children }) => { - const { - user, - isAuthenticated, - isLoading, - getAccessTokenSilently, - } = useAuth0() + const { user, isAuthenticated, isLoading, getAccessTokenSilently } = + useAuth0() const dispatch = useDispatch() useEffect(() => { diff --git a/client/src/components/auth/ProtectedRoute.js b/client/src/components/auth/ProtectedRoute.js index 284ab77be..77fb9d1ef 100644 --- a/client/src/components/auth/ProtectedRoute.js +++ b/client/src/components/auth/ProtectedRoute.js @@ -11,7 +11,7 @@ const ProtectedRoute = ({ component, auth, ...rest }) => { return ( { + render={(props) => { const ProtectedComponent = withAuthenticationRequired( component, { diff --git a/client/src/lib/form-validators/name-length-validator.js b/client/src/lib/form-validators/name-length-validator.js index b3ca3993c..a7eba7100 100644 --- a/client/src/lib/form-validators/name-length-validator.js +++ b/client/src/lib/form-validators/name-length-validator.js @@ -2,4 +2,4 @@ import { createCharacterLengthRange } from '@dhis2/ui' const twoToHundredValidator = createCharacterLengthRange(2, 100) -export const nameLengthValidator = value => twoToHundredValidator(value) +export const nameLengthValidator = (value) => twoToHundredValidator(value) diff --git a/client/src/lib/form-validators/semver-validator.js b/client/src/lib/form-validators/semver-validator.js index c1f38692e..ea65eda15 100644 --- a/client/src/lib/form-validators/semver-validator.js +++ b/client/src/lib/form-validators/semver-validator.js @@ -1,6 +1,6 @@ import semver from 'semver' -export const semverValidator = value => { +export const semverValidator = (value) => { if (!semver.valid(value)) { return 'Not a valid semantic version, adjust the version numbering' } diff --git a/client/src/lib/use-alert.js b/client/src/lib/use-alert.js index 040365f79..ee0a860e5 100644 --- a/client/src/lib/use-alert.js +++ b/client/src/lib/use-alert.js @@ -4,7 +4,7 @@ import AlertsContext from 'src/components/AlertsProvider/AlertsContext' export const useAlert = (message, options = {}) => { const { addAlert } = useContext(AlertsContext) - const show = props => { + const show = (props) => { const resolvedMessage = typeof message === 'function' ? message(props) : message const resolvedOptions = @@ -22,7 +22,7 @@ export const useAlert = (message, options = {}) => { export const useSuccessAlert = () => useAlert( ({ message }) => message, - options => ({ + (options) => ({ ...options, success: true, }) @@ -31,7 +31,7 @@ export const useSuccessAlert = () => export const useErrorAlert = () => useAlert( ({ error }) => `An error occured: ${error.message}`, - options => ({ + (options) => ({ ...options, critical: true, }) diff --git a/client/src/pages/AppView/AppView.js b/client/src/pages/AppView/AppView.js index 422de04b8..25ffaa92c 100644 --- a/client/src/pages/AppView/AppView.js +++ b/client/src/pages/AppView/AppView.js @@ -66,7 +66,8 @@ const AboutSection = ({ appDescription, latestVersion, sourceUrl }) => ( {renderDhisVersionsCompatibility( latestVersion.minDhisVersion, latestVersion.maxDhisVersion - )}. + )} + .
{sourceUrl && ( @@ -104,8 +105,8 @@ const AppView = ({ match }) => { } const appDeveloper = app.developer.organisation || 'Unspecified' - const logoSrc = app.images.find(img => img.logo)?.imageUrl - const screenshots = app.images.filter(img => !img.logo) + const logoSrc = app.images.find((img) => img.logo)?.imageUrl + const screenshots = app.images.filter((img) => !img.logo) const versions = app.versions.sort((a, b) => b.created - a.created) const latestVersion = versions[0] diff --git a/client/src/pages/Apps/AppCards/AppCards.js b/client/src/pages/Apps/AppCards/AppCards.js index 4c7818836..44d829d65 100644 --- a/client/src/pages/Apps/AppCards/AppCards.js +++ b/client/src/pages/Apps/AppCards/AppCards.js @@ -30,7 +30,7 @@ const AppCards = ({ isLoading, error, apps }) => { return (
- {apps.map(app => ( + {apps.map((app) => ( { }) const { channels, types, dhisVersion, query, page } = queryParams const [debouncedQuery] = useDebounce(query, 300) - const setChannels = channels => { + const setChannels = (channels) => { setQueryParams({ channels, page: 1 }) } - const setTypes = types => { + const setTypes = (types) => { setQueryParams({ types, page: 1 }) } - const setDhisVersion = dhisVersion => { + const setDhisVersion = (dhisVersion) => { setQueryParams({ dhisVersion, page: 1 }) } - const setQuery = query => { + const setQuery = (query) => { setQueryParams({ query, page: 1 }, 'replaceIn') } - const setPage = page => { + const setPage = (page) => { setQueryParams({ page }) } diff --git a/client/src/pages/Apps/Filters/Filters.js b/client/src/pages/Apps/Filters/Filters.js index 85401c69d..39f082b58 100644 --- a/client/src/pages/Apps/Filters/Filters.js +++ b/client/src/pages/Apps/Filters/Filters.js @@ -91,7 +91,7 @@ const Filters = ({ onDhisVersionFilterChange(selected) } > - {dhisVersions.map(dhisVersion => ( + {dhisVersions.map((dhisVersion) => ( { const [error, setError] = useState(null) useEffect(() => { - const acceptInvitation = async token => { + const acceptInvitation = async (token) => { try { const { organisation } = await api.acceptOrganisationInvitation( token diff --git a/client/src/pages/UserApp/DetailsCard/DetailsCard.js b/client/src/pages/UserApp/DetailsCard/DetailsCard.js index 0bce99712..ccca805e8 100644 --- a/client/src/pages/UserApp/DetailsCard/DetailsCard.js +++ b/client/src/pages/UserApp/DetailsCard/DetailsCard.js @@ -22,7 +22,7 @@ const EditLogo = ({ appId, logo, mutate }) => { const handleUploadButtonClick = () => { inputEl.current.click() } - const handleUpload = async event => { + const handleUpload = async (event) => { setIsUploading(true) try { // TODO: Implement backend API to replace logo so that it can be @@ -75,7 +75,7 @@ const EditLogo = ({ appId, logo, mutate }) => { } const DetailsCard = ({ app, mutate }) => { - const logo = app.images.find(img => img.logo) + const logo = app.images.find((img) => img.logo) const appDeveloper = app.developer.organisation || 'Unspecified' const appType = appTypeToDisplayName[app.appType] diff --git a/client/src/pages/UserApp/ScreenshotsCard/DeleteScreenshotModal.js b/client/src/pages/UserApp/ScreenshotsCard/DeleteScreenshotModal.js index 85541f03f..39e88f325 100644 --- a/client/src/pages/UserApp/ScreenshotsCard/DeleteScreenshotModal.js +++ b/client/src/pages/UserApp/ScreenshotsCard/DeleteScreenshotModal.js @@ -20,9 +20,9 @@ const DeleteScreenshotModal = ({ appId, imageId, mutate, onClose }) => { setIsSubmitting(true) try { await api.deleteImage(appId, imageId) - mutate(app => ({ + mutate((app) => ({ ...app, - images: app.images.filter(img => img.id !== imageId), + images: app.images.filter((img) => img.id !== imageId), })) successAlert.show({ message: `Successfully deleted screenshot`, diff --git a/client/src/pages/UserApp/ScreenshotsCard/ScreenshotsCard.js b/client/src/pages/UserApp/ScreenshotsCard/ScreenshotsCard.js index 004e7d14d..58cb725d2 100644 --- a/client/src/pages/UserApp/ScreenshotsCard/ScreenshotsCard.js +++ b/client/src/pages/UserApp/ScreenshotsCard/ScreenshotsCard.js @@ -33,8 +33,8 @@ const DeleteScreenshotButton = ({ appId, imageId, mutate }) => { } const ScreenshotsCard = ({ app, mutate }) => { - const screenshots = app.images.filter(img => !img.logo) - const renderDeleteScreenshotButton = imageId => ( + const screenshots = app.images.filter((img) => !img.logo) + const renderDeleteScreenshotButton = (imageId) => ( { const handleUploadButtonClick = () => { inputEl.current.click() } - const handleUpload = async event => { + const handleUpload = async (event) => { setIsUploading(true) const files = Array.from(event.target.files) - const payloads = files.map(file => ({ + const payloads = files.map((file) => ({ image: { caption: '', description: '', @@ -28,7 +28,7 @@ const UploadScreenshot = ({ appId, mutate }) => { }, file, })) - const requests = payloads.map(payload => + const requests = payloads.map((payload) => api.createNewImage(appId, payload) ) try { diff --git a/client/src/pages/UserApp/UserApp.js b/client/src/pages/UserApp/UserApp.js index 461102229..11a0bfc52 100644 --- a/client/src/pages/UserApp/UserApp.js +++ b/client/src/pages/UserApp/UserApp.js @@ -7,7 +7,11 @@ import { useQueryV1 } from 'src/api' const UserApp = ({ match }) => { const { appId } = match.params - const { data: app, error, mutate } = useQueryV1(`apps/${appId}`, { + const { + data: app, + error, + mutate, + } = useQueryV1(`apps/${appId}`, { auth: true, }) diff --git a/client/src/pages/UserAppUpload/CreateOrganisationModal/CreateOrganisationModal.js b/client/src/pages/UserAppUpload/CreateOrganisationModal/CreateOrganisationModal.js index 21f0b127d..caaa75044 100644 --- a/client/src/pages/UserAppUpload/CreateOrganisationModal/CreateOrganisationModal.js +++ b/client/src/pages/UserAppUpload/CreateOrganisationModal/CreateOrganisationModal.js @@ -25,7 +25,7 @@ const CreateOrganisationModal = ({ const handleSubmit = async ({ name, email }) => { try { const organisation = await api.addOrganisation({ name, email }) - mutate(organisations => [...organisations, organisation]) + mutate((organisations) => [...organisations, organisation]) // Ensure data returned by useQuery in parent component has been // updated to include new organisation before setting select input // value diff --git a/client/src/pages/UserAppVersionNew/UserAppVersionNew.js b/client/src/pages/UserAppVersionNew/UserAppVersionNew.js index 3d38c4dcf..d8515123b 100644 --- a/client/src/pages/UserAppVersionNew/UserAppVersionNew.js +++ b/client/src/pages/UserAppVersionNew/UserAppVersionNew.js @@ -23,7 +23,7 @@ import { useSuccessAlert, useErrorAlert } from 'src/lib/use-alert' const { dhisVersions, defaultAppChannel, appChannelToDisplayName } = config.ui const oldestSupportedDhisVersion = dhisVersions[2] -const dhisVersionOptions = dhisVersions.map(v => ({ +const dhisVersionOptions = dhisVersions.map((v) => ({ label: v, value: v, })) @@ -42,7 +42,7 @@ const UserAppVersionNew = ({ match }) => { const successAlert = useSuccessAlert() const errorAlert = useErrorAlert() - const handleSubmit = async values => { + const handleSubmit = async (values) => { try { await api.createNewVersion(appId, { file: values.file[0], diff --git a/client/src/pages/UserApps/AppCard/AppCard.js b/client/src/pages/UserApps/AppCard/AppCard.js index 0c222fd39..88de6e3ad 100644 --- a/client/src/pages/UserApps/AppCard/AppCard.js +++ b/client/src/pages/UserApps/AppCard/AppCard.js @@ -10,7 +10,7 @@ import { } from 'src/constants/apiConstants' import { relativeTimeFormat } from 'src/lib/relative-time-format' -const appCardActionForStatus = appStatus => { +const appCardActionForStatus = (appStatus) => { switch (appStatus) { case APP_STATUS_APPROVED: return 'Updated' @@ -21,7 +21,7 @@ const appCardActionForStatus = appStatus => { } } -const appStatusToCardText = appStatus => { +const appStatusToCardText = (appStatus) => { switch (appStatus) { case APP_STATUS_APPROVED: return 'Available' @@ -33,9 +33,9 @@ const appStatusToCardText = appStatus => { } const AppCard = ({ app, showUploadButton, onApprove, onReject, onDelete }) => { - const logo = app.images.find(i => i.logo) + const logo = app.images.find((i) => i.logo) const actionForStatus = appCardActionForStatus(app.status) - const actionTime = new Date(Math.max(...app.versions.map(v => v.created))) + const actionTime = new Date(Math.max(...app.versions.map((v) => v.created))) const actionRelativeTime = relativeTimeFormat(actionTime) return ( diff --git a/client/src/pages/UserApps/UserApps.js b/client/src/pages/UserApps/UserApps.js index 2259b777e..80ea6c15b 100644 --- a/client/src/pages/UserApps/UserApps.js +++ b/client/src/pages/UserApps/UserApps.js @@ -23,7 +23,7 @@ import { useSuccessAlert, useErrorAlert } from 'src/lib/use-alert' const { appStatusToDisplayName } = config.ui -const sortApps = apps => +const sortApps = (apps) => apps.sort((a, b) => { if (a.name < b.name) { return -1 @@ -37,8 +37,8 @@ const filterApps = (apps, query) => { if (!query) { return apps } - return apps.filter(app => - [app.name, app.appType, app.developer.organisation].some(prop => + return apps.filter((app) => + [app.name, app.appType, app.developer.organisation].some((prop) => prop.toLowerCase().includes(query.toLowerCase()) ) ) @@ -46,12 +46,13 @@ const filterApps = (apps, query) => { const UserApps = ({ user }) => { const [query, setQuery] = useState('') - const { data: appsById, error, mutate } = useQueryV1( - user.isManager ? 'apps/all' : 'apps/myapps', - { - auth: true, - } - ) + const { + data: appsById, + error, + mutate, + } = useQueryV1(user.isManager ? 'apps/all' : 'apps/myapps', { + auth: true, + }) const successAlert = useSuccessAlert() const errorAlert = useErrorAlert() @@ -76,24 +77,24 @@ const UserApps = ({ user }) => { const apps = sortApps(Object.values(appsById)) const filteredApps = filterApps(apps, query) const approvedApps = filteredApps.filter( - app => app.status === APP_STATUS_APPROVED + (app) => app.status === APP_STATUS_APPROVED ) const pendingApps = filteredApps - .filter(app => app.status === APP_STATUS_PENDING) + .filter((app) => app.status === APP_STATUS_PENDING) .sort((a, b) => { - const aLatestVersion = Math.max(...a.versions.map(v => v.created)) - const bLatestVersion = Math.max(...b.versions.map(v => v.created)) + const aLatestVersion = Math.max(...a.versions.map((v) => v.created)) + const bLatestVersion = Math.max(...b.versions.map((v) => v.created)) return bLatestVersion - aLatestVersion }) const rejectedApps = filteredApps.filter( - app => app.status === APP_STATUS_REJECTED + (app) => app.status === APP_STATUS_REJECTED ) const setAppStatus = async (app, status) => { try { await api.setAppApproval(app.id, status) mutate( - apps.map(a => { + apps.map((a) => { if (a.id === app.id) { return { ...a, status } } @@ -118,20 +119,20 @@ const UserApps = ({ user }) => { } } - const handleApprove = app => { + const handleApprove = (app) => { setAppStatus(app, APP_STATUS_APPROVED) } - const handleReject = app => { + const handleReject = (app) => { setAppStatus(app, APP_STATUS_REJECTED) } - const handleDelete = async app => { + const handleDelete = async (app) => { if (!window.confirm(`Are you sure you want to delete ${app.name}?`)) { return } try { await api.deleteApp(app.id) - mutate(apps.filter(a => a.id !== app.id)) + mutate(apps.filter((a) => a.id !== app.id)) successAlert.show({ message: `${app.name} has been deleted`, }) @@ -183,7 +184,7 @@ const UserApps = ({ user }) => { waiting for approval.

- {pendingApps.map(app => ( + {pendingApps.map((app) => ( { Hub.

- {approvedApps.map(app => ( + {approvedApps.map((app) => ( { approval.

- {rejectedApps.map(app => ( + {rejectedApps.map((app) => ( { const { organisationId } = match.params - const { data: organisation, error, mutate } = useQuery( - `organisations/${organisationId}`, - null, - requestOpts - ) + const { + data: organisation, + error, + mutate, + } = useQuery(`organisations/${organisationId}`, null, requestOpts) const inviteMemberModal = useModalState() const editNameModal = useModalState() const successAlert = useSuccessAlert() const errorAlert = useErrorAlert() - const handlePromote = async userId => { + const handlePromote = async (userId) => { try { await api.editOrganisation(organisation.id, { owner: userId }) mutate({ @@ -46,12 +46,12 @@ const UserOrganisation = ({ match, user }) => { errorAlert.show({ error }) } } - const handleRemove = async userId => { + const handleRemove = async (userId) => { try { await api.removeOrganisationMember(organisation.id, userId) mutate({ ...organisation, - users: organisation.users.filter(ou => ou.id !== userId), + users: organisation.users.filter((ou) => ou.id !== userId), }) successAlert.show({ message: 'Successfully removed organisation member', @@ -135,7 +135,7 @@ const UserOrganisation = ({ match, user }) => { Invite member
- {organisation.users.map(ou => ( + {organisation.users.map((ou) => ( { if (!query) { return organisations } - return organisations.filter(organisation => + return organisations.filter((organisation) => organisation.name.toLowerCase().includes(query.toLowerCase()) ) } @@ -115,7 +115,7 @@ const UserOrganisations = ({ user }) => { No organisations found. Try adjusting your search. )} - {filteredOrganisations.map(organisation => ( + {filteredOrganisations.map((organisation) => ( { } // eslint-disable-next-line react/display-name - const provideUser = Component => props => ( - - ) + const provideUser = (Component) => (props) => + ( + + ) return ( @@ -100,7 +101,7 @@ UserView.propTypes = { user: PropTypes.object.isRequired, } -const mapStateToProps = state => ({ +const mapStateToProps = (state) => ({ user: getUserInfo(state), }) diff --git a/client/src/selectors/userSelectors.js b/client/src/selectors/userSelectors.js index 81cd0ed66..441b9190e 100644 --- a/client/src/selectors/userSelectors.js +++ b/client/src/selectors/userSelectors.js @@ -1,10 +1,10 @@ -export const getUserInfo = state => state.user.userInfo +export const getUserInfo = (state) => state.user.userInfo -export const getUserProfile = state => getUserInfo(state).profile +export const getUserProfile = (state) => getUserInfo(state).profile -export const getUserId = state => getUserInfo(state).userId +export const getUserId = (state) => getUserInfo(state).userId -export const isManager = state => { +export const isManager = (state) => { const userInfo = getUserInfo(state) return userInfo?.profile?.manager } diff --git a/client/test/config/configResolver.spec.js b/client/test/config/configResolver.spec.js index f52a09528..added3dbe 100644 --- a/client/test/config/configResolver.spec.js +++ b/client/test/config/configResolver.spec.js @@ -117,17 +117,17 @@ describe('ConfigResolver', () => { expect(conf.routes.baseAppName).to.equal('baseAppName') //should deep merge expect( - Object.keys(conf.ui).every(k => + Object.keys(conf.ui).every((k) => Object.prototype.hasOwnProperty.call(DirectDefaultConfig, k) ) ) expect( - DirectDefaultConfig.ui.dhisVersions.every(v => + DirectDefaultConfig.ui.dhisVersions.every((v) => conf.ui.dhisVersions.includes(v) ) ) expect( - conf.ui.dhisVersions.every(v => + conf.ui.dhisVersions.every((v) => override.ui.dhisVersions.includes(v) ) ) diff --git a/onboarding.md b/onboarding.md index 88460687a..9c1bc187c 100644 --- a/onboarding.md +++ b/onboarding.md @@ -1,5 +1,3 @@ - - # Onboarding This document will serve as a more thorough documentation for App Hub, hopefully providing some insight into the architecture and making it easier to contribute to the project. This will mainly cover the backend. For information about getting the project set up, see the readme. @@ -10,11 +8,11 @@ The App Hub was previously called App Store, and was written in Java. It was dec ### External Libraries -The backend is built around Hapi. Hapi is a configuration oriented framework for creating backend services. It has a huge ecosystem of modules and plugins, and has no external dependencies which means more control of security. It can be a bit overwhelming when looking at the [modules-page](https://hapi.dev/module/?sort=name), but we're not using most of these. +The backend is built around Hapi. Hapi is a configuration oriented framework for creating backend services. It has a huge ecosystem of modules and plugins, and has no external dependencies which means more control of security. It can be a bit overwhelming when looking at the [modules-page](https://hapi.dev/module/?sort=name), but we're not using most of these. -The most important modules to get familiar with are *Joi*, *Boom* and *Bounce*. +The most important modules to get familiar with are _Joi_, _Boom_ and _Bounce_. -**Joi** is an extremely powerful library for describing and validating data. It has since the start of the project left the Hapi-ecosystem and is now standalone, but is still an integral part of Hapi, but it can now be used without it as well. We are using Joi to validate everything from post-data and query-params to database-data. The cool thing about Joi is that it can be easily used to transform and coerce your data as well. This means that we have one place to describe the validation, requirements and transformation of data in our application. We will come back to how integral Joi is in the application later when delving into the architecture. +**Joi** is an extremely powerful library for describing and validating data. It has since the start of the project left the Hapi-ecosystem and is now standalone, but is still an integral part of Hapi, but it can now be used without it as well. We are using Joi to validate everything from post-data and query-params to database-data. The cool thing about Joi is that it can be easily used to transform and coerce your data as well. This means that we have one place to describe the validation, requirements and transformation of data in our application. We will come back to how integral Joi is in the application later when delving into the architecture. **Boom** is used to generate HTTP-friendly error objects. It is used explicitly a few places to generate a particular error-response. Most importantly, it is used internally by Hapi and all uncaught errors in route-handlers will result in a Boom-object with a 500-statuscode. It's also worth mentioning the custom Error-mapper-plugin, which tries to map uncaught database errors to the respective HTTP-statuscode. For instance, when postgres encounters a unique violation, the plugin will run after the handler (hooking into the `onPreResponse` lifecycle-method`), mapping this to a 409-conflict HTTP-error. This means that most of the time we do not need to explicitly check for constraint violations, not found errors etc, and can thus return the db-query directly. @@ -22,15 +20,15 @@ It's also worth mentioning the custom Error-mapper-plugin, which tries to map un **Bounce** is a simple library that makes it easy to rethrow syntax errors. When using `async/await` application errors and developer errors like syntax-errors are combined into one "channel", and without selective exception catching in javascript it can be quite annoying to debug if you've caught an error without logging it. So we use `Bounce.rethrow(error, 'system') to rethrow such developer errors, while safely ignoring expected application errors. **Knex** is a lightweight sql-builder that also handles migrations and seeding of the database. All database changes are written as migrations. Use `knex migrate:make name` to create a new migration. The server will try to migrate to the latest version on startup. -It was decided that we were not going to use an ORM for database-entities. Knex is a good fit as it's very bare-bones, and thus we handle all the database logic ourself. +It was decided that we were not going to use an ORM for database-entities. Knex is a good fit as it's very bare-bones, and thus we handle all the database logic ourself. The API is a bit weird, as it coerces the builder object to a promise when `query.then()` (or `await query`) is called. It is not executed intil one of those are called. -## Architecture +## Architecture ### Architecture v1 -When delving into the code you might notice that there are quite some differences between API v1-routes and v2-routes. This is due to an effort to improve the code-quality and architecture of the code for v2-routes. +When delving into the code you might notice that there are quite some differences between API v1-routes and v2-routes. This is due to an effort to improve the code-quality and architecture of the code for v2-routes. Again, v1 was started to mirror the old Java- API, and was written pretty "straight forward" with the goal of having a version that works. While most of the DB-queries are handled in their own function (in the `data`-folder), handlers grew quite big and we were having problems and bugs with transactions not being closed properly etc. It was a mess to deal with multiple transactions within a handler of hundreds of lines. @@ -38,26 +36,24 @@ This sparked an effort to design a more cohesive and generalized way to handle D ### Towards v2 -The main problems that we wanted to solve was the problem with messy transactions and composability of operations. We also wanted a better way to handle transformation/formatting of data between the database and application code. +The main problems that we wanted to solve was the problem with messy transactions and composability of operations. We also wanted a better way to handle transformation/formatting of data between the database and application code. -It turns out that the transaction-object in the callback of `knex.transaction(trx => {})` can be used in the exact same way as the bound `knex`-object and will then run the query in that transaction. More importantly: knex will automatically rollback any changes to the database if that callback throws an error. This meant that we could easily compose seperate operations without messy catch-handlers with `rollback()`s scattered everywhere. +It turns out that the transaction-object in the callback of `knex.transaction(trx => {})` can be used in the exact same way as the bound `knex`-object and will then run the query in that transaction. More importantly: knex will automatically rollback any changes to the database if that callback throws an error. This meant that we could easily compose seperate operations without messy catch-handlers with `rollback()`s scattered everywhere. -This resulted in a `service`-like architecture. Note that nothing here is set in stone and very much subject to change, and any feedback is very welcome. +This resulted in a `service`-like architecture. Note that nothing here is set in stone and very much subject to change, and any feedback is very welcome. -#### Services and models +#### Services and models -A `Service` is a module which exports functions that encapsulate CRUD-operations on an entity (like Organisation or User). Most of the time, a service should be paired with a `Model`. In it's core a `Model` is basically a `Joi-schema` that describes a particular entity, eg. an Organisation or an User. Joi-schemas are immutable, and can be "extended" using the [append() or keys()](https://joi.dev/api/?v=17.3.0#objectappendschema) method, so we have a [Default](./server/src/models/v2/Default.js)-model that describes properties shared by all entities. +A `Service` is a module which exports functions that encapsulate CRUD-operations on an entity (like Organisation or User). Most of the time, a service should be paired with a `Model`. In it's core a `Model` is basically a `Joi-schema` that describes a particular entity, eg. an Organisation or an User. Joi-schemas are immutable, and can be "extended" using the [append() or keys()](https://joi.dev/api/?v=17.3.0#objectappendschema) method, so we have a [Default](./server/src/models/v2/Default.js)-model that describes properties shared by all entities. All service-functions take a `knex`-parameters as the final parameter. This can be either a bound `knex`-instance, or a `transaction`-object from `knex.transaction()`, as mentioned above these can be used interchangeably. A service-function should always take and return internal data-structures, it's up to the function to transform the results from a query to interal structure. These functions are pretty similar to the old architecture's `data`-functions. However they are a bit more structured and composable. They are also easily integrated as [service-methods](https://hapi.dev/api/?v=20.0.1#server.methods), and thus cacheable. -The `Model`-module exports Joi-schema definitions, along with functions `parseDatabaseJson` and `formatDatabaseJson`. The idea is that we have at least two definitions; database-definition and internal-definition. We could also have a third one for external schemas, but this should be mostly the same as the internal one as there is no need to complicate it further. These definitions can be used in any [hapi-validate](https://hapi.dev/api/?v=20.0.1#-routeoptionsvalidate)-function. The idea is that you use all the Joi-goodness for usecases like restricting and renames of keys. For instance `definition.without('sensitive')`. `Joi.alter()` can be used to group such transformations for a particular alteration, see [tailor()](https://joi.dev/api/?v=17.3.0#anytailortargets). +The `Model`-module exports Joi-schema definitions, along with functions `parseDatabaseJson` and `formatDatabaseJson`. The idea is that we have at least two definitions; database-definition and internal-definition. We could also have a third one for external schemas, but this should be mostly the same as the internal one as there is no need to complicate it further. These definitions can be used in any [hapi-validate](https://hapi.dev/api/?v=20.0.1#-routeoptionsvalidate)-function. The idea is that you use all the Joi-goodness for usecases like restricting and renames of keys. For instance `definition.without('sensitive')`. `Joi.alter()` can be used to group such transformations for a particular alteration, see [tailor()](https://joi.dev/api/?v=17.3.0#anytailortargets). `parseDatabaseJson()` is meant to be a function that can be overriden for more specific transformations, and will be called with the result of a database-query and is meant to return the data for internal application use. `formatDatabaseJson` is the opposite - it takes data from the application and transforms it to database-friendly objects. - Many would think that services and the models should be classes, and I've been a bit back and forth. I'm deliberately not using classes unless it's needed, and most of the time that means when you need state. Up to now these do not need state, but it could make sense to have a base-class that lays out the structure of these modules. But classes needs to instantiated, and that would mean bootstrapping the services on startup which is annoying in itself, and the methods would also not be statically available. [Schmervice](https://github.com/hapipal/schmervice) is also something we could consider. #### Plugins Plugins are essential to the Hapi-ecosystem, but they are not just for sharing generic code across projects. They are great when you want to encapsulate logic that should run across routes during the [request lifecycle](https://hapi.dev/api/?v=20.0.1#request-lifecycle), even just for internal use. - diff --git a/package.json b/package.json index 58145e060..4135cb215 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "clone": "yarn workspace tools clone", "format": "yarn format:js && yarn format:text", "format:staged": "yarn format:js --staged && yarn format:text --staged", - "format:js": "d2-style js apply", - "format:text": "d2-style text apply", + "format:js": "d2-style apply js", + "format:text": "d2-style apply text", "format:client": "yarn workspace client format", "format:server": "yarn workspace client format" }, diff --git a/server/migrations/20190130113004_user.js b/server/migrations/20190130113004_user.js index 818a53b94..312f996cf 100644 --- a/server/migrations/20190130113004_user.js +++ b/server/migrations/20190130113004_user.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('users', table => { +exports.up = async (knex) => { + await knex.schema.createTable('users', (table) => { table.uuid('id').primary() table @@ -15,7 +15,7 @@ exports.up = async knex => { table.string('name', 255) }) - await knex.schema.createTable('user_external_id', table => { + await knex.schema.createTable('user_external_id', (table) => { table.uuid('id').primary() table @@ -27,16 +27,13 @@ exports.up = async knex => { table.uuid('user_id').notNullable() - table - .foreign('user_id') - .references('id') - .inTable('users') + table.foreign('user_id').references('id').inTable('users') table.timestamp('updated_at', true) }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('user_external_id') await knex.schema.dropTable('users') } diff --git a/server/migrations/20190130121634_organisation.js b/server/migrations/20190130121634_organisation.js index 37cf734bd..f422a2b8c 100644 --- a/server/migrations/20190130121634_organisation.js +++ b/server/migrations/20190130121634_organisation.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('organisation', table => { +exports.up = async (knex) => { + await knex.schema.createTable('organisation', (table) => { table.uuid('id').primary() table @@ -9,10 +9,7 @@ exports.up = async knex => { table.uuid('created_by_user_id').notNullable() - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') table.timestamp('updated_at', true) @@ -22,6 +19,6 @@ exports.up = async knex => { }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('organisation') } diff --git a/server/migrations/20190130121824_user-organisation.js b/server/migrations/20190130121824_user-organisation.js index 37aa6045c..105d0f5a3 100644 --- a/server/migrations/20190130121824_user-organisation.js +++ b/server/migrations/20190130121824_user-organisation.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('user_organisation', table => { +exports.up = async (knex) => { + await knex.schema.createTable('user_organisation', (table) => { table .timestamp('created_at', true) .defaultTo(knex.fn.now()) @@ -13,10 +13,7 @@ exports.up = async knex => { table.unique(['user_id', 'organisation_id']) - table - .foreign('user_id') - .references('id') - .inTable('users') + table.foreign('user_id').references('id').inTable('users') table .foreign('organisation_id') @@ -34,7 +31,7 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('DROP VIEW users_with_organisations') await knex.schema.dropTable('user_organisation') } diff --git a/server/migrations/20190130140037_app.js b/server/migrations/20190130140037_app.js index 092699245..3b171c64f 100644 --- a/server/migrations/20190130140037_app.js +++ b/server/migrations/20190130140037_app.js @@ -1,7 +1,7 @@ const { AppStatus, AppType } = require('../src/enums') -exports.up = async knex => { - await knex.schema.createTable('app', table => { +exports.up = async (knex) => { + await knex.schema.createTable('app', (table) => { table.uuid('id').primary() table.enu('type', [ @@ -30,23 +30,14 @@ exports.up = async knex => { .references('id') .inTable('organisation') - table - .foreign('developer_user_id') - .references('id') - .inTable('users') + table.foreign('developer_user_id').references('id').inTable('users') - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') - table - .foreign('updated_by_user_id') - .references('id') - .inTable('users') + table.foreign('updated_by_user_id').references('id').inTable('users') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app') } diff --git a/server/migrations/20190130140038_app_version.js b/server/migrations/20190130140038_app_version.js index 52e16eae6..d1da144d0 100644 --- a/server/migrations/20190130140038_app_version.js +++ b/server/migrations/20190130140038_app_version.js @@ -1,7 +1,7 @@ const { AppStatus, AppType } = require('../src/enums') -exports.up = async knex => { - await knex.schema.createTable('app_version', table => { +exports.up = async (knex) => { + await knex.schema.createTable('app_version', (table) => { table.uuid('id').primary() table.uuid('app_id').notNullable() @@ -31,18 +31,12 @@ exports.up = async knex => { table.string('demo_url', 500) - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') - table - .foreign('updated_by_user_id') - .references('id') - .inTable('users') + table.foreign('updated_by_user_id').references('id').inTable('users') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app_version') } diff --git a/server/migrations/20190130140039_app_version_localised.js b/server/migrations/20190130140039_app_version_localised.js index 4a1bef69a..b415d48fe 100644 --- a/server/migrations/20190130140039_app_version_localised.js +++ b/server/migrations/20190130140039_app_version_localised.js @@ -1,7 +1,7 @@ const { AppStatus, AppType } = require('../src/enums') -exports.up = async knex => { - await knex.schema.createTable('app_version_localised', table => { +exports.up = async (knex) => { + await knex.schema.createTable('app_version_localised', (table) => { table.uuid('id').primary() table.uuid('app_version_id') @@ -30,22 +30,16 @@ exports.up = async knex => { table.uuid('created_by_user_id').notNullable() - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') table.timestamp('updated_at', true).defaultTo(knex.fn.now()) table.uuid('updated_by_user_id') - table - .foreign('updated_by_user_id') - .references('id') - .inTable('users') + table.foreign('updated_by_user_id').references('id').inTable('users') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app_version_localised') } diff --git a/server/migrations/20190130140040_app_status.js b/server/migrations/20190130140040_app_status.js index 24794b981..ff2e1313b 100644 --- a/server/migrations/20190130140040_app_status.js +++ b/server/migrations/20190130140040_app_status.js @@ -1,7 +1,7 @@ const { AppStatus } = require('../src/enums') -exports.up = async knex => { - await knex.schema.createTable('app_status', table => { +exports.up = async (knex) => { + await knex.schema.createTable('app_status', (table) => { table.uuid('id').primary() table.uuid('app_id').notNullable() @@ -26,13 +26,10 @@ exports.up = async knex => { .inTable('app') .onDelete('CASCADE') - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app_status') } diff --git a/server/migrations/20190130161337_review.js b/server/migrations/20190130161337_review.js index a8160a3d8..c602e5c1a 100644 --- a/server/migrations/20190130161337_review.js +++ b/server/migrations/20190130161337_review.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('review', table => { +exports.up = async (knex) => { + await knex.schema.createTable('review', (table) => { table.uuid('id').primary() table.uuid('app_version_id').notNullable() @@ -31,7 +31,7 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('DROP VIEW app_review') await knex.schema.dropTable('review') } diff --git a/server/migrations/20190130170039_appchannel.js b/server/migrations/20190130170039_appchannel.js index 466c601be..801b3d1af 100644 --- a/server/migrations/20190130170039_appchannel.js +++ b/server/migrations/20190130170039_appchannel.js @@ -1,30 +1,18 @@ -exports.up = async knex => { - await knex.schema.createTable('channel', table => { +exports.up = async (knex) => { + await knex.schema.createTable('channel', (table) => { table.uuid('id').primary() - table - .string('name', 50) - .unique() - .notNullable() + table.string('name', 50).unique().notNullable() }) - await knex.schema.createTable('app_channel', table => { + await knex.schema.createTable('app_channel', (table) => { table.uuid('id').primary() - table - .uuid('app_version_id') - .unsigned() - .notNullable() + table.uuid('app_version_id').unsigned().notNullable() - table - .uuid('channel_id') - .unsigned() - .notNullable() + table.uuid('channel_id').unsigned().notNullable() - table - .string('min_dhis2_version', 10) - .notNullable() - .index() + table.string('min_dhis2_version', 10).notNullable().index() table.string('max_dhis2_version', 10).index() @@ -33,20 +21,11 @@ exports.up = async knex => { .defaultTo(knex.fn.now()) .notNullable() - table - .uuid('created_by_user_id') - .unsigned() - .notNullable() + table.uuid('created_by_user_id').unsigned().notNullable() - table - .foreign('created_by_user_id') - .references('id') - .inTable('users') + table.foreign('created_by_user_id').references('id').inTable('users') - table - .foreign('channel_id') - .references('id') - .inTable('channel') + table.foreign('channel_id').references('id').inTable('channel') table .timestamp('updated_at', true) @@ -55,14 +34,11 @@ exports.up = async knex => { table.uuid('updated_by_user_id').unsigned() - table - .foreign('updated_by_user_id') - .references('id') - .inTable('users') + table.foreign('updated_by_user_id').references('id').inTable('users') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app_channel') await knex.schema.dropTable('channel') } diff --git a/server/migrations/20190320113801_mediatype.js b/server/migrations/20190320113801_mediatype.js index 2b4087b72..c4b4d9c85 100644 --- a/server/migrations/20190320113801_mediatype.js +++ b/server/migrations/20190320113801_mediatype.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('media_type', table => { +exports.up = async (knex) => { + await knex.schema.createTable('media_type', (table) => { table.uuid('id').primary() table.string('description', 100) @@ -8,6 +8,6 @@ exports.up = async knex => { }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('media_type') } diff --git a/server/migrations/20190320113929_appversionmedia.js b/server/migrations/20190320113929_appversionmedia.js index d60c1d48c..524fc9f08 100644 --- a/server/migrations/20190320113929_appversionmedia.js +++ b/server/migrations/20190320113929_appversionmedia.js @@ -1,5 +1,5 @@ -exports.up = async knex => { - await knex.schema.createTable('app_version_media', table => { +exports.up = async (knex) => { + await knex.schema.createTable('app_version_media', (table) => { table.uuid('id').primary() table @@ -17,10 +17,7 @@ exports.up = async knex => { table.uuid('media_type_id').notNullable() - table - .foreign('media_type_id') - .references('id') - .inTable('media_type') + table.foreign('media_type_id').references('id').inTable('media_type') table.uuid('app_version_id').notNullable() @@ -32,6 +29,6 @@ exports.up = async knex => { }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.schema.dropTable('app_version_media') } diff --git a/server/migrations/20190430133756_media_add_caption_desc.js b/server/migrations/20190430133756_media_add_caption_desc.js index e6c8af108..b308dbb13 100644 --- a/server/migrations/20190430133756_media_add_caption_desc.js +++ b/server/migrations/20190430133756_media_add_caption_desc.js @@ -1,12 +1,12 @@ -exports.up = async knex => { - await knex.schema.alterTable('app_version_media', table => { +exports.up = async (knex) => { + await knex.schema.alterTable('app_version_media', (table) => { table.string('caption', 255) table.string('description', 255) }) } exports.down = async (knex, Promise) => { - await knex.schema.alterTable('app_version_media', table => { + await knex.schema.alterTable('app_version_media', (table) => { table.dropColumns('caption', 'description') }) } diff --git a/server/migrations/20190430133758_app_view.js b/server/migrations/20190430133758_app_view.js index e94f2cfa3..279380121 100644 --- a/server/migrations/20190430133758_app_view.js +++ b/server/migrations/20190430133758_app_view.js @@ -1,4 +1,4 @@ -exports.up = async knex => { +exports.up = async (knex) => { await knex.raw(` CREATE VIEW apps_view AS SELECT app.id AS app_id, @@ -40,6 +40,6 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('DROP VIEW apps_view') } diff --git a/server/migrations/20190430134957_apps_view_media_caption_desc.js b/server/migrations/20190430134957_apps_view_media_caption_desc.js index 316135284..59b73b62d 100644 --- a/server/migrations/20190430134957_apps_view_media_caption_desc.js +++ b/server/migrations/20190430134957_apps_view_media_caption_desc.js @@ -1,4 +1,4 @@ -exports.up = async knex => { +exports.up = async (knex) => { await knex.raw(` DROP VIEW apps_view; CREATE VIEW apps_view AS @@ -42,7 +42,7 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw(` DROP VIEW apps_view; CREATE VIEW apps_view AS diff --git a/server/migrations/20191217103142_auto-uuid.js b/server/migrations/20191217103142_auto-uuid.js index db63c980d..1c49c30c3 100644 --- a/server/migrations/20191217103142_auto-uuid.js +++ b/server/migrations/20191217103142_auto-uuid.js @@ -13,7 +13,7 @@ const tables = [ 'organisation', ] -exports.up = async knex => { +exports.up = async (knex) => { try { const rawResult = await knex.raw( `select usesuper from pg_user where usename = CURRENT_USER;` @@ -34,11 +34,11 @@ exports.up = async knex => { } //requires this to be run with correct privileges on the database: create extension if not exists "uuid-ossp" - await Promise.all(tables.map(async table => setDefault(table, knex))) + await Promise.all(tables.map(async (table) => setDefault(table, knex))) } -exports.down = async knex => { - await Promise.all(tables.map(async table => dropDefault(table, knex))) +exports.down = async (knex) => { + await Promise.all(tables.map(async (table) => dropDefault(table, knex))) try { const rawResult = await knex.raw( diff --git a/server/migrations/20200203182043_fix_view_users_with_organisations.js b/server/migrations/20200203182043_fix_view_users_with_organisations.js index 8293b38cf..f2510d4ec 100644 --- a/server/migrations/20200203182043_fix_view_users_with_organisations.js +++ b/server/migrations/20200203182043_fix_view_users_with_organisations.js @@ -1,4 +1,4 @@ -exports.up = async knex => { +exports.up = async (knex) => { await knex.raw('DROP VIEW users_with_organisations') await knex.raw(` CREATE VIEW users_with_organisations @@ -10,7 +10,7 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('DROP VIEW users_with_organisations') await knex.raw(` CREATE VIEW users_with_organisations diff --git a/server/migrations/20200310134835_refactor-media.js b/server/migrations/20200310134835_refactor-media.js index 24b27dadb..f316c90ac 100644 --- a/server/migrations/20200310134835_refactor-media.js +++ b/server/migrations/20200310134835_refactor-media.js @@ -1,10 +1,10 @@ -exports.up = async knex => { +exports.up = async (knex) => { await knex.raw('DROP VIEW apps_view') await knex.raw('ALTER TABLE media_type RENAME TO mime_type') //Create the new separate media table - await knex.schema.createTable('media', table => { + await knex.schema.createTable('media', (table) => { table.uuid('id').primary() table.string('original_filename', 255).notNullable() @@ -21,22 +21,16 @@ exports.up = async knex => { table.string('caption', 255) table.string('description', 255) - table - .foreign('mime_type_id') - .references('id') - .inTable('mime_type') + table.foreign('mime_type_id').references('id').inTable('mime_type') }) //Link between app and media - await knex.schema.createTable('app_media', table => { + await knex.schema.createTable('app_media', (table) => { table.uuid('id').primary() table.uuid('media_id') - table - .foreign('media_id') - .references('id') - .inTable('media') + table.foreign('media_id').references('id').inTable('media') table .integer('media_type') //enum/integer from code so no uuid here. Logo or Screenshot @@ -144,11 +138,11 @@ exports.up = async knex => { `) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('ALTER TABLE mime_type RENAME TO media_type') //create a new app_version_media table to match the previous version - await knex.schema.createTable('app_version_media', table => { + await knex.schema.createTable('app_version_media', (table) => { table.uuid('id').primary() table @@ -169,10 +163,7 @@ exports.down = async knex => { table.uuid('media_type_id').notNullable() - table - .foreign('media_type_id') - .references('id') - .inTable('media_type') + table.foreign('media_type_id').references('id').inTable('media_type') table.uuid('app_version_id').notNullable() diff --git a/server/migrations/20200924140557_version-replace-underscore.js b/server/migrations/20200924140557_version-replace-underscore.js index a9c6ef868..6d33eb4e0 100644 --- a/server/migrations/20200924140557_version-replace-underscore.js +++ b/server/migrations/20200924140557_version-replace-underscore.js @@ -1,4 +1,4 @@ -exports.up = function(knex) { +exports.up = function (knex) { return knex.raw( `update app_version set version = replace(version, '_', '.') @@ -7,6 +7,6 @@ exports.up = function(knex) { ) } -exports.down = function(knex) { +exports.down = function (knex) { return Promise.resolve() } diff --git a/server/migrations/20201006112837_add_organisation_email.js b/server/migrations/20201006112837_add_organisation_email.js index 25719a291..9b9acf2e6 100644 --- a/server/migrations/20201006112837_add_organisation_email.js +++ b/server/migrations/20201006112837_add_organisation_email.js @@ -1,11 +1,11 @@ -exports.up = function(knex) { - return knex.schema.table('organisation', table => { +exports.up = function (knex) { + return knex.schema.table('organisation', (table) => { table.string('email') }) } -exports.down = function(knex) { - return knex.schema.table('organisation', table => { +exports.down = function (knex) { + return knex.schema.table('organisation', (table) => { table.dropColumn('email') }) } diff --git a/server/migrations/20210209171106_api-key.js b/server/migrations/20210209171106_api-key.js index 29233fc2e..5bc58dfbf 100644 --- a/server/migrations/20210209171106_api-key.js +++ b/server/migrations/20210209171106_api-key.js @@ -1,16 +1,10 @@ -exports.up = async function(knex) { - await knex.schema.createTable('user_api_key', table => { +exports.up = async function (knex) { + await knex.schema.createTable('user_api_key', (table) => { table.string('hashed_api_key', 64).primary() // sha256 in hex representation is 64 chars - table - .uuid('user_id') - .notNullable() - .unique() + table.uuid('user_id').notNullable().unique() - table - .foreign('user_id') - .references('id') - .inTable('users') + table.foreign('user_id').references('id').inTable('users') table .timestamp('created_at', true) @@ -19,6 +13,6 @@ exports.up = async function(knex) { }) } -exports.down = async function(knex) { +exports.down = async function (knex) { await knex.schema.dropTable('user_api_key') } diff --git a/server/migrations/20210223140633_rename_channels.js b/server/migrations/20210223140633_rename_channels.js index 9455d0aee..aa722be4b 100644 --- a/server/migrations/20210223140633_rename_channels.js +++ b/server/migrations/20210223140633_rename_channels.js @@ -1,11 +1,15 @@ -exports.up = async knex => { +exports.up = async (knex) => { await knex.raw(`UPDATE channel SET name = 'stable' WHERE name = 'Stable'`) - await knex.raw(`UPDATE channel SET name = 'development' WHERE name = 'Development'`) + await knex.raw( + `UPDATE channel SET name = 'development' WHERE name = 'Development'` + ) await knex.raw(`UPDATE channel SET name = 'canary' WHERE name = 'Canary'`) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw(`UPDATE channel SET name = 'Stable' WHERE name = 'stable'`) - await knex.raw(`UPDATE channel SET name = 'Development' WHERE name = 'development'`) + await knex.raw( + `UPDATE channel SET name = 'Development' WHERE name = 'development'` + ) await knex.raw(`UPDATE channel SET name = 'Canary' WHERE name = 'canary'`) } diff --git a/server/migrations/20210420135804_user-allow-duplicate-emails.js b/server/migrations/20210420135804_user-allow-duplicate-emails.js index a96842ddd..3ac325f6a 100644 --- a/server/migrations/20210420135804_user-allow-duplicate-emails.js +++ b/server/migrations/20210420135804_user-allow-duplicate-emails.js @@ -1,9 +1,9 @@ -exports.up = async knex => { - await knex.schema.table('users', table => { +exports.up = async (knex) => { + await knex.schema.table('users', (table) => { table.dropUnique('email') }) - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.string('contact_email', 255) }) @@ -58,23 +58,20 @@ exports.up = async knex => { ON org.id = app.organisation_id `) - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.dropColumn('developer_user_id') }) } -exports.down = async knex => { +exports.down = async (knex) => { await knex.raw('DROP VIEW apps_view') - await knex.schema.table('users', table => { + await knex.schema.table('users', (table) => { table.unique('email') }) - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.uuid('developer_user_id') - table - .foreign('developer_user_id') - .references('id') - .inTable('users') + table.foreign('developer_user_id').references('id').inTable('users') }) // if duplicate email, only one will be kept @@ -85,12 +82,9 @@ exports.down = async knex => { where u.email = a.contact_email `) - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.dropColumn('contact_email') - table - .uuid('developer_user_id') - .notNullable() - .alter() + table.uuid('developer_user_id').notNullable().alter() }) await knex.raw(` diff --git a/server/migrations/20210705145813_core-app.js b/server/migrations/20210705145813_core-app.js index 019991427..04683daef 100644 --- a/server/migrations/20210705145813_core-app.js +++ b/server/migrations/20210705145813_core-app.js @@ -1,5 +1,5 @@ exports.up = async function (knex) { - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.boolean('core_app').defaultTo(false) }) await knex.raw('DROP VIEW apps_view') @@ -49,7 +49,7 @@ exports.up = async function (knex) { exports.down = async function (knex) { await knex.raw('DROP VIEW apps_view') - await knex.schema.table('app', table => { + await knex.schema.table('app', (table) => { table.dropColumn('core_app') }) diff --git a/server/migrations/20220407123044_download_count.js b/server/migrations/20220407123044_download_count.js index 837396055..c385774e1 100644 --- a/server/migrations/20220407123044_download_count.js +++ b/server/migrations/20220407123044_download_count.js @@ -1,11 +1,11 @@ -exports.up = async knex => { - return knex.schema.table('app_version', table => { +exports.up = async (knex) => { + return knex.schema.table('app_version', (table) => { table.integer('download_count').defaultTo(0).notNullable() }) } -exports.down = async knex => { - return knex.schema.table('app_version', table => { +exports.down = async (knex) => { + return knex.schema.table('app_version', (table) => { table.dropColumn('download_count') }) } diff --git a/server/seeds/01_organisation-developers.js b/server/seeds/01_organisation-developers.js index cac8d25de..ef45b953c 100644 --- a/server/seeds/01_organisation-developers.js +++ b/server/seeds/01_organisation-developers.js @@ -1,11 +1,11 @@ const users = require('./mock/users') const organisations = require('./mock/organisations') -const sleep = ms => { - return new Promise(resolve => setTimeout(resolve, ms)) +const sleep = (ms) => { + return new Promise((resolve) => setTimeout(resolve, ms)) } -exports.seed = async knex => { +exports.seed = async (knex) => { console.log('Starting seeding data') console.log(knex.client.config) diff --git a/server/seeds/02_app.js b/server/seeds/02_app.js index e82eae56a..0ba9669c9 100644 --- a/server/seeds/02_app.js +++ b/server/seeds/02_app.js @@ -44,7 +44,7 @@ const statuses = [ }, ] -exports.seed = async knex => { +exports.seed = async (knex) => { console.log('Seeding apps') await knex('app').del() diff --git a/server/seeds/03_review.js b/server/seeds/03_review.js index 76f59ba67..ea9599600 100644 --- a/server/seeds/03_review.js +++ b/server/seeds/03_review.js @@ -3,7 +3,7 @@ const appVersions = require('./mock/appversions') const [dhis2AppVersions, whoAppVersions] = appVersions -exports.seed = async knex => { +exports.seed = async (knex) => { console.log('Seeding reviews') const reviews = [ diff --git a/server/seeds/04_appchannel.js b/server/seeds/04_appchannel.js index dee38beec..a7e92f28e 100644 --- a/server/seeds/04_appchannel.js +++ b/server/seeds/04_appchannel.js @@ -9,7 +9,7 @@ const [ canaryOnlyDashboardWidgetVersions, ] = appVersions -exports.seed = async knex => { +exports.seed = async (knex) => { console.log('Seeding channels') await knex('app_channel').del() diff --git a/server/seeds/05_media.js b/server/seeds/05_media.js index 1bb808b85..8ac28badb 100644 --- a/server/seeds/05_media.js +++ b/server/seeds/05_media.js @@ -6,7 +6,7 @@ const users = require('./mock/users') const mediaTypeSeedData = require('./mock/mime_type') -exports.seed = async knex => { +exports.seed = async (knex) => { console.log('Seeding media') const mediaIds = [ diff --git a/server/seeds/mock/appversions.js b/server/seeds/mock/appversions.js index 9f02515fc..8e4c500cd 100644 --- a/server/seeds/mock/appversions.js +++ b/server/seeds/mock/appversions.js @@ -56,8 +56,6 @@ const dhis2AppVersions = [ version: '1.1.0', created_at: createdAtDate(), }, - - ] const whoAppVersions = [ { diff --git a/server/src/data/addUserToOrganisation.js b/server/src/data/addUserToOrganisation.js index 4156d786f..6d0a1791e 100644 --- a/server/src/data/addUserToOrganisation.js +++ b/server/src/data/addUserToOrganisation.js @@ -3,14 +3,8 @@ const joi = require('joi') const paramsSchema = joi .object() .keys({ - userId: joi - .string() - .uuid() - .required(), - organisationId: joi - .string() - .uuid() - .required(), + userId: joi.string().uuid().required(), + organisationId: joi.string().uuid().required(), }) .options({ allowUnknown: true }) diff --git a/server/src/data/appExists.js b/server/src/data/appExists.js index 4ccf627e3..c6bfc7fd3 100644 --- a/server/src/data/appExists.js +++ b/server/src/data/appExists.js @@ -7,9 +7,7 @@ const appExists = async (appId, knex) => { //Make sure the app exist try { - const app = await knex('app') - .select() - .where('id', appId) + const app = await knex('app').select().where('id', appId) return app && app.length > 0 } catch (err) { diff --git a/server/src/data/deleteApp.js b/server/src/data/deleteApp.js index b18749960..7200b8932 100644 --- a/server/src/data/deleteApp.js +++ b/server/src/data/deleteApp.js @@ -8,9 +8,7 @@ const debug = require('debug')('apphub:server:data:deleteApp') */ const deleteApp = async (id, knex) => { try { - await knex('app') - .where('id', id) - .del() + await knex('app').where('id', id).del() debug('deleted app', id) } catch (err) { debug(err) diff --git a/server/src/data/deleteAppMedia.js b/server/src/data/deleteAppMedia.js index 5f4baddfa..fd3c302c1 100644 --- a/server/src/data/deleteAppMedia.js +++ b/server/src/data/deleteAppMedia.js @@ -8,9 +8,7 @@ const debug = require('debug')('apphub:server:data:deleteMedia') */ const deleteAppMedia = async (id, knex) => { try { - await knex('app_media') - .where('id', id) - .del() + await knex('app_media').where('id', id).del() debug('deleted app_media', id) } catch (err) { debug(err) diff --git a/server/src/data/deleteAppVersion.js b/server/src/data/deleteAppVersion.js index 8ef5f5031..98c37e863 100644 --- a/server/src/data/deleteAppVersion.js +++ b/server/src/data/deleteAppVersion.js @@ -8,9 +8,7 @@ const debug = require('debug')('apphub:server:data:deleteAppVersion') */ const deleteAppVersion = async (id, knex) => { try { - await knex('app_version') - .where('id', id) - .del() + await knex('app_version').where('id', id).del() debug('deleted app version', id) } catch (err) { debug(err) diff --git a/server/src/data/deleteChannel.js b/server/src/data/deleteChannel.js index 192034b2a..8c319af6d 100644 --- a/server/src/data/deleteChannel.js +++ b/server/src/data/deleteChannel.js @@ -13,9 +13,7 @@ module.exports = async (uuid, knex) => { } debug('trying to delete the channel') - const deletedRows = await knex('channel') - .where('id', uuid) - .del() + const deletedRows = await knex('channel').where('id', uuid).del() debug(`deleted ${deletedRows} rows in table channel for uuid ${uuid}`) diff --git a/server/src/data/deleteMedia.js b/server/src/data/deleteMedia.js index f798ec5fa..c07acf679 100644 --- a/server/src/data/deleteMedia.js +++ b/server/src/data/deleteMedia.js @@ -8,9 +8,7 @@ const debug = require('debug')('apphub:server:data:deleteMedia') */ const deleteMedia = async (id, knex) => { try { - await knex('media') - .where('id', id) - .del() + await knex('media').where('id', id).del() debug('deleted media', id) } catch (err) { debug(err) diff --git a/server/src/data/deleteOrganisation.js b/server/src/data/deleteOrganisation.js index 9817a4ab8..b86689118 100644 --- a/server/src/data/deleteOrganisation.js +++ b/server/src/data/deleteOrganisation.js @@ -24,9 +24,7 @@ const deleteOrganisation = async (params, knex) => { } try { - const deletedRows = await knex('organisation') - .where(params) - .delete() + const deletedRows = await knex('organisation').where(params).delete() return deletedRows > 0 } catch (err) { diff --git a/server/src/data/getApps.js b/server/src/data/getApps.js index bcb904879..80b1e4236 100644 --- a/server/src/data/getApps.js +++ b/server/src/data/getApps.js @@ -20,23 +20,23 @@ const getApps = ( return knex('apps_view') .select() - .where(builder => { + .where((builder) => { builder.where('status', status) builder.where('language_code', languageCode) if (channels.length > 0) { - builder.where(builder => { + builder.where((builder) => { builder.where('channel_name', channels[0].toLowerCase()) - channels.slice(1).forEach(channel => { + channels.slice(1).forEach((channel) => { builder.orWhere('channel_name', channel.toLowerCase()) }) }) } if (types.length > 0) { - builder.where(builder => { + builder.where((builder) => { builder.where('type', types[0]) - types.slice(1).forEach(type => { + types.slice(1).forEach((type) => { builder.orWhere('type', type) }) }) @@ -47,7 +47,7 @@ const getApps = ( } if (query) { - builder.where(builder => { + builder.where((builder) => { builder.where('name', 'ilike', `%${query}%`) builder.orWhere('organisation', 'ilike', `%${query}%`) }) diff --git a/server/src/data/getOrganisationAppsByUserId.js b/server/src/data/getOrganisationAppsByUserId.js index 1360437cc..c66149f78 100644 --- a/server/src/data/getOrganisationAppsByUserId.js +++ b/server/src/data/getOrganisationAppsByUserId.js @@ -30,9 +30,7 @@ const getOrganisationAppsByUserId = async (id, knex) => { debug('The user has access to apps:', appIds) - return knex('apps_view') - .select() - .where('app_id', 'in', appIds) + return knex('apps_view').select().where('app_id', 'in', appIds) } module.exports = getOrganisationAppsByUserId diff --git a/server/src/data/getOrganisationById.js b/server/src/data/getOrganisationById.js index e540cecea..c8654b139 100644 --- a/server/src/data/getOrganisationById.js +++ b/server/src/data/getOrganisationById.js @@ -1,10 +1,7 @@ const joi = require('joi') const schema = joi.object({ - id: joi - .string() - .uuid() - .required(), + id: joi.string().uuid().required(), }) /** diff --git a/server/src/data/getUserByEmail.js b/server/src/data/getUserByEmail.js index 4daeda794..86081d460 100644 --- a/server/src/data/getUserByEmail.js +++ b/server/src/data/getUserByEmail.js @@ -18,10 +18,7 @@ const getUserByEmail = async (email, knex) => { } try { - user = await knex('users') - .select() - .where('email', email) - .first() + user = await knex('users').select().where('email', email).first() debug('found user', user) } catch (err) { //TODO: log, re-throw or something other than silent fail? diff --git a/server/src/data/renameChannel.js b/server/src/data/renameChannel.js index f921c1846..73a6559cb 100644 --- a/server/src/data/renameChannel.js +++ b/server/src/data/renameChannel.js @@ -4,10 +4,7 @@ const paramsSchema = joi .object() .keys({ name: joi.string().required(), - id: joi - .string() - .uuid() - .required(), + id: joi.string().uuid().required(), }) .options({ allowUnknown: true }) diff --git a/server/src/data/updateApp.js b/server/src/data/updateApp.js index dc96656cc..37f9e7e96 100644 --- a/server/src/data/updateApp.js +++ b/server/src/data/updateApp.js @@ -22,7 +22,7 @@ const paramsSchema = joi }) .options({ allowUnknown: true }) -const isValidSourceUrl = sourceUrl => { +const isValidSourceUrl = (sourceUrl) => { try { const url = new URL(sourceUrl) return url.protocol === 'http:' || url.protocol === 'https:' diff --git a/server/src/data/updateAppVersion.js b/server/src/data/updateAppVersion.js index 34d312022..bb1aa6349 100644 --- a/server/src/data/updateAppVersion.js +++ b/server/src/data/updateAppVersion.js @@ -4,28 +4,12 @@ const joi = require('joi') const paramsSchema = joi .object() .keys({ - id: joi - .string() - .uuid() - .required(), - userId: joi - .string() - .uuid() - .required(), - minDhisVersion: joi - .string() - .allow(null, '') - .max(10), - maxDhisVersion: joi - .string() - .allow(null, '') - .max(10), + id: joi.string().uuid().required(), + userId: joi.string().uuid().required(), + minDhisVersion: joi.string().allow(null, '').max(10), + maxDhisVersion: joi.string().allow(null, '').max(10), version: joi.string(), - demoUrl: joi - .string() - .uri() - .allow('') - .max(500), + demoUrl: joi.string().uri().allow('').max(500), channel: joi.string().allow(null), }) .options({ allowUnknown: true }) @@ -55,14 +39,8 @@ const updateAppVersion = async (params, knex) => { throw new Error('Missing parameter: knex') } - const { - id, - userId, - minDhisVersion, - maxDhisVersion, - version, - demoUrl, - } = params + const { id, userId, minDhisVersion, maxDhisVersion, version, demoUrl } = + params try { await knex('app_version') diff --git a/server/src/data/updateImageMeta.js b/server/src/data/updateImageMeta.js index 44b04b543..f0c61df87 100644 --- a/server/src/data/updateImageMeta.js +++ b/server/src/data/updateImageMeta.js @@ -29,12 +29,10 @@ const updateImageMeta = async (params, knex) => { const { id, caption, description } = params try { - await knex('media') - .where('id', id) - .update({ - caption, - description, - }) + await knex('media').where('id', id).update({ + caption, + description, + }) } catch (err) { throw new Error(`Could not update media meta: ${id}. ${err.message}`) } diff --git a/server/src/main.js b/server/src/main.js index a35f541ff..51ef6ce09 100644 --- a/server/src/main.js +++ b/server/src/main.js @@ -12,26 +12,26 @@ const { createApiUser } = require('./server/create-api-user.js') debug('Using env: ', process.env.NODE_ENV) -process.on('unhandledRejection', err => { +process.on('unhandledRejection', (err) => { debug(err) process.exit(1) }) migrate(knex) - .catch(err => { + .catch((err) => { debug('The database migrations failed to apply.\n', err) process.exit(1) }) .then(() => - knex.transaction(trx => createChannel({ name: 'stable' }, knex, trx)) + knex.transaction((trx) => createChannel({ name: 'stable' }, knex, trx)) ) - .then(r => debug('Channel was created', r)) - .catch(r => debug('Channel probably exists, skipping', r)) - .then(() => knex.transaction(trx => createApiUser(knex, trx))) + .then((r) => debug('Channel was created', r)) + .catch((r) => debug('Channel probably exists, skipping', r)) + .then(() => knex.transaction((trx) => createApiUser(knex, trx))) .then(() => debug('API User was created or already existed')) - .catch(r => debug('API User probably exists, skipping', r)) + .catch((r) => debug('API User probably exists, skipping', r)) .then(() => init(knex, config)) - .catch(err => { + .catch((err) => { debug('The server failed to start.\n', err) process.exit(1) }) diff --git a/server/src/models/v1/App.js b/server/src/models/v1/App.js index d476d9683..d5632d91a 100644 --- a/server/src/models/v1/App.js +++ b/server/src/models/v1/App.js @@ -5,25 +5,13 @@ const { AppStatuses, AppTypes } = require('../../enums') // database def const def = joi.object().keys({ app_id: joi.number().required(), - uuid: joi - .string() - .guid({ version: 'uuidv4' }) - .required(), - - created_at: joi - .date() - .iso() - .required(), - - updated_at: joi - .date() - .iso() - .required(), - - name: joi - .string() - .max(255, 'utf8') - .required(), + uuid: joi.string().guid({ version: 'uuidv4' }).required(), + + created_at: joi.date().iso().required(), + + updated_at: joi.date().iso().required(), + + name: joi.string().max(255, 'utf8').required(), description: joi.string().allow(''), @@ -31,10 +19,7 @@ const def = joi.object().keys({ type: joi.string().valid(...AppTypes), - source_url: joi - .string() - .empty('') - .default(''), + source_url: joi.string().empty('').default(''), // foreign key references developer: joi.number().required(), @@ -43,5 +28,5 @@ const def = joi.object().keys({ module.exports = { def, - validate: obj => def.validate(obj), + validate: (obj) => def.validate(obj), } diff --git a/server/src/models/v1/in/CreateAppModel.js b/server/src/models/v1/in/CreateAppModel.js index e897aa0f8..bdec07177 100644 --- a/server/src/models/v1/in/CreateAppModel.js +++ b/server/src/models/v1/in/CreateAppModel.js @@ -33,5 +33,5 @@ const payloadSchema = Joi.object({ module.exports = { payloadSchema, def: CreateModelAppData, - validate: obj => CreateModelAppData.validate(obj), + validate: (obj) => CreateModelAppData.validate(obj), } diff --git a/server/src/models/v1/in/CreateAppVersionModel.js b/server/src/models/v1/in/CreateAppVersionModel.js index ffb224395..c125dfaf9 100644 --- a/server/src/models/v1/in/CreateAppVersionModel.js +++ b/server/src/models/v1/in/CreateAppVersionModel.js @@ -6,14 +6,10 @@ const { isSemver } = require('../../helpers') */ const CreateAppVersionModel = Joi.object().keys({ - version: Joi.string() - .required() - .custom(isSemver, 'semver validate'), + version: Joi.string().required().custom(isSemver, 'semver validate'), minDhisVersion: Joi.string().required(), maxDhisVersion: Joi.string().allow('', null), - demoUrl: Joi.string() - .uri() - .allow('', null), + demoUrl: Joi.string().uri().allow('', null), channel: Joi.string().required(), }) @@ -26,5 +22,5 @@ const payloadSchema = Joi.object({ module.exports = { payloadSchema, def: CreateAppVersionModel, - validate: obj => CreateAppVersionModel.validate(obj), + validate: (obj) => CreateAppVersionModel.validate(obj), } diff --git a/server/src/models/v1/in/EditAppModel.js b/server/src/models/v1/in/EditAppModel.js index afee91dce..77b664ff8 100644 --- a/server/src/models/v1/in/EditAppModel.js +++ b/server/src/models/v1/in/EditAppModel.js @@ -20,5 +20,5 @@ const EditAppModel = payloadSchema module.exports = { payloadSchema, def: EditAppModel, - validate: objectToValidate => EditAppModel.validate(objectToValidate), + validate: (objectToValidate) => EditAppModel.validate(objectToValidate), } diff --git a/server/src/models/v1/in/EditAppVersionModel.js b/server/src/models/v1/in/EditAppVersionModel.js index 6d0785921..401acfb7f 100644 --- a/server/src/models/v1/in/EditAppVersionModel.js +++ b/server/src/models/v1/in/EditAppVersionModel.js @@ -2,19 +2,10 @@ const joi = require('joi') const { isSemver } = require('../../helpers') const payloadSchema = joi.object({ - demoUrl: joi - .string() - .uri() - .allow(''), + demoUrl: joi.string().uri().allow(''), version: joi.string().custom(isSemver, 'semver validate'), - minDhisVersion: joi - .string() - .required() - .allow(null, ''), - maxDhisVersion: joi - .string() - .required() - .allow(null, ''), + minDhisVersion: joi.string().required().allow(null, ''), + maxDhisVersion: joi.string().required().allow(null, ''), channel: joi.string(), }) @@ -23,6 +14,6 @@ const EditAppVersionModel = payloadSchema module.exports = { payloadSchema, def: EditAppVersionModel, - validate: objectToValidate => + validate: (objectToValidate) => joi.validate(objectToValidate, EditAppVersionModel), } diff --git a/server/src/models/v1/out/Version.js b/server/src/models/v1/out/Version.js index c1e3eda66..5061b9395 100644 --- a/server/src/models/v1/out/Version.js +++ b/server/src/models/v1/out/Version.js @@ -6,14 +6,8 @@ module.exports = Joi.object().keys({ maxDhisVersion: Joi.string().allow(null, ''), lastUpdated: Joi.number(), created: Joi.number(), - id: Joi.string() - .guid({ version: 'uuidv4' }) - .required(), - downloadUrl: Joi.string() - .uri() - .allow(''), - demoUrl: Joi.string() - .uri() - .allow(''), + id: Joi.string().guid({ version: 'uuidv4' }).required(), + downloadUrl: Joi.string().uri().allow(''), + demoUrl: Joi.string().uri().allow(''), channel: Joi.string().required(), }) diff --git a/server/src/models/v2/Default.js b/server/src/models/v2/Default.js index 7cda4b6b0..0ef3ce431 100644 --- a/server/src/models/v2/Default.js +++ b/server/src/models/v2/Default.js @@ -25,10 +25,7 @@ const definition = joi .object() .keys({ id: joi.string().guid({ version: 'uuidv4' }), - updatedAt: joi - .date() - .cast('number') - .allow(null), + updatedAt: joi.date().cast('number').allow(null), createdAt: joi.date().cast('number'), }) .rename('updated_at', 'updatedAt', { ignoreUndefined: true }) diff --git a/server/src/models/v2/Organisation.js b/server/src/models/v2/Organisation.js index 0346dac03..22b6266b6 100644 --- a/server/src/models/v2/Organisation.js +++ b/server/src/models/v2/Organisation.js @@ -6,16 +6,13 @@ const { createDefaultValidator } = require('./helpers') const definition = defaultDefinition .append({ name: joi.string().max(100), - email: joi - .string() - .email() - .allow(null), + email: joi.string().email().allow(null), slug: joi.string(), owner: joi.string().guid({ version: 'uuidv4' }), users: joi.array().items(User.definition), }) .alter({ - db: s => + db: (s) => s .append({ created_by_user_id: joi diff --git a/server/src/models/v2/helpers.js b/server/src/models/v2/helpers.js index cc5811900..5ac7751c3 100644 --- a/server/src/models/v2/helpers.js +++ b/server/src/models/v2/helpers.js @@ -8,10 +8,10 @@ const Joi = require('joi') * @returns {function(dbResult): []} - A function taking some data (may be an array or object) to be validated by the schema. * The function throws a ValidationError if mapping fails */ -const createDefaultValidator = schema => { - return dbResult => +const createDefaultValidator = (schema) => { + return (dbResult) => Array.isArray(dbResult) - ? dbResult.map(v => Joi.attempt(v, schema)) + ? dbResult.map((v) => Joi.attempt(v, schema)) : Joi.attempt(dbResult, schema) } diff --git a/server/src/models/v2/in/CreateAppModel.js b/server/src/models/v2/in/CreateAppModel.js index fbd82bf15..75b703194 100644 --- a/server/src/models/v2/in/CreateAppModel.js +++ b/server/src/models/v2/in/CreateAppModel.js @@ -16,5 +16,5 @@ const payloadSchema = Joi.object({ module.exports = { payloadSchema, def: CreateModelAppData, - validate: obj => CreateModelAppData.validate(obj), + validate: (obj) => CreateModelAppData.validate(obj), } diff --git a/server/src/models/v2/in/EditChannelModel.js b/server/src/models/v2/in/EditChannelModel.js index d3b70e891..7dda39999 100644 --- a/server/src/models/v2/in/EditChannelModel.js +++ b/server/src/models/v2/in/EditChannelModel.js @@ -9,5 +9,5 @@ const EditChannelModel = payloadSchema module.exports = { payloadSchema, def: EditChannelModel, - validate: objectToValidate => EditChannelModel.validate(objectToValidate), + validate: (objectToValidate) => EditChannelModel.validate(objectToValidate), } diff --git a/server/src/models/v2/out/App.js b/server/src/models/v2/out/App.js index aad506ca8..62ed46381 100644 --- a/server/src/models/v2/out/App.js +++ b/server/src/models/v2/out/App.js @@ -8,9 +8,7 @@ const def = Joi.object().keys({ .required() .valid(...AppTypes), - id: Joi.string() - .guid({ version: 'uuidv4' }) - .required(), + id: Joi.string().guid({ version: 'uuidv4' }).required(), }) module.exports = { diff --git a/server/src/plugins/errorMapper.js b/server/src/plugins/errorMapper.js index 3ba095866..7de0ac9a2 100644 --- a/server/src/plugins/errorMapper.js +++ b/server/src/plugins/errorMapper.js @@ -31,20 +31,22 @@ const dbErrorMap = { } const errorMessageMap = { - conflict: (wrappedError) => `${wrappedError.table} with that ${wrappedError.columns.join(',')} already exists.` + conflict: (wrappedError) => + `${wrappedError.table} with that ${wrappedError.columns.join( + ',' + )} already exists.`, } const getErrorMessage = (wrappedError, httpError, options) => { // this is returned regardless if preserveMessage is false - if(errorMessageMap[httpError]) { + if (errorMessageMap[httpError]) { return errorMessageMap[httpError](wrappedError) } return options.preserveMessage ? wrappedError.message : null } - -const onPreResponseHandler = function(request, h) { +const onPreResponseHandler = function (request, h) { const { response: error } = request // not error or joi-error - ignore @@ -63,12 +65,12 @@ const mapError = (error, options) => { const wrappedError = wrapError(error) for (const key in dbErrorMap) { const dbError = dbErrorMap[key].find( - e => wrappedError.constructor.name === e.name + (e) => wrappedError.constructor.name === e.name ) if (dbError) { const message = getErrorMessage(wrappedError, key, options) const boomError = Boom[key](message) - + if (options.preserveMessage) { // Needed to show 500-errors boomError.reformat(true) diff --git a/server/src/plugins/pagination.js b/server/src/plugins/pagination.js index 8189b3f36..beb9db025 100644 --- a/server/src/plugins/pagination.js +++ b/server/src/plugins/pagination.js @@ -68,7 +68,9 @@ const onPreHandler = function (request, h) { }) if (!options.keepParams) { - Object.keys(pagingParams).forEach(key => delete request.query[key]) + Object.keys(pagingParams).forEach( + (key) => delete request.query[key] + ) } request.plugins.pagination = pager } catch (e) { @@ -131,8 +133,8 @@ const paginationPlugin = { // validate plugin settings so that we don't need to do this during runtime server .table() - .filter(r => r.settings.plugins && r.settings.plugins.pagination) - .map(r => + .filter((r) => r.settings.plugins && r.settings.plugins.pagination) + .map((r) => Joi.assert( r.settings.plugins.pagination, optionsSchema, diff --git a/server/src/plugins/queryFilter.js b/server/src/plugins/queryFilter.js index 2f0f90ad6..cd5e90f40 100644 --- a/server/src/plugins/queryFilter.js +++ b/server/src/plugins/queryFilter.js @@ -86,7 +86,7 @@ const onPreHandler = function (request, h) { schemaDescription } // only add validations with .filter() - Object.keys(validateDescription.keys).forEach(k => { + Object.keys(validateDescription.keys).forEach((k) => { const keyDesc = validateDescription.keys[k] if (keyDesc.type === FILTER_TYPE) { queryFilterKeys.add(k) @@ -94,7 +94,7 @@ const onPreHandler = function (request, h) { }) } else { // add all keys if no validation - Object.keys(request.query).forEach(key => { + Object.keys(request.query).forEach((key) => { const val = request.query[key] const parsed = parseFilterString(val) request.query[key] = parsed diff --git a/server/src/plugins/staticFrontendRoutes.js b/server/src/plugins/staticFrontendRoutes.js index e9a792170..6ae8b3263 100644 --- a/server/src/plugins/staticFrontendRoutes.js +++ b/server/src/plugins/staticFrontendRoutes.js @@ -2,7 +2,7 @@ const path = require('path') const staticFrontendRoutes = { name: 'DHIS2 App Hub Frontend', - register: function(server, options) { + register: function (server, options) { //Temporary route to serve frontend static build until we've flattened the project structure server.route([ { diff --git a/server/src/query/Pager.js b/server/src/query/Pager.js index 0f9e4ec44..b4e163f00 100644 --- a/server/src/query/Pager.js +++ b/server/src/query/Pager.js @@ -1,6 +1,6 @@ const Joi = require('../utils/CustomJoi') -const createDefaultPagingResultSchema = itemsSchema => +const createDefaultPagingResultSchema = (itemsSchema) => Joi.object({ pager: Joi.object({ page: Joi.number(), @@ -20,12 +20,12 @@ const defaultPagingQuerySchema = Joi.object({ pageSize: Joi.number().default(25).min(1), }) -const withPagingQuerySchema = joiSchema => +const withPagingQuerySchema = (joiSchema) => Joi.alternatives().try( defaultPagingQuerySchema.concat(joiSchema), joiSchema ) -const withPagingResultSchema = joiSchema => +const withPagingResultSchema = (joiSchema) => Joi.alternatives().try( createDefaultPagingResultSchema(joiSchema), joiSchema diff --git a/server/src/routes/v1/apps/handlers/createAppVersion.js b/server/src/routes/v1/apps/handlers/createAppVersion.js index 03c0550e5..c13c625f4 100644 --- a/server/src/routes/v1/apps/handlers/createAppVersion.js +++ b/server/src/routes/v1/apps/handlers/createAppVersion.js @@ -70,7 +70,7 @@ module.exports = { const isManager = currentUserIsManager(request) const userApps = await getOrganisationAppsByUserId(currentUserId, db) const userCanEditApp = - isManager || userApps.map(app => app.app_id).indexOf(appId) !== -1 + isManager || userApps.map((app) => app.app_id).indexOf(appId) !== -1 if (!userCanEditApp) { throw Boom.unauthorized() @@ -85,9 +85,8 @@ module.exports = { throw Boom.badRequest(e) } - const validationResult = CreateAppVersionModel.def.validate( - appVersionJson - ) + const validationResult = + CreateAppVersionModel.def.validate(appVersionJson) const file = request.payload.file if (validationResult.error !== undefined) { @@ -112,7 +111,7 @@ module.exports = { //check if that version already exists on this app const existingAppVersions = dbAppRows.filter( - row => row.version === appVersionJson.version + (row) => row.version === appVersionJson.version ) if (existingAppVersions.length > 0) { throw Boom.badRequest( @@ -189,7 +188,11 @@ module.exports = { try { const organisationSlug = dbApp.organisation_slug - const organisation = await Organisation.findOneBySlug(organisationSlug, false, transaction) + const organisation = await Organisation.findOneBySlug( + organisationSlug, + false, + transaction + ) verifyBundle({ buffer: file._data, appId, @@ -214,7 +217,7 @@ module.exports = { //fetch the new version rows and filter out the one we've just created data for dbAppRows = await getAppsById(appId, languageCode, db) const [appWithVersion] = dbAppRows.filter( - app => app.version === appVersionJson.version + (app) => app.version === appVersionJson.version ) const serverUrl = `${request.server.info.protocol}://${request.info.host}/api` diff --git a/server/src/routes/v1/apps/handlers/deleteAppVersion.js b/server/src/routes/v1/apps/handlers/deleteAppVersion.js index 2a74f3319..c1991cad3 100644 --- a/server/src/routes/v1/apps/handlers/deleteAppVersion.js +++ b/server/src/routes/v1/apps/handlers/deleteAppVersion.js @@ -42,7 +42,7 @@ module.exports = { const isManager = currentUserIsManager(request) const userApps = await getOrganisationAppsByUserId(currentUser.id, db) const userCanDeleteVersion = - isManager || userApps.map(app => app.app_id).indexOf(appId) !== -1 + isManager || userApps.map((app) => app.app_id).indexOf(appId) !== -1 debug('isManager:', isManager) debug('userCanDeleteVersion:', userCanDeleteVersion) diff --git a/server/src/routes/v1/apps/handlers/deleteImage.js b/server/src/routes/v1/apps/handlers/deleteImage.js index e2e5203ee..42adcc87e 100644 --- a/server/src/routes/v1/apps/handlers/deleteImage.js +++ b/server/src/routes/v1/apps/handlers/deleteImage.js @@ -41,7 +41,7 @@ module.exports = { const userApps = await getOrganisationAppsByUserId(currentUser.id, db) const canDeleteImage = - isManager || userApps.map(app => app.app_id).indexOf(appId) !== -1 + isManager || userApps.map((app) => app.app_id).indexOf(appId) !== -1 debug('isManager:', isManager) debug('canDeleteImage:', canDeleteImage) diff --git a/server/src/routes/v1/apps/handlers/editApp.js b/server/src/routes/v1/apps/handlers/editApp.js index 6134fe066..abc98b083 100644 --- a/server/src/routes/v1/apps/handlers/editApp.js +++ b/server/src/routes/v1/apps/handlers/editApp.js @@ -46,7 +46,7 @@ module.exports = { db ) const userCanEditApp = - appsUserCanEdit.filter(app => app.app_id === request.params.appId) + appsUserCanEdit.filter((app) => app.app_id === request.params.appId) .length > 0 debug('appsUserCanEdit:', appsUserCanEdit) diff --git a/server/src/routes/v1/apps/handlers/editAppVersion.js b/server/src/routes/v1/apps/handlers/editAppVersion.js index d166a89bf..85d2446fe 100644 --- a/server/src/routes/v1/apps/handlers/editAppVersion.js +++ b/server/src/routes/v1/apps/handlers/editAppVersion.js @@ -43,7 +43,7 @@ module.exports = { const currentUser = await getCurrentUserFromRequest(request, db) const apps = await getOrganisationAppsByUserId(currentUser.id, db) - const hasDeveloperAccessToApp = apps.map(app => app.id).indexOf(appId) + const hasDeveloperAccessToApp = apps.map((app) => app.id).indexOf(appId) if (currentUserIsManager(request) || hasDeveloperAccessToApp) { //can edit appversion diff --git a/server/src/routes/v1/apps/handlers/editImage.js b/server/src/routes/v1/apps/handlers/editImage.js index e954bcf61..acd6d3001 100644 --- a/server/src/routes/v1/apps/handlers/editImage.js +++ b/server/src/routes/v1/apps/handlers/editImage.js @@ -41,7 +41,7 @@ module.exports = { db ) const userCanEditApp = appsUserCanEdit - .map(app => app.app_id) + .map((app) => app.app_id) .includes(request.params.appId) const isManager = currentUserIsManager(request) diff --git a/server/src/routes/v1/apps/handlers/getAppFile.js b/server/src/routes/v1/apps/handlers/getAppFile.js index 4549c3cd4..0be991f66 100644 --- a/server/src/routes/v1/apps/handlers/getAppFile.js +++ b/server/src/routes/v1/apps/handlers/getAppFile.js @@ -77,7 +77,9 @@ module.exports = { // catch instead of try-catch since we don't actually need to await the call appVersionService .incrementDownloadCount(item.version_id, knex) - .catch(e => request.logger.error('Failed to increment download', e)) + .catch((e) => + request.logger.error('Failed to increment download', e) + ) return h .response(file.Body) diff --git a/server/src/routes/v1/apps/handlers/uploadImageToApp.js b/server/src/routes/v1/apps/handlers/uploadImageToApp.js index b27e37911..17edbfc8e 100644 --- a/server/src/routes/v1/apps/handlers/uploadImageToApp.js +++ b/server/src/routes/v1/apps/handlers/uploadImageToApp.js @@ -47,7 +47,7 @@ module.exports = { const userApps = await getOrganisationAppsByUserId(currentUser.id, knex) const canUploadMedia = - isManager || userApps.map(app => app.app_id).indexOf(appId) !== -1 + isManager || userApps.map((app) => app.app_id).indexOf(appId) !== -1 debug('isManager:', isManager) debug('canUploadMedia:', canUploadMedia) diff --git a/server/src/routes/v2/apps.js b/server/src/routes/v2/apps.js index b9ab230d9..bc987148d 100644 --- a/server/src/routes/v2/apps.js +++ b/server/src/routes/v2/apps.js @@ -145,7 +145,7 @@ module.exports = [ } const { appType } = appJsonPayload - const app = await db.transaction(trx => + const app = await db.transaction((trx) => App.create( { userId: currentUserId, @@ -252,7 +252,7 @@ module.exports = [ appVersionService .incrementDownloadCount(appVersion.id, db) - .catch(e => + .catch((e) => request.logger.error('Failed to increment download', e) ) diff --git a/server/src/routes/v2/channels.js b/server/src/routes/v2/channels.js index efb71bc17..94fb91158 100644 --- a/server/src/routes/v2/channels.js +++ b/server/src/routes/v2/channels.js @@ -17,7 +17,7 @@ module.exports = [ request.logger.info('In handler %s', request.path) const channels = await h.context.db.select().from('channel') - return channels.map(channel => ({ + return channels.map((channel) => ({ id: channel.id, name: channel.name, uri: `${request.path}/${channel.id}`, @@ -111,13 +111,13 @@ module.exports = [ .where('channel_id', request.params.id) const apps = {} - channelApps.forEach(app => { + channelApps.forEach((app) => { if (!apps[app.id]) { apps[app.id] = [] } const version = apps[app.id].find( - x => x.version === app.version + (x) => x.version === app.version ) if (!version) { @@ -154,7 +154,7 @@ module.exports = [ debug(`uuid: ${uuid}`) - const deleteChannelWorkUnit = async trx => { + const deleteChannelWorkUnit = async (trx) => { await deleteChannel(uuid, trx) } diff --git a/server/src/routes/v2/me.js b/server/src/routes/v2/me.js index aa4baccd8..d93331d8b 100644 --- a/server/src/routes/v2/me.js +++ b/server/src/routes/v2/me.js @@ -25,7 +25,7 @@ module.exports = [ const organisations = ( await Organisation.find({ filters }, h.context.db) - ).map(org => org.id) + ).map((org) => org.id) return { organisations, diff --git a/server/src/routes/v2/organisations.js b/server/src/routes/v2/organisations.js index a980c044b..11d9d7984 100644 --- a/server/src/routes/v2/organisations.js +++ b/server/src/routes/v2/organisations.js @@ -22,7 +22,7 @@ module.exports = [ response: { schema: Joi.array() .items( - OrgModel.externalDefinition.fork('users', s => + OrgModel.externalDefinition.fork('users', (s) => s.forbidden() ) ) @@ -128,7 +128,7 @@ module.exports = [ const { id: userId } = await getCurrentUserFromRequest(request, db) //TODO: should everyone be able to create new organisations? - const createOrgAndAddUser = async trx => { + const createOrgAndAddUser = async (trx) => { const organisation = await Organisation.create( { userId, @@ -175,7 +175,7 @@ module.exports = [ const updateObj = request.payload - const updateOrganisation = async trx => { + const updateOrganisation = async (trx) => { const organisation = await Organisation.findOne( request.params.orgId, false, @@ -218,7 +218,7 @@ module.exports = [ const { db } = h.context const { id } = await getCurrentUserFromRequest(request, db) - const addUserToOrganisation = async trx => { + const addUserToOrganisation = async (trx) => { const org = await Organisation.findOne( request.params.orgId, true, @@ -226,7 +226,7 @@ module.exports = [ ) const isManager = currentUserIsManager(request) - const isMember = org.users.findIndex(u => u.id === id) > -1 + const isMember = org.users.findIndex((u) => u.id === id) > -1 const canAdd = org.owner === id || isMember || isManager if (!canAdd) { @@ -290,7 +290,7 @@ module.exports = [ const userIdToRemove = request.payload.user - const removeUserFromOrganisation = async trx => { + const removeUserFromOrganisation = async (trx) => { const org = await Organisation.findOne( request.params.orgId, true, @@ -298,7 +298,7 @@ module.exports = [ ) const isManager = currentUserIsManager(request) - const isMember = org.users.findIndex(u => u.id === id) > -1 + const isMember = org.users.findIndex((u) => u.id === id) > -1 const canRemove = org.owner === id || isMember || isManager if (org.owner === userIdToRemove) { diff --git a/server/src/security/apiKeyScheme.js b/server/src/security/apiKeyScheme.js index 9b86b8340..758347661 100644 --- a/server/src/security/apiKeyScheme.js +++ b/server/src/security/apiKeyScheme.js @@ -9,14 +9,11 @@ const optionsSchema = Joi.object({ keySchema: Joi.object() .schema() .default( - Joi.string() - .required() - .length(36) - .message('Invalid API key format') + Joi.string().required().length(36).message('Invalid API key format') ), }) -const scheme = function(server, schemeOptions) { +const scheme = function (server, schemeOptions) { const options = Joi.attempt(schemeOptions, optionsSchema) debug('API-key scheme setup') return { @@ -48,7 +45,7 @@ const scheme = function(server, schemeOptions) { } const plugin = { - register: function(server, pluginOptions) { + register: function (server, pluginOptions) { server.auth.scheme(schemeName, scheme) }, } diff --git a/server/src/security/createApiKeyValidationFunc.js b/server/src/security/createApiKeyValidationFunc.js index e87d2d65f..f286113ed 100644 --- a/server/src/security/createApiKeyValidationFunc.js +++ b/server/src/security/createApiKeyValidationFunc.js @@ -11,20 +11,17 @@ const getUserByApiKey = async (apiKey, trx) => { } // TODO: this should probably be in some User-service - const userInfo = await trx('users') - .select() - .where({ id: userId }) - .first() + const userInfo = await trx('users').select().where({ id: userId }).first() return userInfo } -const createApiKeyValidationFunc = db => { - return async apiKey => { +const createApiKeyValidationFunc = (db) => { + return async (apiKey) => { debug('Validate api-key') const credentials = {} try { - const user = await db.transaction(trx => + const user = await db.transaction((trx) => getUserByApiKey(apiKey, trx) ) diff --git a/server/src/security/createUserValidationFunc.js b/server/src/security/createUserValidationFunc.js index f2b54ec8e..f356da7d4 100644 --- a/server/src/security/createUserValidationFunc.js +++ b/server/src/security/createUserValidationFunc.js @@ -5,7 +5,7 @@ const { createUser } = require('../data') const { ROLES } = require('./index') const customClaimsNamespace = 'https://apps.dhis2.org' -const getNamespacedClaimKey = key => `${customClaimsNamespace}/${key}` +const getNamespacedClaimKey = (key) => `${customClaimsNamespace}/${key}` const createUserValidationFunc = (db, audience, auth0ManagementClient) => { return async (decoded, request, h) => { @@ -55,7 +55,7 @@ const createUserValidationFunc = (db, audience, auth0ManagementClient) => { throw Boom.conflict('Email not verified') } //create the user if it doesn't exist - const createUserTransaction = async trx => { + const createUserTransaction = async (trx) => { const dbUser = await createUser( { email: userInfo.email, diff --git a/server/src/security/index.js b/server/src/security/index.js index d8ad60772..e05e7f616 100644 --- a/server/src/security/index.js +++ b/server/src/security/index.js @@ -8,7 +8,7 @@ const ROLES = { * This returns true if the request is authenticated (e.g. contains a valid token) * @param {*} request */ -const isAuthenticated = request => { +const isAuthenticated = (request) => { try { debug('isAuthenticated:', request.auth) return request.auth.isAuthenticated === true @@ -36,7 +36,7 @@ const hasRole = (request, role) => { * Checks if the user on the request has permissions to delete an app * @param {*} request */ -const canDeleteApp = request => +const canDeleteApp = (request) => isAuthenticated(request) && hasRole(request, ROLES.MANAGER) /** @@ -44,32 +44,32 @@ const canDeleteApp = request => * @param {*} request * @param {*} hapi */ -const canChangeAppStatus = request => +const canChangeAppStatus = (request) => isAuthenticated(request) && hasRole(request, ROLES.MANAGER) /** * Checks if the user on the request has permissions to create an app version * @param {*} request */ -const canCreateAppVersion = request => isAuthenticated(request) +const canCreateAppVersion = (request) => isAuthenticated(request) /** * Checks if the user on the request has permissions to create an app * @param {*} request */ -const canCreateApp = request => isAuthenticated(request) +const canCreateApp = (request) => isAuthenticated(request) /** * Checks if the user on the request has permissions to see all apps * @param {*} request */ -const canSeeAllApps = request => +const canSeeAllApps = (request) => isAuthenticated(request) && hasRole(request, ROLES.MANAGER) -const currentUserIsManager = request => +const currentUserIsManager = (request) => isAuthenticated(request) && hasRole(request, ROLES.MANAGER) -const getCurrentUserFromRequest = request => { +const getCurrentUserFromRequest = (request) => { return new Promise((resolve, reject) => { try { const id = request.auth.credentials.userId diff --git a/server/src/security/verifyBundle.js b/server/src/security/verifyBundle.js index af42971d8..777e03271 100644 --- a/server/src/security/verifyBundle.js +++ b/server/src/security/verifyBundle.js @@ -1,6 +1,6 @@ const AdmZip = require('adm-zip') -const isValidJSON = json => { +const isValidJSON = (json) => { try { JSON.parse(json) return true @@ -45,7 +45,7 @@ const checkD2Config = ({ d2Config, appId, appName, version, canBeCoreApp }) => { module.exports = ({ buffer, appId, appName, version, organisationName }) => { const zip = new AdmZip(buffer) - const entries = zip.getEntries().map(e => e.entryName) + const entries = zip.getEntries().map((e) => e.entryName) const manifestPath = 'manifest.webapp' const d2ConfigPath = 'd2.config.json' const canBeCoreApp = organisationName === 'DHIS2' diff --git a/server/src/server/Auth0ManagementClient.js b/server/src/server/Auth0ManagementClient.js index 1409d3804..7f8774f2e 100644 --- a/server/src/server/Auth0ManagementClient.js +++ b/server/src/server/Auth0ManagementClient.js @@ -1,8 +1,7 @@ -var ManagementClient = require('auth0').ManagementClient; +var ManagementClient = require('auth0').ManagementClient var auth0 = new ManagementClient({ - domain: '{YOUR_ACCOUNT}.auth0.com', - clientId: '{YOUR_NON_INTERACTIVE_CLIENT_ID}', - clientSecret: '{YOUR_NON_INTERACTIVE_CLIENT_SECRET}', - scope: 'read:users update:users' -}); - + domain: '{YOUR_ACCOUNT}.auth0.com', + clientId: '{YOUR_NON_INTERACTIVE_CLIENT_ID}', + clientSecret: '{YOUR_NON_INTERACTIVE_CLIENT_SECRET}', + scope: 'read:users update:users', +}) diff --git a/server/src/server/create-api-user.js b/server/src/server/create-api-user.js index b75c8bf7a..1050f8ad9 100644 --- a/server/src/server/create-api-user.js +++ b/server/src/server/create-api-user.js @@ -1,6 +1,6 @@ const { v4: uuid } = require('uuid') -exports.createApiUser = async knex => { +exports.createApiUser = async (knex) => { if (!process.env.AUTH0_AUDIENCE) { return } diff --git a/server/src/server/migrate-database.js b/server/src/server/migrate-database.js index 25ddb9872..f67f7097b 100644 --- a/server/src/server/migrate-database.js +++ b/server/src/server/migrate-database.js @@ -1,5 +1,5 @@ const debug = require('debug')('apphub:server:boot:database') -exports.migrate = async knex => { +exports.migrate = async (knex) => { if (process.env.SKIP_MIGRATION === 'true') { debug('SKIP_MIGRATION=true, skipping database migration') return false diff --git a/server/src/services/apiKey.js b/server/src/services/apiKey.js index d2d8a30cc..90f0463eb 100644 --- a/server/src/services/apiKey.js +++ b/server/src/services/apiKey.js @@ -13,11 +13,8 @@ const generateApiKey = () => { return { apiKey, hashedKey } } -const hashKey = apiKey => - crypto - .createHash('sha256') - .update(apiKey) - .digest('hex') +const hashKey = (apiKey) => + crypto.createHash('sha256').update(apiKey).digest('hex') const createApiKeyForUser = async (userId, knex) => { const { apiKey, hashedKey } = generateApiKey() diff --git a/server/src/services/app.js b/server/src/services/app.js index 2805c0ea1..8ce0714f5 100644 --- a/server/src/services/app.js +++ b/server/src/services/app.js @@ -115,5 +115,5 @@ exports.createMediaForApp = ( exports.canEditApp = async (userId, appId, knex) => { const appsUserCanEdit = await getOrganisationAppsByUserId(userId, knex) - return appsUserCanEdit.find(app => app.app_id === appId) != null + return appsUserCanEdit.find((app) => app.app_id === appId) != null } diff --git a/server/src/services/organisation.js b/server/src/services/organisation.js index 1a22d7ebe..55397559b 100644 --- a/server/src/services/organisation.js +++ b/server/src/services/organisation.js @@ -4,7 +4,7 @@ const Organisation = require('../models/v2/Organisation') const { NotFoundError } = require('../utils/errors') const { slugify } = require('../utils/slugify') -const getOrganisationQuery = db => +const getOrganisationQuery = (db) => db('organisation').select( 'organisation.id', 'organisation.name', diff --git a/server/src/utils/AWSFileHandler.js b/server/src/utils/AWSFileHandler.js index fc285155f..47780bfd6 100644 --- a/server/src/utils/AWSFileHandler.js +++ b/server/src/utils/AWSFileHandler.js @@ -84,7 +84,7 @@ module.exports = class AWSFileHandler { }, } - objectsInPath.Contents.forEach(obj => { + objectsInPath.Contents.forEach((obj) => { debug('Will try to delete: ', obj.Key) deleteParams.Delete.Objects.push({ Key: obj.Key }) }) diff --git a/server/src/utils/CustomJoi.js b/server/src/utils/CustomJoi.js index 36048cdff..1937a84cb 100644 --- a/server/src/utils/CustomJoi.js +++ b/server/src/utils/CustomJoi.js @@ -67,7 +67,7 @@ const Filter = { result.value = valueResult.value if (valueResult.errors) { - const errs = valueResult.errors.map(e => + const errs = valueResult.errors.map((e) => helpers.error('filter.value', { err: e }) ) errors.push(...errs) @@ -79,7 +79,7 @@ const Filter = { .$_validate(filter.operator, helpers.state, helpers.prefs) result.operator = opResult.value if (opResult.errors) { - const errs = opResult.errors.map(e => + const errs = opResult.errors.map((e) => helpers.error('filter.operator', { err: e }) ) errors.push(...errs) @@ -118,8 +118,8 @@ const StringArray = { base: Joi.array(), type: 'stringArray', coerce: (value, state, options) => ({ - value: value.split ? value.split(',') : value - }) + value: value.split ? value.split(',') : value, + }), } module.exports = Joi.extend(Filter).extend(StringArray) diff --git a/server/src/utils/Filter.js b/server/src/utils/Filter.js index b47361407..5fd9e0fcc 100644 --- a/server/src/utils/Filter.js +++ b/server/src/utils/Filter.js @@ -50,7 +50,7 @@ class Filters { static createFromQueryFilters(filters, { validate, rename } = {}, options) { let result = filters let renameMap = null - Object.keys(filters).map(key => { + Object.keys(filters).map((key) => { try { const filter = parseFilterString(filters[key]) result[key] = filter @@ -122,7 +122,7 @@ class Filters { ? `${settings.tableName}.${colName}` : colName) const { value, operator } = filter - query.where(builder => { + query.where((builder) => { builder.where(nameToUse, toSQLOperator(operator, value), value) if (settings.includeEmpty) { builder.orWhereRaw(`nullif( ??, '') is null`, nameToUse) @@ -156,7 +156,7 @@ class Filters { ) } - query.where(builder => { + query.where((builder) => { builder.whereRaw( `string_to_array( regexp_replace(??, '[^0-9.]+', '', 'g'), '.')::int[] ${toSQLOperator( filter.operator diff --git a/server/src/utils/LocalFileSystemHandler.js b/server/src/utils/LocalFileSystemHandler.js index 2a4a650cd..82ddd9a3c 100644 --- a/server/src/utils/LocalFileSystemHandler.js +++ b/server/src/utils/LocalFileSystemHandler.js @@ -38,7 +38,7 @@ module.exports = class LocalFileSystemHandler { fs.writeFile( path.join(this._uploadDirectory, directoryPath, filename), buffer, - err => { + (err) => { if (err) { reject(err) } else { @@ -93,7 +93,7 @@ module.exports = class LocalFileSystemHandler { fs.unlink( path.join(this._uploadDirectory, directoryPath, filename), - err => { + (err) => { if (err) { reject(err) } else { @@ -113,7 +113,7 @@ module.exports = class LocalFileSystemHandler { return } - rimraf(path.join(this._uploadDirectory, directoryPath), err => { + rimraf(path.join(this._uploadDirectory, directoryPath), (err) => { if (err) { reject(err) } else { diff --git a/server/src/utils/filterUtils.js b/server/src/utils/filterUtils.js index 3b4128e60..07638f8d6 100644 --- a/server/src/utils/filterUtils.js +++ b/server/src/utils/filterUtils.js @@ -37,7 +37,7 @@ const toSQLOperator = (operatorStr, value) => { return operator } -const parseFilterString = filterStr => { +const parseFilterString = (filterStr) => { let operator const seperatorIdx = filterStr.indexOf(SEPERATOR_CHAR) if (seperatorIdx < 0) { diff --git a/server/src/utils/index.js b/server/src/utils/index.js index c5470e505..825eb9182 100644 --- a/server/src/utils/index.js +++ b/server/src/utils/index.js @@ -21,7 +21,7 @@ const getFile = (path, filename) => createBackingStorageInstance().getFile(path, filename) const deleteFile = (path, filename) => createBackingStorageInstance().deleteFile(path, filename) -const deleteDir = path => createBackingStorageInstance().deleteDir(path) +const deleteDir = (path) => createBackingStorageInstance().deleteDir(path) module.exports = { flatten, diff --git a/server/src/utils/slugify.js b/server/src/utils/slugify.js index 8911c7518..10e648ae7 100644 --- a/server/src/utils/slugify.js +++ b/server/src/utils/slugify.js @@ -9,7 +9,7 @@ const slugifyOptions = { strict: true, } -exports.slugify = string => { +exports.slugify = (string) => { const slug = slugify(string, slugifyOptions) return slug.length > 1 ? slug diff --git a/server/src/utils/validateMime.js b/server/src/utils/validateMime.js index ded79de98..d6ebee462 100644 --- a/server/src/utils/validateMime.js +++ b/server/src/utils/validateMime.js @@ -24,11 +24,13 @@ const validateExtensionForMimeType = (mimos, filePath, mimeTypes) => { mimeTypes = [mimeTypes] } const ext = Path.extname(filePath).substring(1) - const mimeExtensions = mimeTypes.flatMap(t => mimos.type(t).extensions) + const mimeExtensions = mimeTypes.flatMap((t) => mimos.type(t).extensions) if (mimeExtensions.includes(ext)) { return true } - throw Boom.badRequest(`File extension must be one of [${mimeExtensions.join(', ')}]`) + throw Boom.badRequest( + `File extension must be one of [${mimeExtensions.join(', ')}]` + ) } module.exports = { diff --git a/server/test/data/index.js b/server/test/data/index.js index 0a5fed843..9d7b908e5 100644 --- a/server/test/data/index.js +++ b/server/test/data/index.js @@ -237,7 +237,7 @@ describe('@data::updateApp', () => { expect(allAppVersionsWithUuid.length).to.be.min(1) - allAppVersionsWithUuid.forEach(app => { + allAppVersionsWithUuid.forEach((app) => { expect(app.name).to.be.equal(newData.name) expect(app.source_url).to.be.equal(newData.sourceUrl) expect(app.description).to.be.equal(newData.description) @@ -257,7 +257,7 @@ describe('@data::updateAppVersion', () => { //First check that we fetch the correct object to change const [app] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(app.version_id).to.equal(appVersionIdToUpdate) expect(app.version).to.equal('0.1') @@ -280,7 +280,7 @@ describe('@data::updateAppVersion', () => { await transaction.commit() const [updatedApp] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(updatedApp.version_id).to.equal(appVersionIdToUpdate) expect(updatedApp.min_dhis2_version).to.equal('123') @@ -313,7 +313,7 @@ describe('@data::updateAppVersion', () => { //First check that we fetch the correct object to change let [app] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(app.version_id).to.equal(appVersionIdToUpdate) expect(app.channel_name).to.equal('stable') @@ -329,7 +329,7 @@ describe('@data::updateAppVersion', () => { await transaction.commit() ;[app] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(app.channel_name).to.equal('development') @@ -347,7 +347,7 @@ describe('@data::updateAppVersion', () => { //Check that the switch back to stable worked ;[app] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(app.channel_name).to.equal('stable') }) @@ -359,7 +359,7 @@ describe('@data::updateAppVersion', () => { //First check that we fetch the correct object to change const [app] = (await getAppsById(mockAppId, 'en', db)).filter( - app => app.version_id === appVersionIdToUpdate + (app) => app.version_id === appVersionIdToUpdate ) expect(app.version_id).to.equal(appVersionIdToUpdate) expect(app.channel_name).to.equal('stable') diff --git a/server/test/plugins/errorMapper.js b/server/test/plugins/errorMapper.js index 3d81987e0..c209a1921 100644 --- a/server/test/plugins/errorMapper.js +++ b/server/test/plugins/errorMapper.js @@ -19,7 +19,7 @@ const Hapi = require('@hapi/hapi') describe('ErrorMapperPlugin', () => { let server - const registerRoutes = server => { + const registerRoutes = (server) => { server.route({ method: 'GET', path: '/null', @@ -55,7 +55,7 @@ describe('ErrorMapperPlugin', () => { throw new UniqueViolationError({ nativeError: new Error('Item already exists!'), table: 'organisation', - columns: ['name'] + columns: ['name'], }) }, }) @@ -230,7 +230,9 @@ describe('ErrorMapperPlugin', () => { const res = await server.inject(request) expect(res.statusCode).to.be.equal(409) - expect(res.result.message).to.be.equal('organisation with that name already exists.') + expect(res.result.message).to.be.equal( + 'organisation with that name already exists.' + ) }) }) }) diff --git a/server/test/plugins/pagination.js b/server/test/plugins/pagination.js index f1b78b033..868353f78 100644 --- a/server/test/plugins/pagination.js +++ b/server/test/plugins/pagination.js @@ -27,7 +27,7 @@ describe('@plugins::PaginationPlugin', () => { }, }, - handler: request => { + handler: (request) => { const pager = request.plugins.pagination return pager }, @@ -273,12 +273,8 @@ describe('@plugins::PaginationPlugin', () => { options: { querySchema: Joi.object({ paging: Joi.boolean().default(true), - page: Joi.number() - .default(1) - .min(1), - pageSize: Joi.number() - .default(15) - .min(1), + page: Joi.number().default(1).min(1), + pageSize: Joi.number().default(15).min(1), }).rename('limit', 'pageSize'), resultSchema: Joi.object({ pager: Joi.object({ @@ -303,7 +299,7 @@ describe('@plugins::PaginationPlugin', () => { }, }, - handler: request => { + handler: (request) => { const pager = request.plugins.pagination const res = [...Array(30).keys()] const formatted = pager.formatResult(res, res.length) @@ -321,18 +317,14 @@ describe('@plugins::PaginationPlugin', () => { enabled: true, querySchema: Joi.object({ paging: Joi.boolean().default(true), - page: Joi.number() - .default(1) - .min(1), - pageSize: Joi.number() - .default(15) - .min(1), + page: Joi.number().default(1).min(1), + pageSize: Joi.number().default(15).min(1), }).rename('size', 'pageSize'), }, }, }, - handler: request => { + handler: (request) => { const pager = request.plugins.pagination const res = [...Array(30).keys()] const formatted = pager.formatResult(res, res.length) diff --git a/server/test/plugins/queryFilter.js b/server/test/plugins/queryFilter.js index 4f2311559..048124155 100644 --- a/server/test/plugins/queryFilter.js +++ b/server/test/plugins/queryFilter.js @@ -22,7 +22,7 @@ describe('QueryFilterPlugin', () => { }, }, }, - handler: request => { + handler: (request) => { const filters = request.plugins.queryFilter return filters }, @@ -256,8 +256,7 @@ describe('QueryFilterPlugin', () => { it('should support rename of the key', async () => { const res = await server.inject({ method: 'GET', - url: - '/validationFilter?name=DHIS2&owner=eq:cedb4418-2417-4e72-bfcc-35ccd0dc3e41', + url: '/validationFilter?name=DHIS2&owner=eq:cedb4418-2417-4e72-bfcc-35ccd0dc3e41', }) expect(res.statusCode).to.be.equal(200) diff --git a/server/test/query/executeQuery.js b/server/test/query/executeQuery.js index 93cbfea78..52e35de23 100644 --- a/server/test/query/executeQuery.js +++ b/server/test/query/executeQuery.js @@ -27,7 +27,7 @@ describe('executeQuery', () => { await db.rollback() }) - const appMocksWithTotal = appMocks.map(a => ({ + const appMocksWithTotal = appMocks.map((a) => ({ ...a, total_count: appMocks.length, })) @@ -42,12 +42,12 @@ describe('executeQuery', () => { 'organisation.created_at' ) - const getQueryMock = new Promise(resolve => { + const getQueryMock = new Promise((resolve) => { resolve(appMocksWithTotal) }) getQueryMock._method = 'select' - const insertQueryMock = new Promise(resolve => resolve(appMocksWithTotal)) + const insertQueryMock = new Promise((resolve) => resolve(appMocksWithTotal)) insertQueryMock._method = 'insert' const appDefinition = Joi.object({ @@ -64,9 +64,9 @@ describe('executeQuery', () => { const appModelMock = { definition: appDefinition, - parseDatabaseJson: apps => + parseDatabaseJson: (apps) => Joi.attempt(apps, Joi.array().items(appDefinition)), - formatDatabaseJson: apps => + formatDatabaseJson: (apps) => Joi.attempt(apps, Joi.array().items(appDefinition)), } @@ -81,15 +81,15 @@ describe('executeQuery', () => { expect(result).to.be.an.object() expect(result.result).to.be.an.array().length(organisationMocks.length) - result.result.forEach(org => { + result.result.forEach((org) => { expect( - organisationMocks.find(o => o.id === org.id) + organisationMocks.find((o) => o.id === org.id) ).to.not.be.undefined() }) }) it('should execute the query and format it if options.formatter is present', async () => { - const formatter = apps => apps.map(a => a.id) + const formatter = (apps) => apps.map((a) => a.id) const formatterSpy = sinon.spy(formatter) const result = await executeQuery(getQueryMock, undefined, { formatter: formatterSpy, @@ -98,7 +98,7 @@ describe('executeQuery', () => { expect(result).to.be.an.object() expect(result.result).to.not.shallow.equal(appMocksWithTotal) expect(formatterSpy.calledOnce).to.be.true() - result.result.forEach(a => { + result.result.forEach((a) => { expect(a).to.not.be.an.object() expect(a).to.be.a.string() }) @@ -130,7 +130,7 @@ describe('executeQuery', () => { it('should prioritise formatter if both model and options.formatter is present', async () => { sinon.spy(appModelMock, 'parseDatabaseJson') - const formatter = apps => apps.map(a => a.id) + const formatter = (apps) => apps.map((a) => a.id) const formatterSpy = sinon.spy(formatter) const result = await executeQuery( getQueryMock, diff --git a/server/test/routes/createApp.js b/server/test/routes/createApp.js index 9764a70a0..a922c9f16 100644 --- a/server/test/routes/createApp.js +++ b/server/test/routes/createApp.js @@ -4,13 +4,8 @@ const Lab = require('@hapi/lab') const FormData = require('form-data') const streamToPromise = require('stream-to-promise') -const { - it, - describe, - afterEach, - beforeEach, - before, -} = (exports.lab = Lab.script()) +const { it, describe, afterEach, beforeEach, before } = (exports.lab = + Lab.script()) const { expect } = require('@hapi/code') const knexConfig = require('../../knexfile') @@ -40,7 +35,7 @@ describe('v1/apps', () => { await db.rollback() }) - const createFormForApp = app => { + const createFormForApp = (app) => { const form = new FormData() form.append('app', JSON.stringify(app)) form.append( diff --git a/server/test/routes/deleteApp.js b/server/test/routes/deleteApp.js index b7f328512..098737f2b 100644 --- a/server/test/routes/deleteApp.js +++ b/server/test/routes/deleteApp.js @@ -25,7 +25,7 @@ describe('test delete app', () => { await server.stop() }) - const createFormForApp = app => { + const createFormForApp = (app) => { const form = new FormData() form.append('app', JSON.stringify(app)) form.append( diff --git a/server/test/routes/index.js b/server/test/routes/index.js index 81017374c..39b56974b 100644 --- a/server/test/routes/index.js +++ b/server/test/routes/index.js @@ -36,10 +36,10 @@ describe('Get all published apps [v1]', () => { const apps = JSON.parse(response.payload) expect(apps).to.not.be.empty() - const approvedApps = apps.filter(app => app.status === 'APPROVED') + const approvedApps = apps.filter((app) => app.status === 'APPROVED') expect(approvedApps.length).to.be.equal(apps.length) - const whoApp = apps.filter(app => app.name === 'A nice app by WHO') + const whoApp = apps.filter((app) => app.name === 'A nice app by WHO') expect(whoApp).to.be.array() @@ -74,9 +74,9 @@ describe('Get all published apps [v1]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) const filteredVersions = versions.filter( - version => version.channel === 'stable' + (version) => version.channel === 'stable' ) expect(filteredVersions.length).to.equal(versions.length) }) @@ -94,10 +94,10 @@ describe('Get all published apps [v1]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) const filteredVersions = versions.filter( - version => version.channel === 'stable' + (version) => version.channel === 'stable' ) expect(filteredVersions.length).to.equal(versions.length) @@ -119,7 +119,7 @@ describe('Get all published apps [v1]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) expect(versions.length).to.equal(1) //the 'a nice app by who' version 1.0 with support for 2.27 @@ -176,10 +176,10 @@ describe('Get all published apps [v2]', () => { const { result: apps } = JSON.parse(response.payload) expect(apps).to.not.be.empty() - const approvedApps = apps.filter(app => app.status === 'APPROVED') + const approvedApps = apps.filter((app) => app.status === 'APPROVED') expect(approvedApps.length).to.be.equal(apps.length) - const whoApp = apps.filter(app => app.name === 'A nice app by WHO') + const whoApp = apps.filter((app) => app.name === 'A nice app by WHO') expect(whoApp).to.be.array() @@ -188,7 +188,7 @@ describe('Get all published apps [v2]', () => { 'World Health Organization' ) const version1App = whoApp[0].versions.find( - ver => ver.id === appVersionMocks[1][0].id + (ver) => ver.id === appVersionMocks[1][0].id ) expect(version1App.version).to.be.equal('1.0') expect(version1App.demoUrl).to.be.equal( @@ -216,9 +216,9 @@ describe('Get all published apps [v2]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) const filteredVersions = versions.filter( - version => version.channel === 'stable' + (version) => version.channel === 'stable' ) expect(filteredVersions.length).to.equal(versions.length) }) @@ -236,10 +236,10 @@ describe('Get all published apps [v2]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) const filteredVersions = versions.filter( - version => version.channel === 'stable' + (version) => version.channel === 'stable' ) expect(filteredVersions.length).to.equal(versions.length) @@ -251,8 +251,7 @@ describe('Get all published apps [v2]', () => { it('should only return apps supporting version 2.27', async () => { const injectOptions = { method: 'GET', - url: - '/api/v2/apps?channels=stable,development,canary&dhis_version=2.27', + url: '/api/v2/apps?channels=stable,development,canary&dhis_version=2.27', } const response = await server.inject(injectOptions) @@ -262,7 +261,7 @@ describe('Get all published apps [v2]', () => { expect(apps).to.not.be.empty() expect(apps).to.be.array() - const versions = flatten(apps.map(app => app.versions)) + const versions = flatten(apps.map((app) => app.versions)) expect(versions.length).to.equal(1) //the 'a nice app by who' version 1.0 with support for 2.27 diff --git a/server/test/routes/v2/apiKey.js b/server/test/routes/v2/apiKey.js index 6b6e0cd07..8b2f75692 100644 --- a/server/test/routes/v2/apiKey.js +++ b/server/test/routes/v2/apiKey.js @@ -1,12 +1,7 @@ const { expect } = require('@hapi/code') const Lab = require('@hapi/lab') -const { - it, - describe, - afterEach, - beforeEach, - before, -} = (exports.lab = Lab.script()) +const { it, describe, afterEach, beforeEach, before } = (exports.lab = + Lab.script()) const knexConfig = require('../../../knexfile') const dbInstance = require('knex')(knexConfig) diff --git a/server/test/routes/v2/apps.js b/server/test/routes/v2/apps.js index 27ecd0328..d59a4487b 100644 --- a/server/test/routes/v2/apps.js +++ b/server/test/routes/v2/apps.js @@ -41,7 +41,7 @@ describe('v2/apps', () => { } const dhis2App = appsMocks[0] - const createFormForApp = app => { + const createFormForApp = (app) => { const form = new FormData() form.append('app', JSON.stringify(app)) return form @@ -79,7 +79,7 @@ describe('v2/apps', () => { const apps = res.result.result expect(apps).to.be.an.array() expect(apps.length).to.be.min(4) // 4 seeds - expect(apps.find(a => a.id === rejectedApp)).to.be.undefined() + expect(apps.find((a) => a.id === rejectedApp)).to.be.undefined() }) it('should get apps-only when core=true ', async () => { @@ -95,7 +95,7 @@ describe('v2/apps', () => { expect(apps).to.be.an.array() const notCore = apps.filter( - a => a.developer.organisation !== 'DHIS2' + (a) => a.developer.organisation !== 'DHIS2' ) expect(notCore).to.have.length(0) @@ -152,7 +152,7 @@ describe('v2/apps', () => { before(async () => { // create a new version to ensure file-exists - const promises = appsToCreate.map(async app => { + const promises = appsToCreate.map(async (app) => { const form = await createAppVersionForm(app, { version: '1.2.3', }) @@ -170,7 +170,7 @@ describe('v2/apps', () => { }) after(async () => { - const promises = appsToCreate.map(app => { + const promises = appsToCreate.map((app) => { console.log( 'deleting app version', app.createdVersionId, @@ -183,7 +183,7 @@ describe('v2/apps', () => { }) }) - const resolved = (await Promise.all(promises)).map(res => + const resolved = (await Promise.all(promises)).map((res) => expect(res.statusCode).to.equal(200) ) }) @@ -198,7 +198,7 @@ describe('v2/apps', () => { expect(result).to.be.an.array() const createdVer = result.find( - v => v.id === whoApp.createdVersionId + (v) => v.id === whoApp.createdVersionId ) expect(createdVer).to.be.an.object() @@ -220,7 +220,7 @@ describe('v2/apps', () => { const manifest = zip .getEntries() - .find(e => e.entryName === 'manifest.webapp') + .find((e) => e.entryName === 'manifest.webapp') expect(manifest).to.not.be.undefined() }) @@ -235,7 +235,7 @@ describe('v2/apps', () => { expect(result).to.be.an.array() const createdVer = result.find( - v => v.id === pendingApp.createdVersionId + (v) => v.id === pendingApp.createdVersionId ) expect(createdVer).to.be.an.object() @@ -270,7 +270,7 @@ describe('v2/apps', () => { expect(result).to.be.an.array() const createdVer = result.find( - v => v.id === pendingApp.createdVersionId + (v) => v.id === pendingApp.createdVersionId ) expect(createdVer).to.be.an.object() @@ -306,7 +306,7 @@ describe('v2/apps', () => { expect(result).to.be.an.array() const createdVer = result.find( - v => v.id === pendingApp.createdVersionId + (v) => v.id === pendingApp.createdVersionId ) expect(createdVer).to.be.an.object() diff --git a/server/test/routes/v2/channels.js b/server/test/routes/v2/channels.js index 7111c1910..ab5a965a4 100644 --- a/server/test/routes/v2/channels.js +++ b/server/test/routes/v2/channels.js @@ -46,9 +46,7 @@ describe('api/v2/channels', () => { const json = JSON.parse(response.payload) expect(json).to.be.an.array() - expect(json.length) - .to.be.a.number() - .and.greaterThan(0) + expect(json.length).to.be.a.number().and.greaterThan(0) }) it('should return unauthorized trying to update a channel with no auth', async () => { @@ -106,9 +104,7 @@ describe('api/v2/channels without configured auth', () => { const json = JSON.parse(response.payload) expect(json).to.be.an.array() - expect(json.length) - .to.be.a.number() - .and.greaterThan(0) + expect(json.length).to.be.a.number().and.greaterThan(0) }) it('should create a channel followed by updating the name of it', async () => { diff --git a/server/test/routes/v2/organisations.js b/server/test/routes/v2/organisations.js index b87b36c13..5baff3833 100644 --- a/server/test/routes/v2/organisations.js +++ b/server/test/routes/v2/organisations.js @@ -1,12 +1,7 @@ const { expect } = require('@hapi/code') const Lab = require('@hapi/lab') -const { - it, - describe, - afterEach, - beforeEach, - before, -} = (exports.lab = Lab.script()) +const { it, describe, afterEach, beforeEach, before } = (exports.lab = + Lab.script()) const knexConfig = require('../../../knexfile') const dbInstance = require('knex')(knexConfig) diff --git a/server/test/security/apiKeyScheme.js b/server/test/security/apiKeyScheme.js index 53486e95e..69a0cee05 100644 --- a/server/test/security/apiKeyScheme.js +++ b/server/test/security/apiKeyScheme.js @@ -1,12 +1,7 @@ const { expect } = require('@hapi/code') const Lab = require('@hapi/lab') -const { - it, - describe, - afterEach, - beforeEach, - before, -} = (exports.lab = Lab.script()) +const { it, describe, afterEach, beforeEach, before } = (exports.lab = + Lab.script()) const Hapi = require('@hapi/hapi') const knexConfig = require('../../knexfile') const dbInstance = require('knex')(knexConfig) diff --git a/server/test/services/organisation.js b/server/test/services/organisation.js index 80412750b..d1a84f9d6 100644 --- a/server/test/services/organisation.js +++ b/server/test/services/organisation.js @@ -32,7 +32,7 @@ describe('@services::Organisation', () => { } const filters = Filters.createFromQueryFilters(filter) const orgs = await Organisation.find({ filters }, db) - const DHIS2App = orgs.find(o => o.name === 'DHIS2') + const DHIS2App = orgs.find((o) => o.name === 'DHIS2') expect(orgs.length).to.be.equal(1) expect(DHIS2App).to.not.be.null() }) @@ -40,8 +40,8 @@ describe('@services::Organisation', () => { it('should find all organisations without a specified filter', async () => { const orgs = ['DHIS2', 'World Health Organization'] const dbOrgs = await Organisation.find({}, db) - orgs.forEach(org => { - const dbOrg = dbOrgs.find(o => o.name === org.name) + orgs.forEach((org) => { + const dbOrg = dbOrgs.find((o) => o.name === org.name) expect(dbOrg).to.not.be.null() }) }) @@ -52,7 +52,7 @@ describe('@services::Organisation', () => { user: user.id, }) const orgs = await Organisation.find({ filters }, db) - const DHIS2App = orgs.find(o => o.name === 'DHIS2') + const DHIS2App = orgs.find((o) => o.name === 'DHIS2') expect(DHIS2App).to.not.be.null() }) @@ -63,10 +63,10 @@ describe('@services::Organisation', () => { user: user.id, }) const orgs = await Organisation.find({ filters }, db) - const DHIS2App = orgs.find(o => o.name === 'DHIS2') + const DHIS2App = orgs.find((o) => o.name === 'DHIS2') expect(DHIS2App).to.not.be.null() expect( - orgs.find(o => OrganisationMocks[1].id === o.id) + orgs.find((o) => OrganisationMocks[1].id === o.id) ).to.be.undefined() }) @@ -90,10 +90,10 @@ describe('@services::Organisation', () => { email, }) const orgs = await Organisation.find({ filters }, db) - const DHIS2App = orgs.find(o => o.name === 'DHIS2') + const DHIS2App = orgs.find((o) => o.name === 'DHIS2') expect(DHIS2App).to.not.be.undefined() expect( - orgs.find(o => OrganisationMocks[1].id === o.id) + orgs.find((o) => OrganisationMocks[1].id === o.id) ).to.be.undefined() }) }) @@ -129,8 +129,8 @@ describe('@services::Organisation', () => { expect(orgById.users).to.have.length(3) const members = [UserMocks[1].name, UserMocks[2].name] - members.forEach(name => { - const member = orgById.users.find(u => u.name === name) + members.forEach((name) => { + const member = orgById.users.find((u) => u.name === name) expect(member).to.not.be.undefined() expect(member.id).to.be.a.string() }) @@ -176,7 +176,9 @@ describe('@services::Organisation', () => { expect(orgWithUsers).to.include('name') expect(orgWithUsers.name).to.be.equal('World Health Organization') expect(orgWithUsers.users).to.be.an.array() - const user = orgWithUsers.users.find(u => u.name === userMock.name) + const user = orgWithUsers.users.find( + (u) => u.name === userMock.name + ) expect(user).to.not.be.undefined() expect(user.email).to.be.equal(userMock.email) }) @@ -219,7 +221,7 @@ describe('@services::Organisation', () => { expect(org.id).to.be.a.string() expect(org.name).to.be.equal('World Health Organization') - const addUserAndGetOrg = async trx => { + const addUserAndGetOrg = async (trx) => { await Organisation.addUserById(org.id, userId, trx) const orgWithUsers = await Organisation.findOne( org.id, @@ -231,7 +233,7 @@ describe('@services::Organisation', () => { const orgWithUsers = await db.transaction(addUserAndGetOrg) const newlyAddedUser = orgWithUsers.users.find( - u => u.name === userMock.name + (u) => u.name === userMock.name ) expect(newlyAddedUser).to.not.be.undefined() }) @@ -253,7 +255,7 @@ describe('@services::Organisation', () => { expect(whoOrg.id).to.be.a.string() expect(whoOrg.name).to.be.equal('World Health Organization') - const addUser = async trx => { + const addUser = async (trx) => { // appstoreUser to who await Organisation.addUserById(whoOrg.id, appstoreUserId, trx) const orgWithUsers = await Organisation.findOne( @@ -263,7 +265,7 @@ describe('@services::Organisation', () => { ) expect(orgWithUsers.users).to.be.an.array() const newUser = orgWithUsers.users.find( - u => u.name === UserMocks[0].name + (u) => u.name === UserMocks[0].name ) expect(newUser).to.not.be.undefined() // add Erik to WHO, should fail @@ -282,7 +284,7 @@ describe('@services::Organisation', () => { ) expect(orgWithUsers.users).to.be.an.array() const newUser = orgWithUsers.users.find( - u => u.name === UserMocks[0].name + (u) => u.name === UserMocks[0].name ) // should be rollbacked, so user should not have been added expect(newUser).to.be.undefined() @@ -297,7 +299,7 @@ describe('@services::Organisation', () => { expect(users).to.be.an.array() expect( - users.findIndex(u => u.email === 'erik@dhis2.org') + users.findIndex((u) => u.email === 'erik@dhis2.org') ).to.be.above(-1) }) @@ -346,7 +348,7 @@ describe('@services::Organisation', () => { const jenkins = await getUserByEmail('apphub-api@dhis2.org', db) const name = 'Sintef' - const createAndGetOrg = async trx => { + const createAndGetOrg = async (trx) => { const { id } = await Organisation.create({ userId, name }, trx) expect(id).to.be.a.string() return await Organisation.findOne(id, true, trx) diff --git a/tools/.eslintrc.js b/tools/.eslintrc.js index b7cb040a6..e363f89ea 100644 --- a/tools/.eslintrc.js +++ b/tools/.eslintrc.js @@ -2,4 +2,4 @@ const { config } = require('@dhis2/cli-style') module.exports = { extends: [config.eslint], -} \ No newline at end of file +} diff --git a/tools/clean.js b/tools/clean.js index ea36ce0c0..8c4a88906 100644 --- a/tools/clean.js +++ b/tools/clean.js @@ -6,7 +6,7 @@ async function main() { const publishedAppsResponse = await request(targetUrl + '/apps') const appsJson = JSON.parse(publishedAppsResponse) - const deleteRequestPromises = appsJson.map(app => + const deleteRequestPromises = appsJson.map((app) => request.delete(`${targetUrl}/apps/${app.id}`) ) diff --git a/tools/clone.js b/tools/clone.js index 3d1e1f4fa..51c9e152e 100644 --- a/tools/clone.js +++ b/tools/clone.js @@ -185,11 +185,11 @@ async function main() { if (errors && errors.length > 0) { console.log(' === WARNING: Found errors during run === ') - errors.map(err => console.error(err)) + errors.map((err) => console.error(err)) } console.log('Cleaning up...') - await rimraf('./apps', function() { + await rimraf('./apps', function () { console.log('Done.') }) } diff --git a/tools/helpers/downloadImages.js b/tools/helpers/downloadImages.js index 88bbc029f..5f2c8fd03 100644 --- a/tools/helpers/downloadImages.js +++ b/tools/helpers/downloadImages.js @@ -4,7 +4,7 @@ const url = require('url') const request = require('request-promise-native') module.exports = async (dir, app) => { - const imagesDownloadPromises = app.images.map(appImage => { + const imagesDownloadPromises = app.images.map((appImage) => { const parsedUrl = url.parse(appImage.imageUrl) const lastIndex = parsedUrl.pathname.lastIndexOf('.') const fileExtension = parsedUrl.path.substring(lastIndex) @@ -21,7 +21,7 @@ module.exports = async (dir, app) => { ) resolve() }) - .on('error', error => { + .on('error', (error) => { reject(error) }) }) diff --git a/tools/helpers/downloadVersions.js b/tools/helpers/downloadVersions.js index bd24866a4..1778bebe2 100644 --- a/tools/helpers/downloadVersions.js +++ b/tools/helpers/downloadVersions.js @@ -3,7 +3,7 @@ const fs = require('fs') const path = require('path') module.exports = async (dir, app) => { - const versionDownloadPromises = app.versions.map(appVersion => { + const versionDownloadPromises = app.versions.map((appVersion) => { return new Promise((resolve, reject) => { const appVersionFile = fs.createWriteStream( path.join(dir, appVersion.version + '.zip') @@ -16,7 +16,7 @@ module.exports = async (dir, app) => { ) resolve() }) - .on('error', error => { + .on('error', (error) => { reject(error) }) }) diff --git a/tools/helpers/generateAppVersion.js b/tools/helpers/generateAppVersion.js index bca2633f3..93d570537 100644 --- a/tools/helpers/generateAppVersion.js +++ b/tools/helpers/generateAppVersion.js @@ -45,7 +45,7 @@ const zip = (name, files, path) => { } const p = Path.join(path, `${name}.zip`) console.log('Zipping file...') - zip.writeZip(p, e => { + zip.writeZip(p, (e) => { e && reject(e) console.log('Zipped to', p) resolve(zip) From f9c7287bd0a937c0c383aca96f0bbd43c4389795 Mon Sep 17 00:00:00 2001 From: Mozafar Haider Date: Tue, 3 Dec 2024 05:47:24 +0000 Subject: [PATCH 2/2] chore: run linting on CI --- .github/workflows/dhis2-verify-commits.yml | 13 +++++++++++++ package.json | 2 ++ 2 files changed, 15 insertions(+) diff --git a/.github/workflows/dhis2-verify-commits.yml b/.github/workflows/dhis2-verify-commits.yml index a8600bb27..072503d60 100644 --- a/.github/workflows/dhis2-verify-commits.yml +++ b/.github/workflows/dhis2-verify-commits.yml @@ -5,6 +5,19 @@ on: types: ['opened', 'edited', 'reopened', 'synchronize'] jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'yarn' + - run: yarn install --frozen-lockfile + - id: lint + run: yarn lint lint-pr-title: runs-on: ubuntu-latest steps: diff --git a/package.json b/package.json index 4135cb215..9ec962a27 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "test:server": "yarn workspace server test", "test:client": "yarn workspace client test", "clone": "yarn workspace tools clone", + "lint": "d2-style check", + "lint:staged": "d2-style check --staged", "format": "yarn format:js && yarn format:text", "format:staged": "yarn format:js --staged && yarn format:text --staged", "format:js": "d2-style apply js",