Skip to content

Commit c7ab132

Browse files
authored
RD-5740 Migrate backend to TypeScript - part 1 (#2179)
* Migrate samlSetup.ts, LoggerHandler.ts and config.ts * Remove unused functions and imports * Refactor DB models types to allow using model data in frontend * Add types for most of the backend routes * Migrate backend tests to TypeScript
1 parent 30ab5d3 commit c7ab132

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+661
-448
lines changed

app/actions/managers.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { clearContext } from './context';
1313
import { setLicense, setLicenseRequired } from './license';
1414
import { setVersion } from './version';
1515
import type { ReduxState } from '../reducers';
16-
import type { AuthUserResponse } from '../../backend/routes/Auth.types';
16+
import type { GetAuthUserResponse } from '../../backend/routes/Auth.types';
1717

1818
function requestLogin() {
1919
return {
@@ -77,7 +77,7 @@ export function login(
7777
};
7878
}
7979

80-
function responseUserData({ username, role, groupSystemRoles, tenantsRoles, showGettingStarted }: AuthUserResponse) {
80+
function responseUserData({ username, role, groupSystemRoles, tenantsRoles, showGettingStarted }: GetAuthUserResponse) {
8181
return {
8282
type: types.SET_USER_DATA,
8383
username,

app/components/AuthRoutes.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Layout from '../containers/layout/Layout';
1515
import LicensePage from '../containers/LicensePage';
1616
import MaintenanceMode from '../containers/maintenance/MaintenanceModePageMessage';
1717
import SplashLoadingScreen from '../utils/SplashLoadingScreen';
18-
import type { AuthUserResponse } from '../../backend/routes/Auth.types';
18+
import type { GetAuthUserResponse } from '../../backend/routes/Auth.types';
1919

2020
class NoTenantsError extends Error {}
2121

@@ -34,7 +34,7 @@ const AuthRoutes: FunctionComponent = () => {
3434
dispatch(getManagerData())
3535
.then(() => dispatch(getTenants()))
3636
.then(() => dispatch(getUserData()))
37-
.then(({ tenantsRoles, role }: AuthUserResponse) => {
37+
.then(({ tenantsRoles, role }: GetAuthUserResponse) => {
3838
if (isEmpty(tenantsRoles) && role !== Consts.ROLE.SYS_ADMIN) throw new NoTenantsError();
3939
setManagerDataFetched();
4040
})

app/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"types": [],
55
"plugins": [{ "name": "typescript-styled-plugin" }]
66
},
7-
"include": ["**/*", "**/*.json", "../backend/consts.ts", "../backend/serverSettings.ts", "../backend/types.ts", "../backend/routes/*.types.ts", "../backend/sharedUtils.ts", "../conf/*.json"],
7+
"include": ["**/*", "**/*.json", "../backend/consts.ts", "../backend/serverSettings.ts", "../backend/**/types.ts",
8+
"../backend/**/*.types.ts", "../backend/sharedUtils.ts", "../conf/*.json"],
89
"files": ["../package.json"]
910
}

app/utils/ConfigLoader.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import log from 'loglevel';
22
import fetch from 'isomorphic-fetch';
33

44
import StageUtils from './stageUtils';
5-
import type { ClientConfig } from '../../backend/routes/Config.types';
5+
import type { GetConfigResponse } from '../../backend/routes/Config.types';
66

77
export default class ConfigLoader {
8-
static load(): Promise<ClientConfig> {
8+
static load(): Promise<GetConfigResponse> {
99
return fetch(StageUtils.Url.url('/config'))
1010
.then(response => response.json())
1111
.catch(e => {

app/utils/auth.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import External from './External';
66
import Internal from './Internal';
77
import encodeTextToBase64 from './encodeTextToBase64';
88
import type { ManagerData, LicenseData, LicenseStatus } from '../reducers/managerReducer';
9-
import type { AuthUserResponse, LicenseResponse } from '../../backend/routes/Auth.types';
9+
import type { GetAuthUserResponse, LicenseResponse } from '../../backend/routes/Auth.types';
1010

1111
export default class Auth {
1212
static login(username: string, password: string) {
@@ -21,7 +21,7 @@ export default class Auth {
2121

2222
static getUserData(managerData: ManagerData) {
2323
const internal = new Internal(managerData);
24-
return internal.doGet('/auth/user') as Promise<AuthUserResponse>;
24+
return internal.doGet('/auth/user') as Promise<GetAuthUserResponse>;
2525
}
2626

2727
static logout(managerData: ManagerData) {

backend/app.ts

+11-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
// @ts-nocheck File not migrated fully to TS
21
import fs from 'fs';
32
import path from 'path';
43
import expressStaticGzip from 'express-static-gzip';
54
import express from 'express';
65
import passport from 'passport';
76
import cookieParser from 'cookie-parser';
87
import morgan from 'morgan';
9-
import type { Router } from 'express';
8+
import type { ErrorRequestHandler, Router } from 'express';
109

11-
import { getConfig, getClientConfig } from './config';
10+
import { getConfig } from './config';
1211
import { CONTEXT_PATH } from './consts';
1312
import LoggerHandler from './handler/LoggerHandler';
14-
import { getMode } from './serverSettings';
1513
import { getResourcePath } from './utils';
1614

1715
import getCookieStrategy from './auth/CookieStrategy';
@@ -46,13 +44,13 @@ const app = express();
4644

4745
app.use(morgan('short', { stream: LoggerHandler.getStream('Express') }));
4846

49-
app.all('/', (request, response) => {
47+
app.all('/', (_request, response) => {
5048
logger.info(`Redirecting to "${contextPath}".`);
5149
response.redirect(contextPath);
5250
});
5351

5452
// For dev purposes
55-
app.use(contextPath, (req, res, next) => {
53+
app.use(contextPath, (_req, res, next) => {
5654
// Setting access control allow origin headers
5755
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4000');
5856
// Request methods you wish to allow
@@ -64,7 +62,7 @@ app.use(contextPath, (req, res, next) => {
6462
);
6563
// Set to true if you need the website to include cookies in the requests sent
6664
// to the API (e.g. in case you use sessions)
67-
res.setHeader('Access-Control-Allow-Credentials', true);
65+
res.setHeader('Access-Control-Allow-Credentials', 'true');
6866

6967
next();
7068
});
@@ -83,11 +81,11 @@ app.use(passport.initialize());
8381
app.use(
8482
`${contextPath}/appData`,
8583
authenticateWithCookie,
86-
expressStaticGzip(path.resolve(__dirname, '../dist/appData'), { indexFromEmptyFile: false })
84+
expressStaticGzip(path.resolve(__dirname, '../dist/appData'), { index: false })
8785
);
8886

8987
const translationsOverrides = 'overrides.json';
90-
app.use(`${contextPath}/userData/${translationsOverrides}`, (req, res) => {
88+
app.use(`${contextPath}/userData/${translationsOverrides}`, (_req, res) => {
9189
const overridesPath = getResourcePath(translationsOverrides, true);
9290
if (fs.existsSync(overridesPath)) res.sendFile(overridesPath);
9391
else res.send({});
@@ -97,7 +95,7 @@ app.use(
9795
`${contextPath}/userData`,
9896
authenticateWithCookie,
9997
expressStaticGzip(getResourcePath('', true), {
100-
indexFromEmptyFile: false
98+
index: false
10199
})
102100
);
103101
// API Routes with authentication
@@ -149,8 +147,7 @@ app.get('*', (request, response) => {
149147
* NOTE: error handlers must have 4 parameters, even if the last one is unused
150148
* @see https://expressjs.com/en/guide/error-handling.html
151149
*/
152-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
153-
app.use((err, req, res, next) => {
150+
const errorHandler: ErrorRequestHandler = (err, _req, res, _next) => {
154151
logger.error('Error has occured ', err);
155152

156153
let { message } = err;
@@ -159,6 +156,7 @@ app.use((err, req, res, next) => {
159156
}
160157

161158
res.status(err.status || 404).send({ message: message || err });
162-
});
159+
};
160+
app.use(errorHandler);
163161

164162
export default app;

backend/auth/SamlStrategy.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Strategy } from 'passport-saml';
2+
import type { Strategy as PassportStrategy } from 'passport';
23
import type { VerifyWithoutRequest } from 'passport-saml';
34
import fs from 'fs';
45
import { getConfig } from '../config';
@@ -18,5 +19,5 @@ export default () => {
1819
cert
1920
},
2021
((user, done) => done(null, user!)) as VerifyWithoutRequest
21-
);
22+
) as PassportStrategy;
2223
};

backend/config.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @ts-nocheck File not migrated fully to TS
21
/* eslint-disable node/no-unpublished-import,global-require,import/no-dynamic-require */
32
import _ from 'lodash';
43
import flatten from 'flat';
@@ -22,7 +21,7 @@ try {
2221
let userDataConfig: Partial<UserConfig> = require(userDataConfigPath);
2322
userDataConfig = _.pick(userDataConfig, _.keys(flatten(userConfig, { safe: true }))); // Security reason - get only allowed parameters
2423
userConfig = _.defaultsDeep(userDataConfig, userConfig); // Create full user configuration
25-
} catch (err) {
24+
} catch (err: any) {
2625
if (err.code !== 'MODULE_NOT_FOUND') {
2726
throw err;
2827
}
@@ -34,7 +33,7 @@ export function loadMeJson() {
3433
try {
3534
// eslint-disable-next-line import/no-unresolved
3635
me = require('../conf/me.json');
37-
} catch (err) {
36+
} catch (err: any) {
3837
if (err.code !== 'MODULE_NOT_FOUND') {
3938
throw err;
4039
}

backend/db/models/BlueprintAdditionsModel.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import type { CommonAttributes, Model, ModelFactory, Optional } from './types';
1+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2+
import type { Model, Optional } from 'sequelize';
3+
import type { ModelFactory } from 'cloudify-ui-common/backend/db';
4+
import type { BlueprintAdditionsAttributes } from './BlueprintAdditionsModel.types';
25

3-
interface BlueprintAdditionsAttributes extends CommonAttributes {
4-
blueprintId: string;
5-
image: any;
6-
imageUrl: string;
7-
}
86
type BlueprintAdditionsCreationAttributes = Optional<BlueprintAdditionsAttributes, 'image' | 'imageUrl'>;
97
export type BlueprintAdditionsInstance = Model<BlueprintAdditionsAttributes, BlueprintAdditionsCreationAttributes> &
108
BlueprintAdditionsAttributes;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { CommonAttributes } from './types';
2+
3+
export interface BlueprintAdditionsData {
4+
blueprintId: string;
5+
image: any;
6+
imageUrl: string;
7+
}
8+
9+
export type BlueprintAdditionsAttributes = CommonAttributes & BlueprintAdditionsData;

backend/db/models/BlueprintUserDataModel.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import type { CommonAttributes, Model, ModelFactory } from './types';
1+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2+
import type { Model } from 'sequelize';
3+
import type { ModelFactory } from 'cloudify-ui-common/backend/db';
4+
import type { BlueprintUserDataAttributes } from './BlueprintUserDataModel.types';
25

3-
interface BlueprintUserDataAttributes extends CommonAttributes {
4-
blueprintId: string;
5-
username: string;
6-
layout: any;
7-
}
86
type BlueprintUserDataCreationAttributes = BlueprintUserDataAttributes;
97
export type BlueprintUserDataInstance = Model<BlueprintUserDataAttributes, BlueprintUserDataCreationAttributes> &
108
BlueprintUserDataAttributes;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { CommonAttributes } from './types';
2+
3+
export interface BlueprintUserData {
4+
blueprintId: string;
5+
username: string;
6+
layout: any;
7+
}
8+
export type BlueprintUserDataAttributes = CommonAttributes & BlueprintUserData;

backend/db/models/ResourcesModel.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import type { CommonAttributes, Model, ModelFactory, Optional } from './types';
1+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2+
import type { Model, Optional } from 'sequelize';
3+
import type { ModelFactory } from 'cloudify-ui-common/backend/db';
4+
25
import type { ResourceType } from '../types/ResourceTypes';
36
import ResourceTypes from '../types/ResourceTypes';
7+
import type { CommonAttributes } from './types';
48

59
interface ResourcesAttributes extends CommonAttributes {
610
resourceId: string;

backend/db/models/UserAppsModel.ts

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
import type { CommonAttributes, Model, ModelFactory } from './types';
2-
import type { Mode } from '../../serverSettings';
1+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2+
import type { Model } from 'sequelize';
3+
import type { ModelFactory } from 'cloudify-ui-common/backend/db';
4+
35
import { MODE_COMMUNITY, MODE_CUSTOMER, MODE_MAIN } from '../../serverSettings';
4-
import type { PageFileDefinition } from '../../routes/Templates.types';
6+
import type { UserAppsAttributes } from './UserAppsModel.types';
57

6-
interface UserAppsAttributes extends CommonAttributes {
7-
username: string;
8-
appDataVersion: number;
9-
mode: Mode;
10-
tenant: string;
11-
appData: { pages: PageFileDefinition[] };
12-
}
13-
type UserAppsCreationAttributes = UserAppsAttributes;
8+
export type UserAppsCreationAttributes = UserAppsAttributes;
149
export type UserAppsInstance = Model<UserAppsAttributes, UserAppsCreationAttributes> & UserAppsAttributes;
1510

1611
const UserAppsModelFactory: ModelFactory<UserAppsInstance> = (sequelize, dataTypes) =>
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { CommonAttributes } from './types';
2+
import type { Mode } from '../../serverSettings';
3+
import type { PageFileDefinition } from '../../routes/Templates.types';
4+
5+
export interface UserAppsData {
6+
username: string;
7+
appDataVersion: number;
8+
mode: Mode;
9+
tenant: string;
10+
appData: { pages: PageFileDefinition[] };
11+
}
12+
13+
export type UserAppsAttributes = CommonAttributes & UserAppsData;

backend/db/models/WidgetBackendsModel.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
import type { CommonAttributes, Model, ModelFactory, Optional } from './types';
1+
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2+
import type { Model, Optional } from 'sequelize';
3+
import type { ModelFactory } from 'cloudify-ui-common/backend/db';
4+
import type { WidgetBackendsAttributes } from './WidgetBackendsModel.types';
25

3-
interface WidgetBackendsAttributes extends CommonAttributes {
4-
widgetId: string;
5-
serviceName: string;
6-
method: string;
7-
script: string;
8-
}
96
type WidgetBackendsCreationAttributes = Optional<WidgetBackendsAttributes, 'script'>;
107
export type WidgetBackendsInstance = Model<WidgetBackendsAttributes, WidgetBackendsCreationAttributes> &
118
WidgetBackendsAttributes;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { CommonAttributes } from './types';
2+
3+
export interface WidgetBackendsData {
4+
widgetId: string;
5+
serviceName: string;
6+
method: string;
7+
script: string;
8+
}
9+
10+
export type WidgetBackendsAttributes = CommonAttributes & WidgetBackendsData;

backend/db/models/types.ts

-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
// eslint-disable-next-line import/no-extraneous-dependencies,node/no-unpublished-import
2-
export type { Model, Optional } from 'sequelize';
3-
export type { ModelFactory } from 'cloudify-ui-common/backend/db';
4-
51
export interface CommonAttributes {
62
readonly id?: number;
73
readonly createdAt?: Date;

0 commit comments

Comments
 (0)