# @saif/platform

The TypeScript/JavaScript counterpart to the .NET `SAIF.Platform` package: a browser-side
`Platform` class that wires up OpenTelemetry and an auth service from Vite env vars, plus the
auth primitives and utilities consumed by `@saif/platform-react`.

## Platform setup

`Platform` combines `OpenTelemetry` and `AuthService` behind one options object. Everything is
optional and defaults to `VITE_*` env var names, so a golden-path frontend can construct it with
no arguments once the corresponding env vars are set:

```ts
import { Platform } from '@saif/platform';

const platform = new Platform();
platform.initialize();
```

`initialize()` starts the OpenTelemetry pipeline (see below); constructing `Platform` alone does
not have side effects.

Override the env var names, or pass explicit values through the nested options, when an app
doesn't follow the default naming:

```ts
const platform = new Platform({
  ENV_BACKEND_URL: 'VITE_BACKEND_URL',
  ENV_FRONTEND_URL: 'VITE_FRONTEND_URL',
  openTelemetryOptions: {
    ENV_OTEL_SERVICE_NAME: 'VITE_OTEL_SERVICE_NAME',
  },
  authServiceOptions: {
    loginPath: '/auth/login',
  },
});
```

`ENV_BACKEND_URL` doubles as the default for OpenTelemetry's CORS trace-header propagation target
and for the auth server URL, unless those are set explicitly in `openTelemetryOptions`/
`authServiceOptions`. `ENV_FRONTEND_URL` (and the optional `ENV_FRONTEND_PATH`) similarly seed
`AuthService`'s default post-login/logout return URL.

## OpenTelemetry

`OpenTelemetry.initialize()` sets up a `WebTracerProvider`, `LoggerProvider`, and `MeterProvider`
(traces, logs, and metrics over OTLP/HTTP), registers the web auto-instrumentations, and installs
`ZoneContextManager` for async context propagation. It's a no-op if `ENV_OTEL_SERVICE_NAME` or
`ENV_OTEL_EXPORTER_OTLP_ENDPOINT` isn't set, so it's safe to call unconditionally in environments
(like local dev) that don't export telemetry:

```ts
import { OpenTelemetry } from '@saif/platform';

new OpenTelemetry({
  ENV_OTEL_SERVICE_NAME: 'VITE_OTEL_SERVICE_NAME',
  ENV_OTEL_EXPORTER_OTLP_ENDPOINT: 'VITE_OTEL_EXPORTER_OTLP_ENDPOINT',
}).initialize();
```

Used through `Platform`, this is already wired up by `platform.initialize()`.

## Auth primitives

`AuthService` is a thin client for a same-origin (or configured cross-origin) auth server: it
redirects to `login`/`logout` paths with a computed `returnUrl`, and fetches the current `User`
from a `me` endpoint.

```ts
import { AuthService } from '@saif/platform';

const authService = new AuthService();

authService.login(); // redirects to `${authServerUrl}/auth/login?returnUrl=...`
const user = await authService.me(); // { isAuthenticated, claims? }
```

`isConfigured` reports whether an auth server URL env var is actually set — `login`/`logout` are
no-ops otherwise, and `me()` resolves to an unauthenticated `User` instead of throwing. `User` and
`Claim` are the plain data shapes returned by `me()`; they carry no behavior of their own.

`@saif/platform-react`'s `AuthProvider` wraps `AuthService` in React context and query-cache
invalidation — use it there instead of calling `AuthService` directly in component code.

## Utils

`trim`/`trimStart`/`trimEnd` trim a specific character (not just whitespace) from a string, e.g.
stripping a trailing slash from a configured base URL:

```ts
import { trimEnd } from '@saif/platform';

trimEnd('https://example.com/', '/'); // 'https://example.com'
```

## Related packages

- [`@saif/platform-react`](../saif-platform-react/index.md) — React bindings: `PlatformProvider`
  context, `AuthProvider`, and a Kiota + TanStack Query layer built on top of this package.

---

[View source on GitHub](https://github.com/saif-corp/forge/blob/main/src/typescript/packages/saif-platform/README.md)
