diff --git a/packages/ts/frontend/src/Connect.ts b/packages/ts/frontend/src/Connect.ts index 4b1ae3b282..2ded276983 100644 --- a/packages/ts/frontend/src/Connect.ts +++ b/packages/ts/frontend/src/Connect.ts @@ -14,9 +14,9 @@ import { FluxConnection, type FluxSubscriptionStateChangeEvent, } from './FluxConnection.js'; -import type { VaadinWindow } from './types.js'; +import type { VaadinGlobal } from './types.js'; -const $wnd = window as VaadinWindow; +const $wnd = globalThis as VaadinGlobal; $wnd.Vaadin ??= {}; $wnd.Vaadin.registrations ??= []; @@ -300,7 +300,8 @@ export class ConnectClient { throw new TypeError(`2 arguments required, but got only ${arguments.length}`); } - const csrfHeaders = getCsrfTokenHeadersForEndpointRequest(document); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const csrfHeaders = globalThis.document ? getCsrfTokenHeadersForEndpointRequest(globalThis.document) : {}; const headers: Record = { Accept: 'application/json', 'Content-Type': 'application/json', diff --git a/packages/ts/frontend/src/CookieManager.ts b/packages/ts/frontend/src/CookieManager.ts index de4e11cb53..2c9762aa3f 100644 --- a/packages/ts/frontend/src/CookieManager.ts +++ b/packages/ts/frontend/src/CookieManager.ts @@ -5,7 +5,8 @@ export function calculatePath({ pathname }: URL): string { } const CookieManager: Cookies.CookiesStatic = Cookies.withAttributes({ - path: calculatePath(new URL(document.baseURI)), + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + path: calculatePath(new URL(globalThis.document?.baseURI ?? '/')), }); export default CookieManager; diff --git a/packages/ts/frontend/src/FluxConnection.ts b/packages/ts/frontend/src/FluxConnection.ts index 4fef3a3019..bc17784861 100644 --- a/packages/ts/frontend/src/FluxConnection.ts +++ b/packages/ts/frontend/src/FluxConnection.ts @@ -182,7 +182,8 @@ export class FluxConnection extends EventTarget { } #connectWebsocket(prefix: string, atmosphereOptions: Partial) { - const extraHeaders = getCsrfTokenHeadersForEndpointRequest(document); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const extraHeaders = globalThis.document ? getCsrfTokenHeadersForEndpointRequest(globalThis.document) : {}; const pushUrl = 'HILLA/push'; const url = prefix.length === 0 ? pushUrl : (prefix.endsWith('/') ? prefix : `${prefix}/`) + pushUrl; this.#socket = atmosphere.subscribe?.({ diff --git a/packages/ts/frontend/src/types.d.ts b/packages/ts/frontend/src/types.d.ts index a5c152f6e2..5255794de4 100644 --- a/packages/ts/frontend/src/types.d.ts +++ b/packages/ts/frontend/src/types.d.ts @@ -16,6 +16,6 @@ export interface Vaadin { registrations?: VaadinRegistration[]; } -export interface VaadinWindow extends Window { +export interface VaadinGlobal { Vaadin?: Vaadin; } diff --git a/packages/ts/frontend/test/Connect.test.ts b/packages/ts/frontend/test/Connect.test.ts index ade3e080ca..76d5baebee 100644 --- a/packages/ts/frontend/test/Connect.test.ts +++ b/packages/ts/frontend/test/Connect.test.ts @@ -18,7 +18,7 @@ import { UnauthorizedResponseError, type FluxConnection, } from '../src/index.js'; -import type { Vaadin, VaadinWindow } from '../src/types.js'; +import type { Vaadin, VaadinGlobal } from '../src/types.js'; import { subscribeStub } from './mocks/atmosphere.js'; import { fluxConnectionSubscriptionStubs } from './mocks/FluxConnection.js'; import { diff --git a/packages/ts/react-i18n/src/index.ts b/packages/ts/react-i18n/src/index.ts index 5ef8f73227..07b7cbd040 100644 --- a/packages/ts/react-i18n/src/index.ts +++ b/packages/ts/react-i18n/src/index.ts @@ -4,6 +4,14 @@ import { FormatCache } from './FormatCache.js'; import { getLanguageSettings, updateLanguageSettings } from './settings.js'; import type { I18nOptions, Translations, TranslationsResult } from './types.js'; +interface VaadinGlobal { + Vaadin?: { + featureFlags?: { + hillaI18n?: boolean; + }; + }; +} + function determineInitialLanguage(options?: I18nOptions): string { // Use explicitly configured language if defined if (options?.language) { @@ -31,7 +39,7 @@ export class I18n { constructor() { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (!(window as any).Vaadin?.featureFlags?.hillaI18n) { + if (!(globalThis as VaadinGlobal).Vaadin?.featureFlags?.hillaI18n) { // Remove when removing feature flag throw new Error( `The Hilla I18n API is currently considered experimental and may change in the future. To use it you need to explicitly enable it in Copilot or by adding com.vaadin.experimental.hillaI18n=true to vaadin-featureflags.properties`, diff --git a/packages/ts/react-signals/src/FullStackSignal.ts b/packages/ts/react-signals/src/FullStackSignal.ts index 1b96087c8d..8b4abe3cb1 100644 --- a/packages/ts/react-signals/src/FullStackSignal.ts +++ b/packages/ts/react-signals/src/FullStackSignal.ts @@ -3,6 +3,14 @@ import { nanoid } from 'nanoid'; import { computed, signal, Signal } from './core.js'; import { createSetStateEvent, type StateEvent } from './events.js'; +interface VaadinGlobal { + Vaadin?: { + featureFlags?: { + fullstackSignals?: boolean; + }; + }; +} + const ENDPOINT = 'SignalsHandler'; /** @@ -28,7 +36,7 @@ export abstract class DependencyTrackingSignal extends Signal { protected constructor(value: T | undefined, onFirstSubscribe: () => void, onLastUnsubscribe: () => void) { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (!(window as any).Vaadin?.featureFlags?.fullstackSignals) { + if (!(globalThis as VaadinGlobal).Vaadin?.featureFlags?.fullstackSignals) { // Remove when removing feature flag throw new Error( `The Hilla Fullstack Signals API is currently considered experimental and may change in the future. To use it you need to explicitly enable it in Copilot or by adding com.vaadin.experimental.fullstackSignals=true to vaadin-featureflags.properties`,