diff --git a/runtime/analytics/types.ts b/runtime/analytics/types.ts new file mode 100644 index 00000000..50ca4a66 --- /dev/null +++ b/runtime/analytics/types.ts @@ -0,0 +1,7 @@ +export interface AnalyticsService { + sendTrackingLogEvent(eventName: string, properties: Record): 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/AxiosJwtAuthService.js b/runtime/auth/AxiosJwtAuthService.js index 41e4b669..5c105e6c 100644 --- a/runtime/auth/AxiosJwtAuthService.js +++ b/runtime/auth/AxiosJwtAuthService.js @@ -32,15 +32,9 @@ const optionsPropTypes = { class AxiosJwtAuthService { /** * @param {Object} options - * @param {Object} options.config - * @param {string} options.config.baseUrl - * @param {string} options.config.lmsBaseUrl - * @param {string} options.config.loginUrl - * @param {string} options.config.logoutUrl - * @param {string} options.config.refreshAccessTokenApiPath - * @param {string} options.config.accessTokenCookieName - * @param {string} options.config.csrfTokenApiPath + * @param {import('../../types').SiteConfig} options.config * @param {Object} options.loggingService requires logError and logInfo methods + * @param {Array} [options.middleware] Optional array of middleware functions to apply to the HTTP clients. */ constructor(options) { this.authenticatedHttpClient = null; @@ -288,7 +282,7 @@ class AxiosJwtAuthService { * console.log(authenticatedUser); // Will contain additional user information * ``` * - * @returns {Promise} + * @returns {Promise} */ async hydrateAuthenticatedUser() { const user = this.getAuthenticatedUser(); diff --git a/runtime/auth/MockAuthService.js b/runtime/auth/MockAuthService.js index 48684226..33ffb667 100644 --- a/runtime/auth/MockAuthService.js +++ b/runtime/auth/MockAuthService.js @@ -75,14 +75,7 @@ const optionsPropTypes = { class MockAuthService { /** * @param {Object} options - * @param {Object} options.config - * @param {string} options.config.baseUrl - * @param {string} options.config.lmsBaseUrl - * @param {string} options.config.loginUrl - * @param {string} options.config.logoutUrl - * @param {string} options.config.refreshAccessTokenApiPath - * @param {string} options.config.accessTokenCookieName - * @param {string} options.config.csrfTokenApiPath + * @param {import('../../types').SiteConfig} options.config * @param {Object} options.loggingService requires logError and logInfo methods */ constructor(options) { @@ -265,9 +258,9 @@ class MockAuthService { * console.log(authenticatedUser); // Will contain additional user information * ``` * - * @returns {Promise} + * @returns {Promise} */ - hydrateAuthenticatedUser = jest.fn(() => { + hydrateAuthenticatedUser = jest.fn(async () => { const user = this.getAuthenticatedUser(); if (user !== null) { this.setAuthenticatedUser({ ...user, ...this.hydratedAuthenticatedUser }); diff --git a/runtime/auth/types.ts b/runtime/auth/types.ts new file mode 100644 index 00000000..7616dbb0 --- /dev/null +++ b/runtime/auth/types.ts @@ -0,0 +1,15 @@ +import { User } from '../../types'; + +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(): User | null; + setAuthenticatedUser(authUser: User): void; + fetchAuthenticatedUser(options?: Record): Promise; + ensureAuthenticatedUser(redirectUrl?: string): Promise; + hydrateAuthenticatedUser(): Promise; +} diff --git a/runtime/index.ts b/runtime/index.ts index 6ad3accf..d810ba90 100644 --- a/runtime/index.ts +++ b/runtime/index.ts @@ -11,6 +11,8 @@ export { sendTrackingLogEvent } from './analytics'; +export type { AnalyticsService } from './analytics/types'; + export { AUTHENTICATED_USER_CHANGED, AUTHENTICATED_USER_TOPIC, @@ -31,6 +33,8 @@ export { setAuthenticatedUser } from './auth'; +export type { AuthService } from './auth/types'; + export { getSiteConfig, setSiteConfig, @@ -102,6 +106,8 @@ export { resetLoggingService } from './logging'; +export type { LoggingService } from './logging/types'; + export { CurrentAppContext, CurrentAppProvider, diff --git a/types.ts b/types.ts index 4e81a595..238214e3 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 @@ -60,6 +63,22 @@ export interface RequiredSiteConfig { export type LocalizedMessages = Record>; export type SiteMessages = LocalizedMessages[]; +export type LoggingServiceClass = new (options: { + config: SiteConfig; +}) => LoggingService; + +export type AnalyticsServiceClass = new (options: { + config: SiteConfig; + loggingService: LoggingService; + httpClient: unknown; +}) => AnalyticsService; + +export type AuthServiceClass = new (options: { + config: SiteConfig; + loggingService: LoggingService; + middleware: unknown[]; +}) => AuthService; + export interface OptionalSiteConfig { // Site environment environment: EnvironmentTypes; @@ -97,6 +116,11 @@ export interface OptionalSiteConfig { // Analytics segmentKey: string | null; + + // Services + loggingService: LoggingServiceClass; + analyticsService: AnalyticsServiceClass; + authService: AuthServiceClass; } export type SiteConfig = RequiredSiteConfig & Partial; @@ -125,7 +149,7 @@ export interface User { roles: string[]; userId: number; username: string; - avatar: string; + avatar?: string; } export enum EnvironmentTypes {