From ea6e34c29808f08159b7de63346ab40645351194 Mon Sep 17 00:00:00 2001 From: vkumar-sonata Date: Tue, 21 Jul 2026 09:55:43 +0000 Subject: [PATCH 1/3] fix: add missing SiteConfig service override definitions --- types.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/types.ts b/types.ts index 62113472..303de828 100644 --- a/types.ts +++ b/types.ts @@ -59,6 +59,31 @@ export interface RequiredSiteConfig { export type LocalizedMessages = Record>; export type SiteMessages = LocalizedMessages[]; +// Generic logger contract +export interface LoggingService { + debug?(message: string, meta?: Record): void, + info?(message: string, meta?: Record): void, + warn?(message: string, meta?: Record): void, + error?(message: string | Error, meta?: Record): void, +} + +// Generic analytics contract +export interface AnalyticsService { + identify?(userId: string | number, traits?: Record): void, + track(event: string, properties?: Record): void, + page?(name?: string, properties?: Record): void, + reset?(): void, +} + +// Generic auth contract +export interface AuthService { + isAuthenticated(): boolean | Promise, + getAccessToken?(): string | null | Promise, + login?(redirectUrl?: string): void | Promise, + logout?(redirectUrl?: string): void | Promise, + getCurrentUser?(): User | null | Promise, +} + export interface OptionalSiteConfig { // Site environment environment: EnvironmentTypes, @@ -92,6 +117,11 @@ export interface OptionalSiteConfig { // Analytics segmentKey: string | null, + + // Services + loggingService: LoggingService, + analyticsService: AnalyticsService, + authService: AuthService, } export type SiteConfig = RequiredSiteConfig & Partial; From 3195cdc47fddaff9211cdeb766ced085d321586d Mon Sep 17 00:00:00 2001 From: vkumar-sonata Date: Thu, 6 Aug 2026 19:22:28 +0000 Subject: [PATCH 2/3] fix: correct service constructor types and add typecheck fixture --- eslint.config.js | 1 + runtime/analytics/types.ts | 7 +++ runtime/auth/types.ts | 13 +++++ ...site-config-service-overrides.typecheck.ts | 18 ++++++ types.ts | 57 +++++++++++-------- 5 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 runtime/analytics/types.ts create mode 100644 runtime/auth/types.ts create mode 100644 test-types/site-config-service-overrides.typecheck.ts diff --git a/eslint.config.js b/eslint.config.js index 079f4afc..286f14ca 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,6 +13,7 @@ module.exports = tseslint.config( 'test-site/*', 'config/*', 'docs/*', + 'test-types/*', ], }, ); diff --git a/runtime/analytics/types.ts b/runtime/analytics/types.ts new file mode 100644 index 00000000..0d0a1769 --- /dev/null +++ b/runtime/analytics/types.ts @@ -0,0 +1,7 @@ +export interface AnalyticsService { + sendTrackingLogEvent(eventName: string, properties: object): Promise, + identifyAuthenticatedUser(userId: string | number, traits?: Record): void, + identifyAnonymousUser(traits?: Record): void, + sendTrackEvent(eventName?: string, properties?: Record): void, + sendPageEvent(category: string, name: string, properties?: Record): void, +} diff --git a/runtime/auth/types.ts b/runtime/auth/types.ts new file mode 100644 index 00000000..4a26d390 --- /dev/null +++ b/runtime/auth/types.ts @@ -0,0 +1,13 @@ +export interface AuthService { + getAuthenticatedHttpClient(options?: Record): unknown, + getHttpClient(options?: Record): unknown, + getLoginRedirectUrl(redirectUrl?: string): string, + redirectToLogin(redirectUrl?: string): void, + getLogoutRedirectUrl(redirectUrl?: string): string, + redirectToLogout(redirectUrl?: string): void, + getAuthenticatedUser(): Record | null, + setAuthenticatedUser(authUser: Record): void, + fetchAuthenticatedUser(options?: Record): Promise | null>, + ensureAuthenticatedUser(redirectUrl?: string): Promise>, + hydrateAuthenticatedUser(): Promise, +} diff --git a/test-types/site-config-service-overrides.typecheck.ts b/test-types/site-config-service-overrides.typecheck.ts new file mode 100644 index 00000000..c0b7bdd7 --- /dev/null +++ b/test-types/site-config-service-overrides.typecheck.ts @@ -0,0 +1,18 @@ +import { SiteConfig } from '../types'; +import NewRelicLoggingService from '../runtime/logging/NewRelicLoggingService'; +import SegmentAnalyticsService from '../runtime/analytics/SegmentAnalyticsService'; +import AxiosJwtAuthService from '../runtime/auth/AxiosJwtAuthService'; + +const config: SiteConfig = { + loggingService: NewRelicLoggingService, + analyticsService: SegmentAnalyticsService, + authService: AxiosJwtAuthService, + siteId: '', + siteName: '', + baseUrl: '', + lmsBaseUrl: '', + loginUrl: '', + logoutUrl: '', +} + +export default config; \ No newline at end of file diff --git a/types.ts b/types.ts index 303de828..62e62f97 100644 --- a/types.ts +++ b/types.ts @@ -2,6 +2,9 @@ import { FC, ReactElement, ReactNode } from 'react'; import { MessageDescriptor } from 'react-intl'; import { RouteObject } from 'react-router'; import { SlotOperation } from './runtime/slots/types'; +import { LoggingService } from './runtime/logging/types'; +import { AnalyticsService } from './runtime/analytics/types'; +import { AuthService } from './runtime/auth/types'; // Apps @@ -59,30 +62,34 @@ export interface RequiredSiteConfig { export type LocalizedMessages = Record>; export type SiteMessages = LocalizedMessages[]; -// Generic logger contract -export interface LoggingService { - debug?(message: string, meta?: Record): void, - info?(message: string, meta?: Record): void, - warn?(message: string, meta?: Record): void, - error?(message: string | Error, meta?: Record): void, -} +export type { LoggingService, AnalyticsService, AuthService }; -// Generic analytics contract -export interface AnalyticsService { - identify?(userId: string | number, traits?: Record): void, - track(event: string, properties?: Record): void, - page?(name?: string, properties?: Record): void, - reset?(): void, -} +// Logging instantiated +export type LoggingServiceClass = new (options: { + config: SiteConfig, +}) => LoggingService; -// Generic auth contract -export interface AuthService { - isAuthenticated(): boolean | Promise, - getAccessToken?(): string | null | Promise, - login?(redirectUrl?: string): void | Promise, - logout?(redirectUrl?: string): void | Promise, - getCurrentUser?(): User | null | Promise, -} +// Analytics instantiated +export type AnalyticsServiceClass = new (options: { + config: SiteConfig, + loggingService: LoggingService, + httpClient: unknown, +}) => AnalyticsService; + +// Auth instantiated +export type AuthServiceClass = new (options: { + config: { + baseUrl: string, + lmsBaseUrl: string, + loginUrl: string, + logoutUrl: string, + refreshAccessTokenApiPath: string, + accessTokenCookieName: string, + csrfTokenApiPath: string, + }, + loggingService: object, + middleware?: unknown[], +}) => AuthService; export interface OptionalSiteConfig { // Site environment @@ -119,9 +126,9 @@ export interface OptionalSiteConfig { segmentKey: string | null, // Services - loggingService: LoggingService, - analyticsService: AnalyticsService, - authService: AuthService, + loggingService: LoggingServiceClass, + analyticsService: AnalyticsServiceClass, + authService: AuthServiceClass, } export type SiteConfig = RequiredSiteConfig & Partial; From 8c5c1a8986f8152c6bf3910a5f7b0b044b3d33c6 Mon Sep 17 00:00:00 2001 From: vkumar-sonata Date: Mon, 31 Aug 2026 05:37:01 +0000 Subject: [PATCH 3/3] fix: refine service constructor types based on reviewer feedback --- eslint.config.js | 1 - runtime/analytics/index.ts | 1 + runtime/analytics/types.ts | 2 +- runtime/auth/index.ts | 1 + runtime/auth/types.ts | 12 +++++---- runtime/logging/index.ts | 1 + ...site-config-service-overrides.typecheck.ts | 18 ------------- types.ts | 27 +++++-------------- 8 files changed, 18 insertions(+), 45 deletions(-) delete mode 100644 test-types/site-config-service-overrides.typecheck.ts diff --git a/eslint.config.js b/eslint.config.js index 286f14ca..079f4afc 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -13,7 +13,6 @@ module.exports = tseslint.config( 'test-site/*', 'config/*', 'docs/*', - 'test-types/*', ], }, ); diff --git a/runtime/analytics/index.ts b/runtime/analytics/index.ts index 36613629..ffa65611 100644 --- a/runtime/analytics/index.ts +++ b/runtime/analytics/index.ts @@ -10,3 +10,4 @@ export { } from './interface'; export { default as MockAnalyticsService } from './MockAnalyticsService'; export { default as SegmentAnalyticsService } from './SegmentAnalyticsService'; +export type * from './types'; diff --git a/runtime/analytics/types.ts b/runtime/analytics/types.ts index 0d0a1769..1ed9797d 100644 --- a/runtime/analytics/types.ts +++ b/runtime/analytics/types.ts @@ -1,5 +1,5 @@ export interface AnalyticsService { - sendTrackingLogEvent(eventName: string, properties: object): Promise, + sendTrackingLogEvent(eventName: string, properties: object): Promise, identifyAuthenticatedUser(userId: string | number, traits?: Record): void, identifyAnonymousUser(traits?: Record): void, sendTrackEvent(eventName?: string, properties?: Record): void, diff --git a/runtime/auth/index.ts b/runtime/auth/index.ts index eaf890bb..49b74a4e 100644 --- a/runtime/auth/index.ts +++ b/runtime/auth/index.ts @@ -17,3 +17,4 @@ export { setAuthenticatedUser } from './interface'; export { default as MockAuthService } from './MockAuthService'; +export type * from './types'; diff --git a/runtime/auth/types.ts b/runtime/auth/types.ts index 4a26d390..f8d38e43 100644 --- a/runtime/auth/types.ts +++ b/runtime/auth/types.ts @@ -1,3 +1,5 @@ +import { User } from '../../types'; + export interface AuthService { getAuthenticatedHttpClient(options?: Record): unknown, getHttpClient(options?: Record): unknown, @@ -5,9 +7,9 @@ export interface AuthService { redirectToLogin(redirectUrl?: string): void, getLogoutRedirectUrl(redirectUrl?: string): string, redirectToLogout(redirectUrl?: string): void, - getAuthenticatedUser(): Record | null, - setAuthenticatedUser(authUser: Record): void, - fetchAuthenticatedUser(options?: Record): Promise | null>, - ensureAuthenticatedUser(redirectUrl?: string): Promise>, - hydrateAuthenticatedUser(): Promise, + getAuthenticatedUser(): User | null, + setAuthenticatedUser(authUser: User): void, + fetchAuthenticatedUser(options?: Record): Promise, + ensureAuthenticatedUser(redirectUrl?: string): Promise, + hydrateAuthenticatedUser(): Promise, } diff --git a/runtime/logging/index.ts b/runtime/logging/index.ts index c7ec935d..95d5d500 100644 --- a/runtime/logging/index.ts +++ b/runtime/logging/index.ts @@ -7,3 +7,4 @@ export { } from './interface'; export { default as MockLoggingService } from './MockLoggingService'; export { default as NewRelicLoggingService } from './NewRelicLoggingService'; +export type * from './types'; diff --git a/test-types/site-config-service-overrides.typecheck.ts b/test-types/site-config-service-overrides.typecheck.ts deleted file mode 100644 index c0b7bdd7..00000000 --- a/test-types/site-config-service-overrides.typecheck.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { SiteConfig } from '../types'; -import NewRelicLoggingService from '../runtime/logging/NewRelicLoggingService'; -import SegmentAnalyticsService from '../runtime/analytics/SegmentAnalyticsService'; -import AxiosJwtAuthService from '../runtime/auth/AxiosJwtAuthService'; - -const config: SiteConfig = { - loggingService: NewRelicLoggingService, - analyticsService: SegmentAnalyticsService, - authService: AxiosJwtAuthService, - siteId: '', - siteName: '', - baseUrl: '', - lmsBaseUrl: '', - loginUrl: '', - logoutUrl: '', -} - -export default config; \ No newline at end of file diff --git a/types.ts b/types.ts index 62e62f97..b8ac4771 100644 --- a/types.ts +++ b/types.ts @@ -2,9 +2,9 @@ import { FC, ReactElement, ReactNode } from 'react'; import { MessageDescriptor } from 'react-intl'; import { RouteObject } from 'react-router'; import { SlotOperation } from './runtime/slots/types'; -import { LoggingService } from './runtime/logging/types'; -import { AnalyticsService } from './runtime/analytics/types'; -import { AuthService } from './runtime/auth/types'; +import { LoggingService } from './runtime/logging'; +import { AnalyticsService } from './runtime/analytics'; +import { AuthService } from './runtime/auth'; // Apps @@ -62,33 +62,20 @@ export interface RequiredSiteConfig { export type LocalizedMessages = Record>; export type SiteMessages = LocalizedMessages[]; -export type { LoggingService, AnalyticsService, AuthService }; - -// Logging instantiated export type LoggingServiceClass = new (options: { config: SiteConfig, }) => LoggingService; -// Analytics instantiated export type AnalyticsServiceClass = new (options: { config: SiteConfig, loggingService: LoggingService, httpClient: unknown, }) => AnalyticsService; -// Auth instantiated export type AuthServiceClass = new (options: { - config: { - baseUrl: string, - lmsBaseUrl: string, - loginUrl: string, - logoutUrl: string, - refreshAccessTokenApiPath: string, - accessTokenCookieName: string, - csrfTokenApiPath: string, - }, - loggingService: object, - middleware?: unknown[], + config: SiteConfig, + loggingService: LoggingService, + middleware: unknown[], }) => AuthService; export interface OptionalSiteConfig { @@ -157,7 +144,7 @@ export interface User { roles: string[], userId: number, username: string, - avatar: string, + avatar?: string, } export enum EnvironmentTypes {