Skip to content

Commit d490815

Browse files
VIA-537 SB & AS Improve config type safety and enable IntelliSense
Defines a strict `AppConfig` interface to map configuration keys to their specific types. This allows for the removal of manual type casting (e.g., `as string`) throughout the codebase and updates test builders to support the new typed structure. Also enables auto-complete for config keys in IntelliJ etc.
1 parent 3d66b66 commit d490815

34 files changed

+108
-77
lines changed

auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ const AuthJWTPerformanceMarker = "auth-jwt-callback";
2121
const AuthSessionPerformanceMarker = "auth-session-callback";
2222

2323
export const { handlers, signIn, signOut, auth } = NextAuth(async () => {
24-
const MAX_SESSION_AGE_SECONDS: number = ((await config.MAX_SESSION_AGE_MINUTES) as number) * 60;
24+
const MAX_SESSION_AGE_SECONDS: number = (await config.MAX_SESSION_AGE_MINUTES) * 60;
2525
const headerValues = await headers();
2626

2727
const requestContext: RequestContext = extractRequestContextFromHeaders(headerValues);
2828

2929
return await asyncLocalStorage.run(requestContext, async () => {
3030
return {
3131
providers: [await NHSLoginAuthProvider()],
32-
secret: (await config.AUTH_SECRET) as string,
32+
secret: await config.AUTH_SECRET,
3333
pages: {
3434
signIn: SSO_FAILURE_ROUTE,
3535
signOut: SESSION_LOGOUT_ROUTE,

contract/fetch-eligibility-content.contract.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { EligibilityApiResponse } from "@src/services/eligibility-api/api-types"
33
import { fetchEligibilityContent } from "@src/services/eligibility-api/gateway/fetch-eligibility-content";
44
import config from "@src/utils/config";
55
import { asyncLocalStorage } from "@src/utils/requestContext";
6-
import { AsyncConfigMock, configBuilder } from "@test-data/config/builders";
6+
import { ConfigMock, configBuilder } from "@test-data/config/builders";
77
import { readFileSync } from "fs";
88
import { pactWith } from "jest-pact";
99

@@ -40,7 +40,7 @@ const successfulResponse: EligibilityApiResponse = {
4040
};
4141

4242
pactWith({ consumer: "VitA", provider: "EliD", port: 1234, logLevel: "warn" }, (provider) => {
43-
const mockedConfig = config as AsyncConfigMock;
43+
const mockedConfig = config as ConfigMock;
4444

4545
beforeEach(() => {
4646
const defaultConfig = configBuilder()

src/_lambda/content-cache-hydrator/content-cache-reader.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { VaccineInfo, VaccineType } from "@src/models/vaccine";
66
import { readContentFromCache } from "@src/services/content-api/gateway/content-reader-service";
77
import { InvalidatedCacheError, S3NoSuchKeyError } from "@src/services/content-api/gateway/exceptions";
88
import config from "@src/utils/config";
9-
import { AsyncConfigMock, configBuilder } from "@test-data/config/builders";
9+
import { ConfigMock, configBuilder } from "@test-data/config/builders";
1010

1111
jest.mock("@src/services/content-api/gateway/content-reader-service");
1212
jest.mock("sanitize-data", () => ({ sanitize: jest.fn() }));
@@ -16,7 +16,7 @@ const mockContentCachePath = "wiremock/__files/";
1616
describe("readCachedContentForVaccine", () => {
1717
const mockCacheFileContents = "mock-cache-file-contents";
1818
const vaccineType = VaccineType.RSV;
19-
const mockedConfig = config as AsyncConfigMock;
19+
const mockedConfig = config as ConfigMock;
2020

2121
beforeEach(() => {
2222
const defaultConfig = configBuilder().withContentCachePath(mockContentCachePath).build();

src/_lambda/content-cache-hydrator/content-cache-reader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const readCachedContentForVaccine = async (vaccineType: VaccineType): Promise<Re
1616
let cachedContent: string;
1717

1818
try {
19-
cachedContent = await readContentFromCache((await config.CONTENT_CACHE_PATH) as string, cacheFilename, vaccineType);
19+
cachedContent = await readContentFromCache(await config.CONTENT_CACHE_PATH, cacheFilename, vaccineType);
2020
} catch (error) {
2121
if (error instanceof S3NoSuchKeyError) {
2222
return { cacheStatus: "empty", cacheContent: "" };

src/_lambda/content-cache-hydrator/content-fetcher.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CONTENT_API_PATH_PREFIX, fetchContentForVaccine } from "@src/_lambda/content-cache-hydrator/content-fetcher";
22
import { VaccineInfo, VaccineType } from "@src/models/vaccine";
33
import config from "@src/utils/config";
4-
import { AsyncConfigMock, configBuilder } from "@test-data/config/builders";
4+
import { ConfigMock, configBuilder } from "@test-data/config/builders";
55
import axios from "axios";
66

77
jest.mock("axios");
@@ -11,7 +11,7 @@ describe("fetchContentForVaccine", () => {
1111
const testApiKey: string = "test-key";
1212
const testApiEndpoint: URL = new URL("https://test-endpoint/");
1313
const testApiContent = { test: "content" };
14-
const mockedConfig = config as AsyncConfigMock;
14+
const mockedConfig = config as ConfigMock;
1515

1616
beforeEach(() => {
1717
const defaultConfig = configBuilder().withContentApiKey(testApiKey).andContentApiEndpoint(testApiEndpoint).build();

src/_lambda/content-cache-hydrator/content-fetcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ const log = logger.child({ module: "content-fetcher" });
77
const CONTENT_API_PATH_PREFIX = "nhs-website-content/";
88

99
const fetchContentForVaccine = async (vaccineType: VaccineType): Promise<string> => {
10-
const apiEndpoint: URL = (await config.CONTENT_API_ENDPOINT) as URL;
10+
const apiEndpoint: URL = await config.CONTENT_API_ENDPOINT;
1111
const vaccinePath = VaccineInfo[vaccineType].contentPath;
12-
const apiKey: string = (await config.CONTENT_API_KEY) as string;
12+
const apiKey: string = await config.CONTENT_API_KEY;
1313

1414
const uri: string = `${apiEndpoint}${CONTENT_API_PATH_PREFIX}${vaccinePath}`;
1515
let response: AxiosResponse;

src/_lambda/content-cache-hydrator/content-writer-service.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from "@src/_lambda/content-cache-hydrator/content-writer-service";
1010
import { Filename, VaccineInfo, VaccineType } from "@src/models/vaccine";
1111
import config from "@src/utils/config";
12-
import { AsyncConfigMock, configBuilder } from "@test-data/config/builders";
12+
import { ConfigMock, configBuilder } from "@test-data/config/builders";
1313
import { writeFile } from "node:fs/promises";
1414

1515
jest.mock("node:fs/promises");
@@ -29,7 +29,7 @@ describe("Content Writer Service", () => {
2929
const location: string = "test-location/";
3030
const path: Filename = "test-filename.json" as Filename;
3131
const content: string = "test-data";
32-
const mockedConfig = config as AsyncConfigMock;
32+
const mockedConfig = config as ConfigMock;
3333

3434
beforeEach(() => {
3535
mockSend = jest.fn();

src/_lambda/content-cache-hydrator/content-writer-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const _writeContentToCache = async (
3939

4040
const writeContentForVaccine = async (vaccineType: VaccineType, vaccineContent: string) => {
4141
const cacheFilename = VaccineInfo[vaccineType].cacheFilename;
42-
await _writeContentToCache((await config.CONTENT_CACHE_PATH) as string, cacheFilename, vaccineContent);
42+
await _writeContentToCache(await config.CONTENT_CACHE_PATH, cacheFilename, vaccineContent);
4343
};
4444

4545
export { _writeFileS3, _writeContentToCache, writeContentForVaccine };

src/_lambda/content-cache-hydrator/handler.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { getFilteredContentForVaccine } from "@src/services/content-api/parsers/
1212
import { getStyledContentForVaccine } from "@src/services/content-api/parsers/content-styling-service";
1313
import config from "@src/utils/config";
1414
import { RequestContext, asyncLocalStorage } from "@src/utils/requestContext";
15-
import { AsyncConfigMock, configBuilder } from "@test-data/config/builders";
15+
import { ConfigMock, configBuilder } from "@test-data/config/builders";
1616
import { Context } from "aws-lambda";
1717

1818
jest.mock("@src/_lambda/content-cache-hydrator/content-writer-service");
@@ -53,7 +53,7 @@ describe("Lambda Handler", () => {
5353
});
5454

5555
describe("when content-change-approval-needed feature disabled", () => {
56-
const mockedConfig = config as AsyncConfigMock;
56+
const mockedConfig = config as ConfigMock;
5757

5858
beforeEach(() => {
5959
const defaultConfig = configBuilder().withContentCacheIsChangeApprovalEnabled(false).build();
@@ -100,7 +100,7 @@ describe("Lambda Handler", () => {
100100
});
101101

102102
describe("when content-change-approval-needed feature enabled", () => {
103-
const mockedConfig = config as AsyncConfigMock;
103+
const mockedConfig = config as ConfigMock;
104104

105105
beforeEach(() => {
106106
const defaultConfig = configBuilder().withContentCacheIsChangeApprovalEnabled(true).build();

src/_lambda/content-cache-hydrator/handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ const runContentCacheHydrator = async (event: ContentCacheHydratorEvent) => {
150150
for (const vaccine of vaccinesToRunOn) {
151151
const status = await hydrateCacheForVaccine(
152152
vaccine,
153-
(await config.CONTENT_CACHE_IS_CHANGE_APPROVAL_ENABLED) as boolean,
153+
await config.CONTENT_CACHE_IS_CHANGE_APPROVAL_ENABLED,
154154
forceUpdate,
155155
);
156156
invalidatedCount += status.invalidatedCount;

0 commit comments

Comments
 (0)