From 4b14f5e5e1294be207c714ae6c311710e5590273 Mon Sep 17 00:00:00 2001 From: areebniyas Date: Fri, 3 Oct 2025 11:58:46 +0530 Subject: [PATCH] chore: add strict mode support for javascript package --- packages/javascript/src/StorageManager.ts | 2 +- packages/javascript/src/__legacy__/client.ts | 18 +++--- .../helpers/authentication-helper.ts | 14 +++-- .../src/api/executeEmbeddedSignInFlow.ts | 20 ++++-- .../src/api/executeEmbeddedSignUpFlow.ts | 20 ++++-- packages/javascript/src/api/getSchemas.ts | 13 +++- packages/javascript/src/api/getScim2Me.ts | 13 +++- packages/javascript/src/api/getUserInfo.ts | 31 ++++++++-- .../src/api/initializeEmbeddedSignInFlow.ts | 20 ++++-- .../javascript/src/api/updateMeProfile.ts | 35 +++++++++-- .../src/utils/getAuthorizeRequestUrlParams.ts | 2 +- .../src/utils/getRedirectBasedSignUpUrl.ts | 4 +- .../javascript/src/utils/identifyPlatform.ts | 3 +- .../src/utils/processOpenIDScopes.ts | 2 +- .../transformBrandingPreferenceToTheme.ts | 62 +++++++++---------- packages/javascript/tsconfig.json | 2 +- 16 files changed, 184 insertions(+), 77 deletions(-) diff --git a/packages/javascript/src/StorageManager.ts b/packages/javascript/src/StorageManager.ts index b7130b5d..f800944b 100644 --- a/packages/javascript/src/StorageManager.ts +++ b/packages/javascript/src/StorageManager.ts @@ -68,7 +68,7 @@ class StorageManager { const dataToBeSaved: PartialData = {...existingData}; - delete dataToBeSaved[attribute as string]; + Reflect.deleteProperty(dataToBeSaved, attribute as string); const dataToBeSavedJSON: string = JSON.stringify(dataToBeSaved); diff --git a/packages/javascript/src/__legacy__/client.ts b/packages/javascript/src/__legacy__/client.ts index e54ddaec..1f11ba30 100644 --- a/packages/javascript/src/__legacy__/client.ts +++ b/packages/javascript/src/__legacy__/client.ts @@ -62,11 +62,11 @@ const DefaultConfig: Partial> = { */ export class AsgardeoAuthClient { private _storageManager!: StorageManager; - private _config: () => Promise; - private _oidcProviderMetaData: () => Promise; - private _authenticationHelper: AuthenticationHelper; - private _cryptoUtils: Crypto; - private _cryptoHelper: IsomorphicCrypto; + private _config!: () => Promise; + private _oidcProviderMetaData!: () => Promise; + private _authenticationHelper!: AuthenticationHelper; + private _cryptoUtils!: Crypto; + private _cryptoHelper!: IsomorphicCrypto; private static _instanceID: number; @@ -241,7 +241,7 @@ export class AsgardeoAuthClient { await this._storageManager.setTemporaryDataParameter(pkceKey, codeVerifier, userId); } - if (authRequestConfig['client_secret']) { + if (authRequestConfig['client_secret'] && configData.clientSecret) { authRequestConfig['client_secret'] = configData.clientSecret; } @@ -250,10 +250,10 @@ export class AsgardeoAuthClient { redirectUri: configData.afterSignInUrl, clientId: configData.clientId, scopes: processOpenIDScopes(configData.scopes), - responseMode: configData.responseMode, + ...(configData.responseMode && { responseMode: configData.responseMode }), codeChallengeMethod: PKCEConstants.DEFAULT_CODE_CHALLENGE_METHOD, - codeChallenge, - prompt: configData.prompt, + ...(codeChallenge && { codeChallenge }), + ...(configData.prompt && { prompt: configData.prompt }), }, {key: pkceKey}, authRequestConfig, diff --git a/packages/javascript/src/__legacy__/helpers/authentication-helper.ts b/packages/javascript/src/__legacy__/helpers/authentication-helper.ts index 792767ed..840ef30b 100644 --- a/packages/javascript/src/__legacy__/helpers/authentication-helper.ts +++ b/packages/javascript/src/__legacy__/helpers/authentication-helper.ts @@ -51,7 +51,9 @@ export class AuthenticationHelper { Object.keys(configData.endpoints).forEach((endpointName: string) => { const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); - oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + (oidcProviderMetaData as Record)[snakeCasedName] = configData?.endpoints + ? (configData.endpoints as Record)[endpointName] ?? '' + : ''; }); return {...response, ...oidcProviderMetaData}; @@ -100,7 +102,9 @@ export class AuthenticationHelper { Object.keys(configData.endpoints).forEach((endpointName: string) => { const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); - oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + (oidcProviderMetaData as Record)[snakeCasedName] = configData?.endpoints + ? (configData.endpoints as Record)[endpointName] ?? '' + : ''; }); return {...oidcProviderMetaData}; @@ -124,7 +128,9 @@ export class AuthenticationHelper { Object.keys(configData.endpoints).forEach((endpointName: string) => { const snakeCasedName: string = endpointName.replace(/[A-Z]/g, (letter: string) => `_${letter.toLowerCase()}`); - oidcProviderMetaData[snakeCasedName] = configData?.endpoints ? configData.endpoints[endpointName] : ''; + (oidcProviderMetaData as Record)[snakeCasedName] = configData?.endpoints + ? (configData.endpoints as Record)[endpointName] ?? '' + : ''; }); const defaultEndpoints: OIDCDiscoveryApiResponse = { @@ -231,7 +237,7 @@ export class AuthenticationHelper { .replace(TokenExchangeConstants.Placeholders.ACCESS_TOKEN, sessionData.access_token) .replace( TokenExchangeConstants.Placeholders.USERNAME, - this.getAuthenticatedUserInfo(sessionData.id_token).username, + this.getAuthenticatedUserInfo(sessionData.id_token).username || '', ) .replace(TokenExchangeConstants.Placeholders.SCOPES, scope) .replace(TokenExchangeConstants.Placeholders.CLIENT_ID, configData.clientId) diff --git a/packages/javascript/src/api/executeEmbeddedSignInFlow.ts b/packages/javascript/src/api/executeEmbeddedSignInFlow.ts index e91777e2..8320e9ef 100644 --- a/packages/javascript/src/api/executeEmbeddedSignInFlow.ts +++ b/packages/javascript/src/api/executeEmbeddedSignInFlow.ts @@ -36,14 +36,24 @@ const executeEmbeddedSignInFlow = async ({ ); } + const baseHeaders = { + 'Content-Type': 'application/json', + Accept: 'application/json', + }; + + let finalHeaders: HeadersInit; + if (requestConfig.headers instanceof Headers) { + finalHeaders = requestConfig.headers; + } else if (requestConfig.headers && typeof requestConfig.headers === 'object') { + finalHeaders = { ...baseHeaders, ...(requestConfig.headers as Record) }; + } else { + finalHeaders = baseHeaders; + } + const response: Response = await fetch(url ?? `${baseUrl}/oauth2/authn`, { ...requestConfig, method: requestConfig.method || 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - ...requestConfig.headers, - }, + headers: finalHeaders, body: JSON.stringify(payload), }); diff --git a/packages/javascript/src/api/executeEmbeddedSignUpFlow.ts b/packages/javascript/src/api/executeEmbeddedSignUpFlow.ts index 8224a129..b6b17c4e 100644 --- a/packages/javascript/src/api/executeEmbeddedSignUpFlow.ts +++ b/packages/javascript/src/api/executeEmbeddedSignUpFlow.ts @@ -59,14 +59,24 @@ const executeEmbeddedSignUpFlow = async ({ ); } + const baseHeaders = { + 'Content-Type': 'application/json', + Accept: 'application/json', + }; + + let finalHeaders: HeadersInit; + if (requestConfig.headers instanceof Headers) { + finalHeaders = requestConfig.headers; + } else if (requestConfig.headers && typeof requestConfig.headers === 'object') { + finalHeaders = { ...baseHeaders, ...(requestConfig.headers as Record) }; + } else { + finalHeaders = baseHeaders; + } + const response: Response = await fetch(url ?? `${baseUrl}/api/server/v1/flow/execute`, { ...requestConfig, method: requestConfig.method || 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - ...requestConfig.headers, - }, + headers: finalHeaders, body: JSON.stringify({ ...(payload ?? {}), flowType: EmbeddedFlowType.Registration, diff --git a/packages/javascript/src/api/getSchemas.ts b/packages/javascript/src/api/getSchemas.ts index 435bc089..148fd008 100644 --- a/packages/javascript/src/api/getSchemas.ts +++ b/packages/javascript/src/api/getSchemas.ts @@ -90,8 +90,19 @@ export interface GetSchemasConfig extends Omit { * ``` */ const getSchemas = async ({url, baseUrl, fetcher, ...requestConfig}: GetSchemasConfig): Promise => { + const finalUrl = url ?? baseUrl; + if (!finalUrl) { + throw new AsgardeoAPIError( + 'Either url or baseUrl must be provided', + 'getSchemas-ValidationError-000', + 'javascript', + 400, + 'Invalid Request', + ); + } + try { - new URL(url ?? baseUrl); + new URL(finalUrl); } catch (error) { throw new AsgardeoAPIError( `Invalid URL provided. ${error?.toString()}`, diff --git a/packages/javascript/src/api/getScim2Me.ts b/packages/javascript/src/api/getScim2Me.ts index 055881c5..d19fe4c4 100644 --- a/packages/javascript/src/api/getScim2Me.ts +++ b/packages/javascript/src/api/getScim2Me.ts @@ -91,8 +91,19 @@ export interface GetScim2MeConfig extends Omit { * ``` */ const getScim2Me = async ({url, baseUrl, fetcher, ...requestConfig}: GetScim2MeConfig): Promise => { + const finalUrl = url ?? baseUrl; + if (!finalUrl) { + throw new AsgardeoAPIError( + 'Either url or baseUrl must be provided', + 'getScim2Me-ValidationError-000', + 'javascript', + 400, + 'Invalid Request', + ); + } + try { - new URL(url ?? baseUrl); + new URL(finalUrl); } catch (error) { throw new AsgardeoAPIError( `Invalid URL provided. ${error?.toString()}`, diff --git a/packages/javascript/src/api/getUserInfo.ts b/packages/javascript/src/api/getUserInfo.ts index 08784463..fa1b7f9f 100644 --- a/packages/javascript/src/api/getUserInfo.ts +++ b/packages/javascript/src/api/getUserInfo.ts @@ -37,6 +37,16 @@ import AsgardeoAPIError from '../errors/AsgardeoAPIError'; * ``` */ const getUserInfo = async ({url, ...requestConfig}: Partial): Promise => { + if (!url) { + throw new AsgardeoAPIError( + 'URL is required', + 'getUserInfo-ValidationError-000', + 'javascript', + 400, + 'Invalid Request', + ); + } + try { new URL(url); } catch (error) { @@ -49,14 +59,25 @@ const getUserInfo = async ({url, ...requestConfig}: Partial): Promise) }; + } else { + finalHeaders = baseHeaders; + } + const response: Response = await fetch(url, { ...requestConfig, method: 'GET', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - ...requestConfig.headers, - }, + headers: finalHeaders, }); if (!response.ok) { diff --git a/packages/javascript/src/api/initializeEmbeddedSignInFlow.ts b/packages/javascript/src/api/initializeEmbeddedSignInFlow.ts index cfe26aaa..e07879d9 100644 --- a/packages/javascript/src/api/initializeEmbeddedSignInFlow.ts +++ b/packages/javascript/src/api/initializeEmbeddedSignInFlow.ts @@ -73,14 +73,24 @@ const initializeEmbeddedSignInFlow = async ({ } }); + const baseHeaders = { + 'Content-Type': 'application/x-www-form-urlencoded', + Accept: 'application/json', + }; + + let finalHeaders: HeadersInit; + if (requestConfig.headers instanceof Headers) { + finalHeaders = requestConfig.headers; + } else if (requestConfig.headers && typeof requestConfig.headers === 'object') { + finalHeaders = { ...baseHeaders, ...(requestConfig.headers as Record) }; + } else { + finalHeaders = baseHeaders; + } + const response: Response = await fetch(url ?? `${baseUrl}/oauth2/authorize`, { ...requestConfig, method: requestConfig.method || 'POST', - headers: { - ...requestConfig.headers, - 'Content-Type': 'application/x-www-form-urlencoded', - Accept: 'application/json', - }, + headers: finalHeaders, body: searchParams.toString(), }); diff --git a/packages/javascript/src/api/updateMeProfile.ts b/packages/javascript/src/api/updateMeProfile.ts index ff99cd84..07bbe9a4 100644 --- a/packages/javascript/src/api/updateMeProfile.ts +++ b/packages/javascript/src/api/updateMeProfile.ts @@ -89,8 +89,19 @@ const updateMeProfile = async ({ fetcher, ...requestConfig }: UpdateMeProfileConfig): Promise => { + const finalUrl = url ?? baseUrl; + if (!finalUrl) { + throw new AsgardeoAPIError( + 'Either url or baseUrl must be provided', + 'updateMeProfile-ValidationError-000', + 'javascript', + 400, + 'Invalid Request', + ); + } + try { - new URL(url ?? baseUrl); + new URL(finalUrl); } catch (error) { throw new AsgardeoAPIError( `Invalid URL provided. ${error?.toString()}`, @@ -146,12 +157,28 @@ const updateMeProfile = async ({ throw error; } + // Type guard for error object with response/data properties + const isErrorWithResponse = (err: unknown): err is { response?: { data?: { detail?: string } } } => { + return typeof err === 'object' && err !== null; + }; + + const isErrorWithData = (err: unknown): err is { data?: { status?: number } } => { + return typeof err === 'object' && err !== null; + }; + + const errorMessage = isErrorWithResponse(error) && error.response?.data?.detail + ? error.response.data.detail + : 'An error occurred while updating the user profile. Please try again.'; + + const errorStatus = isErrorWithData(error) && error.data?.status + ? error.data.status + : 500; + throw new AsgardeoAPIError( - error?.response?.data?.detail || - 'An error occurred while updating the user profile. Please try again.', + errorMessage, 'updateMeProfile-NetworkError-001', 'javascript', - error?.data?.status, + errorStatus, 'Network Error', ); } diff --git a/packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts b/packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts index 3d17216e..8ebfc8cb 100644 --- a/packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts +++ b/packages/javascript/src/utils/getAuthorizeRequestUrlParams.ts @@ -71,7 +71,7 @@ const getAuthorizeRequestUrlParams = ( authorizeRequestParams.set('response_type', 'code'); authorizeRequestParams.set('client_id', clientId as string); - authorizeRequestParams.set('scope', scopes); + authorizeRequestParams.set('scope', scopes ?? ScopeConstants.OPENID); authorizeRequestParams.set('redirect_uri', redirectUri as string); if (responseMode) { diff --git a/packages/javascript/src/utils/getRedirectBasedSignUpUrl.ts b/packages/javascript/src/utils/getRedirectBasedSignUpUrl.ts index 9e63c93a..b15c7f29 100644 --- a/packages/javascript/src/utils/getRedirectBasedSignUpUrl.ts +++ b/packages/javascript/src/utils/getRedirectBasedSignUpUrl.ts @@ -34,13 +34,13 @@ import logger from './logger'; const getRedirectBasedSignUpUrl = (config: Config): string => { const {baseUrl} = config; - if (!isRecognizedBaseUrlPattern(baseUrl)) return ''; + if (!baseUrl || !isRecognizedBaseUrlPattern(baseUrl)) return ''; let signUpBaseUrl: string = baseUrl; if (identifyPlatform(config) === Platform.Asgardeo) { try { - const url: URL = new URL(baseUrl!); + const url: URL = new URL(baseUrl); // Replace 'api.' with 'accounts.' in the hostname, preserving subdomains like 'dev.' if (/([a-z0-9-]+\.)*api\.asgardeo\.io$/i.test(url.hostname)) { diff --git a/packages/javascript/src/utils/identifyPlatform.ts b/packages/javascript/src/utils/identifyPlatform.ts index 3c147ac8..09b0d9ce 100644 --- a/packages/javascript/src/utils/identifyPlatform.ts +++ b/packages/javascript/src/utils/identifyPlatform.ts @@ -53,7 +53,8 @@ const identifyPlatform = (config: Config): Platform => { return Platform.Unknown; } catch (error) { - logger.debug(`[identifyPlatform] Error identifying platform from base URL: ${baseUrl}. Error: ${error.message}`); + const errorMessage = error instanceof Error ? error.message : String(error); + logger.debug(`[identifyPlatform] Error identifying platform from base URL: ${baseUrl}. Error: ${errorMessage}`); return Platform.Unknown; } diff --git a/packages/javascript/src/utils/processOpenIDScopes.ts b/packages/javascript/src/utils/processOpenIDScopes.ts index c57a8b6d..7c041a78 100644 --- a/packages/javascript/src/utils/processOpenIDScopes.ts +++ b/packages/javascript/src/utils/processOpenIDScopes.ts @@ -36,7 +36,7 @@ import AsgardeoRuntimeError from '../errors/AsgardeoRuntimeError'; * processOpenIDScopes({}); // throws AsgardeoRuntimeError * ``` */ -const processOpenIDScopes = (scopes: string | string[]): string => { +const processOpenIDScopes = (scopes?: string | string[]): string => { let processedScopes: string[] = []; if (scopes) { diff --git a/packages/javascript/src/utils/transformBrandingPreferenceToTheme.ts b/packages/javascript/src/utils/transformBrandingPreferenceToTheme.ts index d11e709b..2d9e9aa0 100644 --- a/packages/javascript/src/utils/transformBrandingPreferenceToTheme.ts +++ b/packages/javascript/src/utils/transformBrandingPreferenceToTheme.ts @@ -26,18 +26,18 @@ import createTheme from '../theme/createTheme'; type ColorVariant = {main?: string; dark?: string; contrastText?: string}; type TextColors = {primary?: string; secondary?: string; dark?: string}; -const extractColorValue = (colorVariant?: ColorVariant, preferDark = false): string | undefined => { +const extractColorValue = (colorVariant?: ColorVariant, preferDark = false, fallback = '#000000'): string => { if (preferDark && colorVariant?.dark && colorVariant.dark.trim()) { return colorVariant.dark; } - return colorVariant?.main; + return colorVariant?.main || fallback; }; /** * Safely extracts contrast text color from the branding preference structure */ -const extractContrastText = (colorVariant?: {main?: string; contrastText?: string}) => { - return colorVariant?.contrastText; +const extractContrastText = (colorVariant?: {main?: string; contrastText?: string}, fallback = '#ffffff'): string => { + return colorVariant?.contrastText || fallback; }; /** @@ -65,50 +65,50 @@ const transformThemeVariant = (themeVariant: ThemeVariant, isDark = false): Part activatedOpacity: 0.12, }, primary: { - main: extractColorValue(colors?.primary as ColorVariant, isDark), - contrastText: extractContrastText(colors?.primary), - dark: colors?.primary?.dark || (colors?.primary as ColorVariant)?.main, + main: extractColorValue(colors?.primary as ColorVariant, isDark, '#1976d2'), + contrastText: extractContrastText(colors?.primary, '#ffffff'), + dark: colors?.primary?.dark || (colors?.primary as ColorVariant)?.main || '#1565c0', }, secondary: { - main: extractColorValue(colors?.secondary as ColorVariant, isDark), - contrastText: extractContrastText(colors?.secondary), - dark: colors?.secondary?.dark || (colors?.secondary as ColorVariant)?.main, + main: extractColorValue(colors?.secondary as ColorVariant, isDark, '#dc004e'), + contrastText: extractContrastText(colors?.secondary, '#ffffff'), + dark: colors?.secondary?.dark || (colors?.secondary as ColorVariant)?.main || '#9a0036', }, background: { - surface: extractColorValue(colors?.background?.surface as ColorVariant, isDark), - disabled: extractColorValue(colors?.background?.surface as ColorVariant, isDark), + surface: extractColorValue(colors?.background?.surface as ColorVariant, isDark, '#ffffff'), + disabled: extractColorValue(colors?.background?.surface as ColorVariant, isDark, '#f5f5f5'), dark: - (colors?.background?.surface as ColorVariant)?.dark || (colors?.background?.surface as ColorVariant)?.main, + (colors?.background?.surface as ColorVariant)?.dark || (colors?.background?.surface as ColorVariant)?.main || '#303030', body: { - main: extractColorValue(colors?.background?.body as ColorVariant, isDark), - dark: (colors?.background?.body as ColorVariant)?.dark || (colors?.background?.body as ColorVariant)?.main, + main: extractColorValue(colors?.background?.body as ColorVariant, isDark, '#fafafa'), + dark: (colors?.background?.body as ColorVariant)?.dark || (colors?.background?.body as ColorVariant)?.main || '#212121', }, }, text: { - primary: (colors?.text as TextColors)?.primary, - secondary: (colors?.text as TextColors)?.secondary, - dark: (colors?.text as TextColors)?.dark || (colors?.text as TextColors)?.primary, + primary: (colors?.text as TextColors)?.primary || '#000000', + secondary: (colors?.text as TextColors)?.secondary || '#666666', + dark: (colors?.text as TextColors)?.dark || (colors?.text as TextColors)?.primary || '#000000', }, - border: colors?.outlined?.default, + border: colors?.outlined?.default || '#e0e0e0', error: { - main: extractColorValue(colors?.alerts?.error as ColorVariant, isDark), - contrastText: extractContrastText(colors?.alerts?.error), - dark: (colors?.alerts?.error as ColorVariant)?.dark || (colors?.alerts?.error as ColorVariant)?.main, + main: extractColorValue(colors?.alerts?.error as ColorVariant, isDark, '#d32f2f'), + contrastText: extractContrastText(colors?.alerts?.error, '#ffffff'), + dark: (colors?.alerts?.error as ColorVariant)?.dark || (colors?.alerts?.error as ColorVariant)?.main || '#c62828', }, info: { - main: extractColorValue(colors?.alerts?.info as ColorVariant, isDark), - contrastText: extractContrastText(colors?.alerts?.info), - dark: (colors?.alerts?.info as ColorVariant)?.dark || (colors?.alerts?.info as ColorVariant)?.main, + main: extractColorValue(colors?.alerts?.info as ColorVariant, isDark, '#1976d2'), + contrastText: extractContrastText(colors?.alerts?.info, '#ffffff'), + dark: (colors?.alerts?.info as ColorVariant)?.dark || (colors?.alerts?.info as ColorVariant)?.main || '#1565c0', }, success: { - main: extractColorValue(colors?.alerts?.neutral as ColorVariant, isDark), - contrastText: extractContrastText(colors?.alerts?.neutral), - dark: (colors?.alerts?.neutral as ColorVariant)?.dark || (colors?.alerts?.neutral as ColorVariant)?.main, + main: extractColorValue(colors?.alerts?.neutral as ColorVariant, isDark, '#2e7d32'), + contrastText: extractContrastText(colors?.alerts?.neutral, '#ffffff'), + dark: (colors?.alerts?.neutral as ColorVariant)?.dark || (colors?.alerts?.neutral as ColorVariant)?.main || '#1b5e20', }, warning: { - main: extractColorValue(colors?.alerts?.warning as ColorVariant, isDark), - contrastText: extractContrastText(colors?.alerts?.warning), - dark: (colors?.alerts?.warning as ColorVariant)?.dark || (colors?.alerts?.warning as ColorVariant)?.main, + main: extractColorValue(colors?.alerts?.warning as ColorVariant, isDark, '#ed6c02'), + contrastText: extractContrastText(colors?.alerts?.warning, '#ffffff'), + dark: (colors?.alerts?.warning as ColorVariant)?.dark || (colors?.alerts?.warning as ColorVariant)?.main || '#e65100', }, }, images: { diff --git a/packages/javascript/tsconfig.json b/packages/javascript/tsconfig.json index 56fc2075..904156be 100644 --- a/packages/javascript/tsconfig.json +++ b/packages/javascript/tsconfig.json @@ -14,7 +14,7 @@ "sourceMap": true, "target": "ESNext", "forceConsistentCasingInFileNames": true, - "strict": false, + "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true,